def in_state(self, dt): device = self._context device.sorb_temp = approaches.linear(device.sorb_temp, device.temperature_sp, device.heater_voltage, dt) device.he3pot_temp = approaches.linear(device.he3pot_temp, device.drift_towards, device.drift_rate, dt)
def in_state(self, dt): device = self._context output_current_state(self._context, "started") device.set_true_frequency(approaches.linear(device.get_true_frequency(), device.get_demanded_frequency(), 1, dt)) equilibrium_frequency_temperature = 2*MAX_TEMPERATURE*device.get_true_frequency()/device.get_system_frequency() device.set_temperature(approaches.linear(device.get_temperature(), equilibrium_frequency_temperature, device.get_true_frequency()*0.001, dt)) device.set_true_phase_delay(approaches.linear(device.get_true_phase_delay(), device.get_demanded_phase_delay(), 1, dt))
def in_state(self, dt): device = self._context device.heater_current = approaches.linear( device.heater_current, device.HEATER_OFF_CURRENT, device.HEATER_RAMP_RATE, dt) curr_ramp_rate = device.current_ramp_rate / SECS_PER_MIN # In this state, the magnet current is totally unaffected by whatever the PSU decides to do. if device.activity == Activity.TO_SETPOINT: device.current = approaches.linear(device.current, device.current_setpoint, curr_ramp_rate, dt) elif device.activity == Activity.TO_ZERO: device.current = approaches.linear(device.current, 0, curr_ramp_rate, dt)
def in_state(self, dt): self._context.phase = approaches.linear( self._context.phase, self._context.target_phase, self._phase_locking_speed, dt, )
def in_state(self, dt): device = self._context device.volume_dispensed = approaches.linear(device.volume_dispensed, device.volume_target, device.normalised_rate(), dt) device.volume_infused = self.originally_infused + device.volume_dispensed
def in_state(self, dt): device = self._context rate = 10 device.temperature = approaches.linear(device.temperature, device.temperature_sp, rate, dt)
def in_state(self, dt): # TODO: Does manual control work like this? Or is it perhaps a separate state? if self._context.pump_manual_mode: self._context.pump_speed = self._context.manual_target_speed else: # TODO: Figure out real correlation self._context.pump_speed = 30 * (self._context.temperature_rate / 50.0) # Handle "cooling too fast" error if self._context.pump_speed > 30: self._context.pump_speed = 30 self._context.pump_overspeed = True else: self._context.pump_speed = int(self._context.pump_speed) self._context.pump_overspeed = False # Approach target temperature at set temperature rate # TODO: Should be based on pump speed somehow self._context.temperature = approaches.linear( self._context.temperature, self._context.temperature_limit, self._context.temperature_rate / 60.0, dt, )
def in_state(self, dt): self._context.parking_position = approaches.linear( self._context.parking_position, self._context.target_parking_position, self._parking_speed, dt, )
def in_state(self, dt): super(GoingToSetpointState, self).in_state(dt) device = self._context device.channels[device.control_channel].value = approaches.linear( device.channels[device.control_channel].value, device.channels[device.control_channel].ramp_amplitude_setpoint, 0.001, dt)
def in_state(self, dt): device = self._context for output_index in range(device.sensor_count): sensor_source = device.sensor_source[ output_index] - 1 # sensor source is 1 indexed try: temp = device.temperatures[sensor_source] setpoint = device.setpoints[output_index] device.temperatures[sensor_source] = approaches.linear( temp, setpoint, 0.1, dt) except IndexError: # sensor source is out of range (probably 3) pass try: heater_sensor_source = device.sensor_source[HEATER_INDEX] - 1 # set heater between 0 and 100% proportional to diff in temp * 10 temp = device.temperatures[heater_sensor_source] setpoint = device.setpoints[HEATER_INDEX] diff_in_temp = setpoint - temp heater_limit = device.pid[HEATER_INDEX]["limit"] device.heater = max(0, min(diff_in_temp * 10.0, heater_limit)) except IndexError: # heater is not connected to a sensor so it is off device.heater = 0
def in_state(self, dt): # Approach target temperature at a set rate self._context.temperature = approaches.linear( self._context.temperature, self._context.set_point_temperature, self._context.heating_power / 60.0, dt, )
def in_state(self, dt): # Approach target temperature at set temperature rate self._context.temperature = approaches.linear( self._context.temperature, self._context.temperature_limit, self._context.temperature_rate / 60.0, dt, )
def in_state(self, dt): old_position = self._context.position self._context.position = approaches.linear(old_position, self._context.target, self._context.speed, dt) self.log.info('Moved position (%s -> %s), target=%s, speed=%s', old_position, self._context.position, self._context.target, self._context.speed)
def in_state(self, dt): device = self._context rate = device.ramp_rate target = device.ramp_target_value() constant = device.constant if device.is_output_mode_tesla: rate = rate * constant device.output = approaches.linear(device.output, target, rate, dt) device.check_is_at_target()
def in_state(self, dt): device = self._context device.position = approaches.linear(device.position, device.target_position, device.velocity, dt) if not device.within_hard_limits( ): # If outside of limits device controller faults and must be re-initialised device.motor_warn_status = WarnStateCode.UNDEFINED_POSITION if abs(device.target_position - device.position) <= device.tolerance: device.position_reached = True
def in_state(self, dt): device = self._context # to avoid tests taking forever, ignoring actual rate in favour of value that ramps between boundaries in # roughly 8 seconds rate = 0.05 target = device.ramp_target_value() constant = device.constant if device.is_output_mode_tesla: rate = rate * constant device.output = approaches.linear(device.output, target, rate, dt) device.check_is_at_target()
def simulate(self, dt): """ Simulate movement of the axis. Args: dt: time since last simulation """ if self.moving: self.rbv = approaches.linear(self.rbv, self._move_to_sp, self.speed, dt) self.moving = not self._at_position() self.log.debug("moving {}".format(self.moving)) return
def in_state(self, dt): for channel_number in self._context.channels.keys(): channel = self._context.channels[channel_number] channel.trigger_auto_fill(self._context.cycle) if self._context.cycle: target = 100.0 if channel.is_filling() else 0.0 rate = -Channel.GAS_USE_RATE if channel.is_filling(): rate += Channel.FAST_FILL_RATE if channel.is_fill_rate_fast( ) else Channel.SLOW_FILL_RATE channel.level = approaches.linear(channel.level, target, abs(rate), dt)
def in_state(self, dt): device = self._context rate = 0 if not device.magneticbearing: rate += 1 if device.drive: rate += 50 device.set_true_speed( approaches.linear(device.get_true_speed(), 0, rate, dt)) check_speed(device)
def in_state(self, dt): device = self._context device.heater_current = approaches.linear( device.heater_current, device.HEATER_ON_CURRENT, device.HEATER_RAMP_RATE, dt) # The magnet can only be ramped at a certain rate. The PSUs ramp rate can be varied. # If the PSU attempts to ramp too fast for the magnet, then get a quench curr_ramp_rate = device.current_ramp_rate / SECS_PER_MIN if curr_ramp_rate > device.MAGNET_RAMP_RATE: device.quench("PSU ramp rate is too high") elif abs(device.current - device.magnet_current) > device.QUENCH_CURRENT_DELTA * dt: device.quench("Difference between PSU current ({}) and magnet current ({}) is higher than allowed ({})" .format(device.current, device.magnet_current, device.QUENCH_CURRENT_DELTA * dt)) elif device.activity == Activity.TO_SETPOINT: device.current = approaches.linear(device.current, device.current_setpoint, curr_ramp_rate, dt) device.magnet_current = approaches.linear(device.magnet_current, device.current_setpoint, curr_ramp_rate, dt) elif device.activity == Activity.TO_ZERO: device.current = approaches.linear(device.current, 0, curr_ramp_rate, dt) device.magnet_current = approaches.linear(device.magnet_current, 0, curr_ramp_rate, dt)
def in_state(self, dt): # TODO: Does manual control work like this? Or is it perhaps a separate state? if self._context.pump_manual_mode: self._context.pump_speed = self._context.manual_target_speed else: # TODO: Figure out real correlation self._context.pump_speed = 30 * (self._context.temperature_rate / 50.0) # Handle "cooling too fast" error if self._context.pump_speed > 30: self._context.pump_speed = 30 self._context.pump_overspeed = True else: self._context.pump_speed = int(self._context.pump_speed) self._context.pump_overspeed = False # Approach target temperature at set temperature rate # TODO: Should be based on pump speed somehow self._context.temperature = approaches.linear( self._context.temperature, self._context.temperature_limit, self._context.temperature_rate / 60.0, dt)
def test_target_equals_current_does_not_change(self): pos = 34.0 self.assertEqual(linear(pos, pos, 15.0, 0.5), pos)
def in_state(self, dt): self._context.parking_position = approaches.linear(self._context.parking_position, self._context.target_parking_position, self._parking_speed, dt)
def test_target_negative_speed_inverts_behavior(self): pos = 34.0 self.assertEqual(linear(pos, 23, -2.0, 0.5), 35.0) self.assertEqual(linear(pos, 43, -2.0, 0.5), 33.0)
def test_target_less_than_pos_works(self): pos = 34.0 target = 23.0 self.assertEqual(linear(pos, target, 2.0, 0.5), 33.0)
def test_target_greater_than_pos_works(self): pos = 34.0 target = 43.0 self.assertEqual(linear(pos, target, 2.0, 0.5), 35.0)
def test_no_overshoot(self): pos = 34.0 target = 33.0 self.assertEqual(linear(pos, target, 10.0, 100.0), target)
def in_state(self, dt): self._context.phase = approaches.linear(self._context.phase, self._context.target_phase, self._phase_locking_speed, dt)
def in_state(self, dt): # Approach target temperature at a set rate self._context.temperature = approaches.linear( self._context.temperature, self._context.set_point_temperature, self._context.heating_power / 60.0, dt)
def test_dt_zero_does_not_change_value(self): pos = 34.0 target = 23.0 self.assertEqual(linear(pos, target, 1.0, 0.0), pos)
def in_state(self, dt): self._context.speed = approaches.linear(self._context.speed, self._context.target_speed, self._acceleration, dt)
def in_state(self, dt): self._context.car_pos = approaches.linear(self._context.car_pos, self._context.car_target, self._context.CAR_SPEED, dt)
def in_state(self, dt): # Approach target temperature at set temperature rate self._context.temperature = approaches.linear( self._context.temperature, self._context.temperature_limit, self._context.temperature_rate / 60.0, dt)
def in_state(self, dt): device = self._context device.temperature = approaches.linear(device.temperature, device.drift_towards, device.drift_rate, dt)
def in_state(self, dt): device = self._context output_current_state(self._context, "stopped") device.set_true_frequency(approaches.linear(device.get_true_frequency(), 0, 1, dt)) device.set_temperature(approaches.linear(device.get_temperature(), 0, 0.1, dt)) device.set_true_phase_delay(approaches.linear(device.get_true_phase_delay(), 0, 1, dt))