Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,7 @@ def commit_settings(self, param):

def ini_stage(self, controller=None):
"""
Initialize the controller and stages (axes) with given parameters.

============== ================================================ ==========================================================================================
**Parameters** **Type** **Description**

*controller* instance of the specific controller object If defined this hardware will use it and will not initialize its own controller instance
============== ================================================ ==========================================================================================

Returns
-------
Easydict
dictionnary containing keys:
* *info* : string displaying various info
* *controller*: instance of the controller object in order to control other axes without the need to init the same controller twice
* *stage*: instance of the stage (axis or whatever) object
* *initialized*: boolean indicating if initialization has been done corretly

See Also
--------
daq_utils.ThreadCommand
"""
self.ini_stage_init(controller, BeamSteering())
self.controller.tau = self.settings['tau'] / 1000
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
from pymodaq.control_modules.move_utility_classes import DAQ_Move_base, comon_parameters_fun, main, DataActuatorType

from pymodaq.utils.daq_utils import ThreadCommand
from pymodaq.utils.data import DataActuator

from pymodaq_plugins_mockexamples.hardware.heater import HeaterController


class DAQ_Move_MockHeater(DAQ_Move_base):
"""
Wrapper object to access the Mock fonctionnalities, similar wrapper for all controllers.

=============== ==============
**Attributes** **Type**
*params* dictionnary
=============== ==============
"""
_controller_units = 'W'
is_multiaxes = True
stage_names = ['Heater']
_epsilon = 0.01

params = [] + comon_parameters_fun(is_multiaxes, stage_names, epsilon=_epsilon)
data_actuator_type = DataActuatorType.DataActuator

def ini_attributes(self):
self.controller: HeaterController = None


def get_actuator_value(self) -> DataActuator:
"""

"""
pos = DataActuator(self._title, data=self.controller.check_position())
pos = self.get_position_with_scaling(pos)
return pos

def commit_settings(self, param):
pass

def ini_stage(self, controller: HeaterController = None):
"""

"""
if self.is_master:
self.controller = HeaterController() # any object that will control the stages
else:
self.controller = controller

info = "Boiler controller initialized"
initialized = True

return info, initialized

def move_abs(self, position: DataActuator):
"""
Make the absolute move from the given position after thread command signal was received in DAQ_Move_main.

=============== ========= =======================
**Parameters** **Type** **Description**

*position* float The absolute position
=============== ========= =======================

See Also
--------
DAQ_Move_base.set_position_with_scaling, DAQ_Move_base.poll_moving

"""
position = self.check_bound(position)
self.target_value = position
self.controller.move_abs(self.target_value.value(self.axis_unit))

def move_rel(self, position: DataActuator):
"""

"""
position = self.check_bound(self.current_value + position) - self.current_value
self.target_value = position + self.current_value
position = self.set_position_with_scaling(self.target_value)

self.controller.move_rel(position.value(self.axis_unit))

def stop_motion(self):
"""
Call the specific move_done function (depending on the hardware).

See Also
--------
move_done
"""
self.move_done()

if __name__ == '__main__':
main(__file__)
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import numpy as np


from pymodaq.utils.data import DataFromPlugins

from pymodaq.control_modules.viewer_utility_classes import DAQ_Viewer_base, comon_parameters, main
from pymodaq_data import DataToExport

from pymodaq_plugins_mockexamples.hardware.heater import HeaterController



class DAQ_0DViewer_MockHeater(DAQ_Viewer_base):
"""
"""
params = comon_parameters + [
{'title:': 'Noise', 'name': 'noise', 'type': 'float', 'value': HeaterController._noise},
{'title:': 'Ambiant temp', 'name': 'ambiant_temp', 'type': 'float',
'value': HeaterController._ambiant_temperature}
]


def ini_attributes(self):
self.controller: HeaterController = None
self.ind_data = 0

def commit_settings(self, param):
"""
"""
if param.name() == 'noise':
self.controller.noise = param.value()
elif param.name() == 'ambiant_temp':
self.controller.ambiant_temp = param.value()


def ini_detector(self, controller=None):
"""
"""
if self.is_master:
self.controller = HeaterController()
else:
self.controller = controller

initialized = True
info = 'Controller ok'
return info, initialized

def close(self):
"""
not implemented.
"""
pass

def grab_data(self, Naverage=1, **kwargs):
"""


"""
temperature = self.controller.grab()
self.dte_signal.emit(DataToExport(self._title, data=[
DataFromPlugins(name=self._title, data=[np.array([temperature])],
dim='Data0D', labels=['Temperature'])]))

def stop(self):
"""
not implemented.
"""
return ""


if __name__ == '__main__':
main(__file__)
56 changes: 56 additions & 0 deletions src/pymodaq_plugins_mockexamples/hardware/heater.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from time import perf_counter
from qtpy.QtCore import QObject
from numpy.random import random
import numpy as np
from pymodaq import Q_


class HeaterController(QObject):
_current_temperature = 20.
_ambiant_temperature = 19.
_noise = 0.1

def __init__(self, ):
super().__init__()
self.startTimer(10)
self._current_power = 0.
self._ellapsed_time = Q_(0., 's')
self._tau = Q_(1, 's')

def timerEvent(self, event):
dt = Q_(perf_counter(), 's') - self._ellapsed_time
self._ellapsed_time += dt

self._current_temperature += 1 * self._current_power * dt.m_as('s') + self._noise * (random() - 0.5)
# some heat dissipation
self._current_temperature -= 0.2 * dt.m_as('s')
self._current_temperature = np.clip(self._current_temperature, self.ambiant_temp, None)

def check_position(self):
return self._current_power

def move_abs(self, value):
self._current_power = value

@property
def ambiant_temp(self):
return self._ambiant_temperature

@ambiant_temp.setter
def ambiant_temp(self, temperature):
self._ambiant_temperature = temperature


@property
def noise(self):
return self._noise

@noise.setter
def noise(self, noise):
self._noise = noise

def move_rel(self, value):
self._current_power += value

def grab(self):
return self._current_temperature
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def convert_input(self, measurements: DataToExport) -> DataToExport:
],
)

def convert_output(self, outputs: List[float], dt, stab=True) -> DataToActuators:
def convert_output(self, outputs: List[float], dt: float, stab=True) -> DataToActuators:
"""
Convert the output of the PID in units to be fed into the actuator
Parameters
Expand Down
76 changes: 76 additions & 0 deletions src/pymodaq_plugins_mockexamples/models/PIDModelMockHeater.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import numpy as np

from pymodaq.extensions.pid.utils import PIDModelGeneric
from pymodaq.utils.data import DataToActuators, DataActuator
from pymodaq_data import DataToExport



class PIDModelMockHeater(PIDModelGeneric):

limits = dict(max=dict(state=False, value=10),
min=dict(state=False, value=0), )
konstants = dict(kp=0.001, ki=0, kd=0.0000)

actuators_name = ["Heater"]
detectors_name = ['Temperature']

Nsetpoints = 1
setpoint_ini = [20]
setpoints_names = ['Temperature']



def __init__(self, pid_controller):
super().__init__(pid_controller)

def update_settings(self, param):
"""
Get a parameter instance whose value has been modified by a user on the UI
Parameters
----------
param: (Parameter) instance of Parameter object
"""
if param.name() == '':
pass

def ini_model(self):
super().ini_model()

def convert_input(self, measurements: DataToExport) -> DataToExport:
"""
Convert the measurements in the units to be fed to the PID (same dimensionality as the setpoint)
Parameters
----------
measurements: DataToExport
DataToExport object from which the model extract a value of the same units as the setpoint

Returns
-------
DataToExport: the converted input as 0D DataCalculated stored in a DataToExport
"""

return DataToExport('output', data=[measurements.get_data_from_name(self.detectors_name[0])])

def convert_output(self, outputs: list[float], dt: float, stab=True) -> DataToActuators:
"""
Convert the output of the PID in units to be fed into the actuator
Parameters
----------
outputs: (list of float) output value from the PID from which the model extract a value of the same units as the actuator
dt: (float) elapsed time in seconds since last call

Returns
-------
DataToActuatorPID: the converted output as a DataToActuatorPID object (derived from DataToExport)
"""
out_put_to_actuator = DataToActuators('Boiler',
mode='abs',
data=[DataActuator(name=self.actuators_name[0],
data = [np.atleast_1d(outputs[0] / dt)])],)


return out_put_to_actuator



Loading