# dt_ctrl.ctrl # # Controller network for Dwingeloo Telescope. # # This file contains the fixed part of the network and its parameters. # Other .ctrl files are used for those parts which are conditional, # such as the use of simulation networks or real servo drives. # # Frequency is limited by the stoeber drives. frequency 250 # dt_ctrl_el.ctrl Elevation with real servo drives # dt_ctrl_el_sim.ctrl Elevation with simulated network # dt_ctrl_az.ctrl Azimuth with real servo drives # dt_ctrl_az_sim.ctrl Azimuth with simulated network # # Uncomment either the real network, or the sim network. # But never both! #include "dt_ctrl_el.ctrl" include "dt_ctrl_el_sim.ctrl" #include "dt_ctrl_az.ctrl" include "dt_ctrl_az_sim.ctrl" blocks { { "setpoint_generator", "azimuth_spg", "Azimuth_Setpoint", "rad" } { "servo_state", "azimuth_servo_state" } { "subtract", "azimuth_setpoint_error" } { "subtract", "azimuth_error" } { "pid_aw", "azimuth_pid" } { "filter_iir", "azimuth_pid_filter" } { "limit_var", "azimuth_pid_limit" } { "add", "azimuth_speed_ff" } { "limit", "azimuth_speed_limit" } { "dt_az_safety", "azimuth_safety" } { "gain", "azimuth_speed_servo" } { "value", "azimuth_torque" } { "value", "azimuth_position_offset" } { "add", "azimuth_position_offset_sum" } { "gain", "azimuth_position_gain" } { "rangecheck", "azimuth_speed_warning" } { "matrix_2x2", "elevation_input_matrix" } { "setpoint_generator", "elevation_spg", "Elevation_Setpoint", "rad" } { "servo_state", "elevation_servo_state" } { "setpoint_generator", "elevation_torsion_spg", "Elevation_Torsion_Setpoint", "rad" } { "subtract", "elevation_setpoint_error" } { "subtract", "elevation_error" } { "subtract", "elevation_torsion_error" } { "subtract", "elevation_torsion_setpoint_error" } { "subtract", "elevation_torsion_torque" } { "filter_lp", "elevation_torsion_torque_lp" } { "pid_aw", "elevation_pid" } { "pid_aw", "elevation_torsion_pid" } { "add", "elevation_speed_ff" } { "switch", "elevation_position_switch" } { "limit", "elevation_torsion_speed_limit" } { "limit", "elevation_speed_limit" } { "limit_2nd", "elevation_jerk_limit" } { "dt_el_safety", "elevation_safety" } { "matrix_2x2", "elevation_output_matrix" } { "value", "elevation_torque_r" } { "value", "elevation_torque_l" } { "value", "elevation_position_offset_r" } { "value", "elevation_position_offset_l" } { "add", "elevation_position_offset_r_sum" } { "add", "elevation_position_offset_l_sum" } { "value_bool", "false" } } links { { "dt_az", "position", "azimuth_position_gain", "in" , true } { "azimuth_position_gain", "out", "azimuth_position_offset_sum", "in0" , true } { "azimuth_position_offset", "value", "azimuth_position_offset_sum", "in1" , true } { "azimuth_position_offset_sum", "out", "azimuth_error", "negative" , true } { "azimuth_servo_state", "reset", "azimuth_spg", "reset" , false } { "azimuth_position_offset_sum", "out", "azimuth_spg", "reset_x" , true } { "azimuth_spg", "x", "azimuth_servo_state", "spg_x" , true } { "azimuth_spg", "v", "azimuth_servo_state", "spg_v" , true } { "azimuth_spg", "a", "azimuth_servo_state", "spg_a" , true } { "azimuth_safety", "safe_out", "azimuth_servo_state", "safe" , false } { "azimuth_servo_state", "out_x", "azimuth_error", "positive" , true } { "azimuth_position_offset_sum", "out", "azimuth_setpoint_error", "negative" , true } { "azimuth_spg", "setpoint", "azimuth_setpoint_error", "positive" , true } { "azimuth_servo_state", "out_v", "azimuth_speed_ff", "in0" , true } { "azimuth_error", "difference", "azimuth_pid", "in" , true } { "azimuth_servo_state", "enable", "azimuth_pid", "enable" , true } { "azimuth_pid", "out", "azimuth_pid_limit", "in" , true } { "azimuth_servo_state", "out_v", "azimuth_pid_limit", "limit" , true } { "azimuth_pid_limit", "out", "azimuth_pid_filter", "in" , true } { "azimuth_pid_filter", "out", "azimuth_speed_ff", "in1" , true } { "azimuth_speed_ff", "out", "azimuth_speed_limit", "in" , true } { "azimuth_speed_limit", "out", "azimuth_safety", "speed_in" , true } { "azimuth_position_offset_sum", "out", "azimuth_safety", "position_in" , true } { "azimuth_torque", "value", "azimuth_safety", "torque_in" , true } { "dt_az", "be4", "azimuth_safety", "safety_in_positive", true } { "dt_az", "be2", "azimuth_safety", "safety_in_negative", true } { "azimuth_servo_state", "enable", "azimuth_safety", "enable" , true } { "azimuth_safety", "speed_out", "azimuth_speed_servo", "in" , true } { "azimuth_speed_servo", "out", "dt_az", "speed" , true } { "azimuth_safety", "torque_out", "dt_az", "torque" , true } { "azimuth_servo_state", "enable", "dt_az", "enable" , true } { "dt_az", "speed", "azimuth_speed_warning", "in" , true } { "azimuth_speed_warning", "invalid", "dt_az", "ba1" , true } { "false", "value", "dt_az", "ba2" , true } { "elevation_servo_state", "reset", "elevation_spg", "reset" , false } { "elevation_input_matrix", "out0", "elevation_spg", "reset_x" , true } { "elevation_spg", "x", "elevation_servo_state", "spg_x" , true } { "elevation_spg", "v", "elevation_servo_state", "spg_v" , true } { "elevation_spg", "a", "elevation_servo_state", "spg_a" , true } { "elevation_safety", "safe_out", "elevation_servo_state", "safe" , false } { "elevation_servo_state", "out_x", "elevation_error", "positive" , true } { "elevation_servo_state", "out_v", "elevation_speed_ff", "in0" , true } { "dt_el_r", "position", "elevation_position_offset_r_sum", "in0" , true } { "dt_el_l", "position", "elevation_position_offset_l_sum", "in0" , true } { "elevation_position_offset_r", "value", "elevation_position_offset_r_sum", "in1" , true } { "elevation_position_offset_l", "value", "elevation_position_offset_l_sum", "in1" , true } { "elevation_position_offset_r_sum","out", "elevation_input_matrix", "in0" , true } { "elevation_position_offset_l_sum","out", "elevation_input_matrix", "in1" , true } { "elevation_input_matrix", "out0", "elevation_error", "negative" , true } { "elevation_spg", "setpoint", "elevation_setpoint_error", "positive" , true } { "elevation_input_matrix", "out0", "elevation_setpoint_error", "negative" , true } { "elevation_error", "difference", "elevation_pid", "in" , true } { "elevation_servo_state", "enable", "elevation_pid", "enable" , true } { "elevation_pid", "out", "elevation_speed_ff", "in1" , true } { "elevation_speed_ff", "out", "elevation_position_switch", "in" , true } { "elevation_servo_state", "enable", "elevation_position_switch", "on" , true } { "elevation_position_switch", "out", "elevation_speed_limit", "in" , true } { "elevation_servo_state", "enable", "elevation_jerk_limit", "enable" , true } { "elevation_speed_limit", "out", "elevation_jerk_limit", "in" , true } { "elevation_jerk_limit", "out", "elevation_output_matrix", "in0" , true } { "dt_el_r", "torque", "elevation_torsion_torque", "positive" , true } { "dt_el_l", "torque", "elevation_torsion_torque", "negative" , true } { "elevation_torsion_torque", "difference", "elevation_torsion_torque_lp", "in" , true } { "elevation_position_offset_r_sum","out", "elevation_safety", "position_in_r" , true } { "elevation_position_offset_l_sum","out", "elevation_safety", "position_in_l" , true } { "elevation_input_matrix", "out1", "elevation_safety", "torsion_in" , true } { "elevation_output_matrix", "out0", "elevation_safety", "speed_in_r" , true } { "elevation_output_matrix", "out1", "elevation_safety", "speed_in_l" , true } { "elevation_torsion_torque_lp", "out", "elevation_safety", "torque_in" , true } { "elevation_torque_r", "value", "elevation_safety", "torque_in_r" , true } { "elevation_torque_l", "value", "elevation_safety", "torque_in_l" , true } { "dt_el_l", "be4", "elevation_safety", "safety_in_top", true } { "dt_el_l", "be2", "elevation_safety", "safety_in_bottom", true } { "elevation_servo_state", "enable", "elevation_safety", "enable" , true } { "elevation_safety", "speed_out_r", "dt_el_r", "speed" , true } { "elevation_safety", "speed_out_l", "dt_el_l", "speed" , true } { "elevation_safety", "torque_out_r","dt_el_r", "torque" , true } { "elevation_safety", "torque_out_l","dt_el_l", "torque" , true } { "elevation_servo_state", "enable", "dt_el_r", "enable" , true } { "elevation_servo_state", "enable", "dt_el_l", "enable" , true } { "false", "value", "dt_el_r", "ba1" , true } { "false", "value", "dt_el_r", "ba2" , true } { "false", "value", "dt_el_l", "ba1" , true } { "false", "value", "dt_el_l", "ba2" , true } { "elevation_servo_state", "reset", "elevation_torsion_spg", "reset" , false } { "elevation_input_matrix", "out1", "elevation_torsion_spg", "reset_x" , true } { "elevation_torsion_spg", "x", "elevation_torsion_error", "positive" , true } { "elevation_input_matrix", "out1", "elevation_torsion_error", "negative" , true } { "elevation_torsion_spg", "setpoint", "elevation_torsion_setpoint_error", "positive" , true } { "elevation_input_matrix", "out1", "elevation_torsion_setpoint_error", "negative" , true } { "elevation_torsion_error", "difference", "elevation_torsion_pid", "in" , true } { "elevation_servo_state", "enable", "elevation_torsion_pid", "enable" , true } { "elevation_torsion_pid", "out", "elevation_torsion_speed_limit", "in" , true } { "elevation_torsion_speed_limit", "out", "elevation_output_matrix", "in1" , true } } traces { { "Azimuth_Spg0", "rad", "azimuth_spg", "x" } { "Azimuth_Spg1", "rad/s", "azimuth_spg", "v" } { "Azimuth_Spg2", "rad/s/s", "azimuth_spg", "a" } { "Azimuth_Spg3", "rad/s/s/s", "azimuth_spg", "j" } { "Azimuth_Setpoint", "rad", "azimuth_spg", "setpoint" } { "Azimuth_Error", "rad", "azimuth_error", "difference" } { "Azimuth_Setpoint_Error", "rad", "azimuth_setpoint_error", "difference" } { "Azimuth_PID", "rad/s", "azimuth_pid", "out" } { "Azimuth_I", "rad/s", "azimuth_pid", "outi" } { "Azimuth_PID_filtered", "rad/s", "azimuth_pid_filter", "out" } { "Azimuth_Position", "rad", "azimuth_position_offset_sum", "out" } { "Azimuth_Speed", "rad/s", "dt_az", "speed" } { "Azimuth_Torque", "Nm", "dt_az", "torque" } { "Azimuth_Safe", "Boolean", "azimuth_safety", "safe_out" } { "Azimuth_Enabled", "Boolean", "dt_az", "enabled" } { "Azimuth_Drive_Safety", "Boolean", "dt_az", "be1" } { "Azimuth_Drive_Safety_p270", "Boolean", "dt_az", "be4" } { "Azimuth_Drive_Safety_m270", "Boolean", "dt_az", "be2" } { "Focusbox_Position", "Volt", "dt_az", "ae1" } { "Elevation_Position", "rad", "elevation_input_matrix", "out0" } { "Elevation_Torsion", "rad", "elevation_input_matrix", "out1" } { "Elevation_Setpoint", "rad", "elevation_spg", "setpoint" } { "Elevation_Spg0", "rad", "elevation_spg", "x" } { "Elevation_Spg1", "rad/s", "elevation_spg", "v" } { "Elevation_Spg2", "rad/s", "elevation_spg", "a" } { "Elevation_Spg3", "rad/s", "elevation_spg", "j" } { "Elevation_Error", "rad", "elevation_error", "difference" } { "Elevation_Setpoint_Error", "rad", "elevation_setpoint_error", "difference" } { "Elevation_PID", "rad/s", "elevation_pid", "out" } { "Elevation_Torsion_Error", "rad", "elevation_torsion_error", "difference" } { "Elevation_Torsion_Setpoint_Error", "rad", "elevation_torsion_setpoint_error", "difference" } { "Elevation_Torsion_PID", "rad/s", "elevation_torsion_pid", "out" } { "Elevation_Position_Right", "rad", "elevation_position_offset_r_sum", "out" } { "Elevation_Position_Left", "rad", "elevation_position_offset_l_sum", "out" } { "Elevation_Speed_Right", "rad/s", "dt_el_r", "speed" } { "Elevation_Speed_Left", "rad/s", "dt_el_l", "speed" } { "Elevation_Torque_Right", "Nm", "dt_el_r", "torque" } { "Elevation_Torque_Left", "Nm", "dt_el_l", "torque" } { "Elevation_Torsion_Torque", "Nm", "elevation_torsion_torque_lp", "out" } { "Elevation_Safe", "Boolean", "elevation_safety", "safe_out" } { "Elevation_Enabled", "Boolean", "dt_el_l", "enabled" } { "Elevation_Drive_Safety_Right", "Boolean", "dt_el_r", "be1" } { "Elevation_Drive_Safety_Left", "Boolean", "dt_el_l", "be1" } { "Elevation_Top_Safe", "Boolean", "dt_el_l", "be4" } { "Elevation_Bottom_Safe", "Boolean", "dt_el_l", "be2" } } set azimuth_gear 15006.75 set elevation_gear 44803.125 params { { "azimuth_spg", "setpoint", (float) 0.0 } { "azimuth_spg", "t", (float) 0.004 } # maximum speed and position clients input is checked against { "azimuth_spg", "max_x", (float) deg2rad(270.0) } { "azimuth_spg", "min_x", (float) deg2rad(-270.0) } { "azimuth_spg", "max_v", (float) rpm2rads(3000.0)/$(azimuth_gear) } # acceleration and jerk we use to generate a profile { "azimuth_spg", "max_a", (float) 0.0002 } { "azimuth_spg", "max_j", (float) 0.00001 } # at which precision do we consider the values to be 'equal' { "azimuth_spg", "precision_x", (float) 0.000001 } { "azimuth_spg", "precision_a", (float) 0.000001 } { "azimuth_spg", "precision_v", (float) 0.000001 } # maximum values within we allow normal operation { "azimuth_servo_state", "max_x", (float) deg2rad(270.0) } { "azimuth_servo_state", "min_x", (float) deg2rad(-270.0) } { "azimuth_servo_state", "max_v", (float) rpm2rads(3000.0)/$(azimuth_gear) } { "azimuth_servo_state", "max_a", (float) 0.0002 } # controller factors { "azimuth_pid", "kp", (float) 0.20 } { "azimuth_pid", "ki", (float) 0.00 } { "azimuth_pid", "kd", (float) 0.0 } { "azimuth_pid", "t", (float) 0.004 } # the amount of 'wind-up' we allow in the integrator { "azimuth_pid", "maxw", (float) rpm2rads(0.005) } { "azimuth_pid", "minw", (float) rpm2rads(-0.005) } # second order filter to make sure we do not trigger the eigenfrequency of the DT { "azimuth_pid_filter", "transfer", (int) 2, (double) 6.343831259e+05, (float) { -0.9964520027, 1.9964456974 }, (float) { 1.0, 2.0 } } { "azimuth_speed_warning", "max", (double) rpm2rads(200.0) } { "azimuth_speed_warning", "min", (double) rpm2rads(-200.0) } # Due to high vibrations observed at high speed it was decided to limit # the pid controller. At low speed the value is untouched, but the # output is limited when speed increases # limit = offset + gain * speed { "azimuth_pid_limit", "offset", (float) rpm2rads(100.0)/$(azimuth_gear) } { "azimuth_pid_limit", "gain", (float)-0.3 } # speed limit on spg + pid just before we send it to the drive { "azimuth_speed_limit", "min", (float) rpm2rads(-3000.0)/$(azimuth_gear) } { "azimuth_speed_limit", "max", (float) rpm2rads(3000.0)/$(azimuth_gear) } # gear ratio between DT and servodrive { "azimuth_speed_servo", "gain", (float)-$(azimuth_gear) } # torque we allow the servodrive to actuate on the DT { "azimuth_torque", "value", (float) 10.0 } # inverse gear ratio between DT and servodrive { "azimuth_position_gain", "gain", (float)-1.0/$(azimuth_gear) } # callibration value for position { "azimuth_position_offset","value", (float) 0.0 } # positions were we go into safe behavior # these must be outside the normal operating range { "azimuth_safety", "position_min", (float) deg2rad(-290.0) } { "azimuth_safety", "position_max", (float) deg2rad(290.0) } # 'safe zone' is between the operating range and the absolute safety # value above { "azimuth_safety", "safe_zone_min", (float) deg2rad(-280.0) } { "azimuth_safety", "safe_zone_max", (float) deg2rad(280.0) } { "azimuth_safety", "safe_zone_min_speed", (float) rpm2rads(-0.001) } { "azimuth_safety", "safe_zone_max_speed", (float) rpm2rads(0.001) } { "azimuth_safety", "emergency_torque", (float) 3.0 } # we do not start in recovery mode { "azimuth_safety", "recover", (int) 0 } { "elevation_input_matrix", "constants", (float) { 0.5/$(elevation_gear), -0.5/$(elevation_gear) }, (float) { 1.0/$(elevation_gear), 1.0/$(elevation_gear) } } { "elevation_output_matrix", "constants", (float) { $(elevation_gear), $(elevation_gear)/2.0 }, (float) { -$(elevation_gear), $(elevation_gear)/2.0 } } { "elevation_spg", "setpoint", (float) 0.0 } { "elevation_spg", "t", (float) 0.004 } { "elevation_spg", "max_x", (float) deg2rad(90.0) } { "elevation_spg", "min_x", (float) deg2rad(-0.05) } { "elevation_spg", "max_v", (float) rpm2rads(2100.0)/$(elevation_gear) } { "elevation_spg", "max_a", (float) 0.0003 } { "elevation_spg", "max_j", (float) 0.000016 } { "elevation_spg", "precision_x", (float) 0.000001 } { "elevation_spg", "precision_a", (float) 0.000001 } { "elevation_spg", "precision_v", (float) 0.000001 } { "elevation_servo_state", "max_x", (float) deg2rad(90.0) } { "elevation_servo_state", "min_x", (float) deg2rad(-0.05) } { "elevation_servo_state", "max_v", (float) rpm2rads(2100.0)/$(elevation_gear) } { "elevation_servo_state", "max_a", (float) 0.0003 } { "elevation_torsion_spg", "setpoint", (float) 0.0 } { "elevation_torsion_spg", "t", (float) 0.004 } { "elevation_torsion_spg", "max_x", (float) 0.00 } { "elevation_torsion_spg", "min_x", (float)-0.00 } { "elevation_torsion_spg", "max_v", (float) rpm2rads(0.001) } { "elevation_torsion_spg", "max_a", (float) 0.00004 } { "elevation_torsion_spg", "max_j", (float) 0.00001 } { "elevation_torsion_spg", "precision_x", (float) 0.000001 } { "elevation_torsion_spg", "precision_a", (float) 0.000001 } { "elevation_torsion_spg", "precision_v", (float) 0.000001 } { "elevation_pid", "kp", (float) 0.80 } { "elevation_pid", "ki", (float) 0.001 } { "elevation_pid", "kd", (float) 0.001 } { "elevation_pid", "t", (float) 0.004 } { "elevation_pid", "maxw", (float) rpm2rads(0.002) } { "elevation_pid", "minw", (float) rpm2rads(-0.002) } { "elevation_speed_limit", "min", (float) rpm2rads(-0.08) } { "elevation_speed_limit", "max", (float) rpm2rads(0.08) } { "elevation_jerk_limit", "min", (float)-0.003 } { "elevation_jerk_limit", "max", (float) 0.003 } { "elevation_jerk_limit", "t", (float) 0.004 } { "elevation_torsion_pid", "t", (float) 0.004 } { "elevation_torsion_pid", "kp", (float) 0.2 } { "elevation_torsion_pid", "ki", (float) 0.0 } { "elevation_torsion_pid", "kd", (float) 0.0 } { "elevation_torsion_pid", "maxw", (float) 0.0001 } { "elevation_torsion_pid", "minw", (float)-0.0001 } { "elevation_torsion_speed_limit", "min", (float) rpm2rads(-0.001) } { "elevation_torsion_speed_limit", "max", (float) rpm2rads(0.001) } { "elevation_safety", "safe_zone_min_speed", (float)-30 } { "elevation_safety", "safe_zone_max_speed", (float) 30 } { "elevation_safety", "torsion_max", (float) 0.0002 } { "elevation_safety", "recover", (int) 0 } { "elevation_safety", "torque_max", (float) 20.0 } { "elevation_safety", "emergency_torque", (float) 3.0 } { "elevation_torque_r", "value", (float) 10.0 } { "elevation_torque_l", "value", (float) 10.0 } { "elevation_torsion_torque_lp", "t", (float) 0.004 } { "elevation_torsion_torque_lp", "tau", (float) 10.0 } { "elevation_position_offset_r","value", (float) 0.0 } { "elevation_position_offset_l","value", (float) 0.0 } { "elevation_safety", "position_min", (float) -78.19620464325844733 } { "elevation_safety", "position_max", (float) 70767.56520214889483 } { "elevation_safety", "safe_zone_min", (float) -70.37658417893260259 } { "elevation_safety", "safe_zone_max", (float) 70689.36899750563638 } { "elevation_safety", "torsion_recover_max", (float) 0.01745329251994329577 } } # Load file with calibration parameters. # All parameters above should not be subject to calibration. include "dt_ctrl.param"