Source code for mxcubecore.HardwareObjects.mockup.MotorMockup

# encoding: utf-8
#
#  Project name: MXCuBE
#  https://github.com/mxcube
#
#  This file is part of MXCuBE software.
#
#  MXCuBE is free software: you can redistribute it and/or modify
#  it under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  MXCuBE is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public License
#  along with MXCuBE. If not, see <http://www.gnu.org/licenses/>.

"""
Example of xml config file

<object class="MotorMockup">
  <username>Mock motor</username>
  <actuator_name>mock_motor</actuator_name>
  <!-- for the mockup only -->
  <default_value>500</default_value>
  <velocity>100</velocity>
  <wrap_range>None</wrap_range>
  <default_limits>[-360, 360]</default_limits>
</object>
"""

import time

from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor, MotorStates
from mxcubecore.HardwareObjects.mockup.ActuatorMockup import ActuatorMockup

__copyright__ = """ Copyright © 2010-2020 by the MXCuBE collaboration """
__license__ = "LGPLv3+"

DEFAULT_VELOCITY = 100
DEFAULT_LIMITS = (-10000, 10000)
DEFAULT_VALUE = 10.124
DEFAULT_WRAP_RANGE = None


[docs]class MotorMockup(ActuatorMockup, AbstractMotor): """Mock Motor implementation""" SPECIFIC_STATES = MotorStates def __init__(self, name): AbstractMotor.__init__(self, name) self._wrap_range = None
[docs] def init(self): """Initialisation method""" # get username, actuator_name and tolerance super().init() # local properties if not self.get_velocity(): self.set_velocity(DEFAULT_VELOCITY) if None in self.get_limits(): self.update_limits(DEFAULT_LIMITS) try: self._wrap_range = float(self.get_property("wrap_range")) except (TypeError, ValueError): self._wrap_range = DEFAULT_WRAP_RANGE if self.default_value is None: self.default_value = DEFAULT_VALUE self.update_value(self.default_value) self.update_state(self.STATES.READY)
def _move(self, value): """Simulated motor movement. Args: value (float): target position Returns: (float): The reached position. """ self.update_specific_state(self.SPECIFIC_STATES.MOVING) start_pos = self.get_value() if value is not None and start_pos is not None: delta = abs(value - start_pos) direction = -1 if value < self.get_value() else 1 start_time = time.time() while (time.time() - start_time) < (delta / self.get_velocity()): time.sleep(0.02) val = start_pos + direction * self.get_velocity() * ( time.time() - start_time ) val = val if not self._wrap_range else val % self._wrap_range self.update_value(val) time.sleep(0.02) _low, _high = self.get_limits() if value == self.default_value: self.update_specific_state(self.SPECIFIC_STATES.HOME) elif value == _low: self.update_specific_state(self.SPECIFIC_STATES.LOWLIMIT) elif value == _high: self.update_specific_state(self.SPECIFIC_STATES.HIGHLIMIT) else: self.update_specific_state(None) return value def is_moving(self): return (self.get_state() == self.STATES.BUSY) or ( self.get_state() == self.SPECIFIC_STATES.MOVING )