@@ -596,3 +596,93 @@ def release(self, value):
596596 self ._release = value
597597 self ._leftmotor .release = value
598598 self ._rightmotor .release = value
599+
600+
601+ class TargetTrackerMotor (Device ):
602+ """Motor device which can be used to track a target.
603+
604+ This type of motor is non-blocking by default and doesn't wait
605+ for a command to be finished. An actual running command will be overwritten. If you need sequential execution which
606+ wait's for a movement to finish, then use the ~Motor class.
607+
608+ :param port: Port of device
609+ :raises DeviceError: Occurs if there is no motor attached to port
610+ """
611+
612+ def __init__ (self , port ):
613+ """Initialise motor
614+
615+ :param port:
616+ """
617+ super ().__init__ (port )
618+ if self ._typeid in {38 }:
619+ self .mode ([(1 , 0 ), (2 , 0 )])
620+ self ._combi = "1 0 2 0"
621+ self ._noapos = True
622+ else :
623+ self .mode ([(1 , 0 ), (2 , 0 ), (3 , 0 )])
624+ self ._combi = "1 0 2 0 3 0"
625+ self ._noapos = False
626+ self .plimit (0.7 )
627+ self .bias (0.3 )
628+ self ._init_pid ()
629+
630+ def _init_pid (self ):
631+ """Initialize the pid controller"""
632+ cmd = f"pid { self .port } 0 5 s2 0.0027777778 1 5 0 .1 3\r "
633+ self ._write (cmd )
634+
635+ def plimit (self , plimit ):
636+ """Limit power
637+
638+ :param plimit: Value 0 to 1
639+ :raises MotorError: Occurs if invalid plimit value passed
640+ """
641+ if not (0 <= plimit <= 1 ):
642+ raise MotorError ("plimit should be 0 to 1" )
643+ self ._write (f"port { self .port } ; plimit { plimit } \r " )
644+
645+ def bias (self , bias ):
646+ """Bias motor
647+
648+ :param bias: Value 0 to 1
649+ :raises MotorError: Occurs if invalid bias value passed
650+ """
651+ if not (0 <= bias <= 1 ):
652+ raise MotorError ("bias should be 0 to 1" )
653+ self ._write (f"port { self .port } ; bias { bias } \r " )
654+
655+ def run_to_position (self , degrees ):
656+ """Run motor to position (in degrees)
657+
658+ :param degrees: Position in degrees from -180 to 180
659+ """
660+ cmd = f"port { self .port } ; set { 1 / 360 * degrees } \r "
661+ self ._write (cmd )
662+
663+ def get_position (self ):
664+ """Get position of motor with relation to preset position (can be negative or positive)
665+
666+ :return: Position of motor in degrees from preset position
667+ :rtype: int
668+ """
669+ return self .get ()[1 ]
670+
671+ def get_aposition (self ):
672+ """Get absolute position of motor
673+
674+ :return: Absolute position of motor from -180 to 180
675+ :rtype: int
676+ """
677+ if self ._noapos :
678+ raise MotorError ("No absolute position with this motor" )
679+ else :
680+ return self .get ()[2 ]
681+
682+ def get_speed (self ):
683+ """Get speed of motor
684+
685+ :return: Speed of motor
686+ :rtype: int
687+ """
688+ return self .get ()[0 ]
0 commit comments