Source code for crappy.actuator.servostar

# coding: utf-8

from multiprocessing import Lock

from .actuator import Actuator
from .._global import OptionalModule

try:
  import serial
except (ModuleNotFoundError, ImportError):
  serial = OptionalModule("pyserial")


[docs]class Servostar(Actuator): """To drive and configure a servostar variator through a serial connection."""
[docs] def __init__(self, device, baudrate=38400, mode="serial"): """Sets the instance attributes. Args: device (:obj:`str`, optional): Path to connect to the serial port. baudrate (:obj:`int`, optional): Set the corresponding baud rate. mode (:obj:`str`, optional): Can be `'analog'` or `'serial'`. """ Actuator.__init__(self) self.devname = device self.mode = mode self.baud = baudrate self.lock = Lock() self.last = None
def open(self): self.lock.acquire() self.ser = serial.Serial(self.devname, baudrate=self.baud, timeout=2) self.ser.flushInput() self.ser.write('ANCNFG 0\r\n') self.lock.release() if self.mode == "analog": self.set_mode_analog() elif self.mode == "serial": self.set_mode_serial() else: raise AttributeError("No such mode: " + str(self.mode)) self.lock.acquire() self.ser.write('EN\r\n') self.ser.write('MH\r\n') self.lock.release()
[docs] def set_position(self, pos, speed=20000, acc=200, dec=200): """Go to the position specified at the given speed and acceleration.""" if self.last is pos: return if isinstance(pos, bool): # To use set_position(True) as set_mode_serial() # and set_position(False) as set_mode_analog() # (to command all of this from as single generator) if pos: self.set_mode_serial() else: self.set_mode_analog() elif self.mode != "serial": self.set_mode_serial() self.lock.acquire() self.ser.flushInput() self.ser.write(" ".join(["ORDER 0", str(int(pos)), str(speed), "8192", str(acc), str(dec), "0 0 0 0\r\n"])) self.ser.write("MOVE 0\r\n") # activates the order self.lock.release() self.last = pos
[docs] def get_position(self): """Reads current position. Returns: Current position of the motor. """ self.lock.acquire() self.ser.flushInput() self.ser.write("PFB\r\n") r = '' while r != "PFB\r\n": if len(r) == 5: r = r[1:] r += self.ser.read() if not r: print("Servostar timeout error! make sure the servostar is on!") self.lock.release() return r = '' while "\n" not in r: r += self.ser.read() self.lock.release() return int(r)
[docs] def set_mode_serial(self): """Sets the serial input as setpoint.""" self.lock.acquire() self.ser.flushInput() self.ser.write('OPMODE 8\r\n') self.lock.release() self.mode = "serial"
[docs] def set_mode_analog(self): """Sets the analog input as setpoint.""" self.last = None self.lock.acquire() self.ser.flushInput() self.ser.write('OPMODE 1\r\n') self.lock.release() self.mode = "analog"
[docs] def clear_errors(self): """Clears error in motor registers.""" self.ser.flushInput() self.ser.write("CLRFAULT\r\n")
[docs] def stop(self): """Stops the motor.""" self.ser.write("DIS\r\n") self.ser.flushInput()
def close(self): self.ser.close()