コード例 #1
0
ファイル: test_board_config.py プロジェクト: BCCWAI/Tinymovr
 def setUpClass(cls):
     channel = guess_channel(bustype_hint=bustype)
     can_bus: can.Bus = can.Bus(bustype=bustype, channel=channel)
     iface: IFace = CAN(can_bus)
     cls.tm = Tinymovr(node_id=1, iface=iface)
     cls.tm.reset()
     time.sleep(0.2)
コード例 #2
0
def main():
    global tm1, tm2

    channel = guess_channel(bustype_hint='slcan')
    can_bus: can.Bus = can.Bus(bustype='slcan',
                               channel=channel,
                               bitrate=1000000)
    iface: IFace = CAN(can_bus)
    tm1 = Tinymovr(node_id=1, iface=iface)
    tm2 = Tinymovr(node_id=2, iface=iface)

    assert (tm1.motor_config.flags == 1)
    assert (tm2.motor_config.flags == 1)

    tm1.set_limits(300000, 25)
    tm2.set_limits(300000, 25)

    tm1.set_gains(280, 1.1e-4)
    tm2.set_gains(280, 1.1e-4)

    sleep(0.1)

    tm1.position_control()
    tm2.position_control()

    sleep(0.1)

    offset_1 = tm1.encoder_estimates.position
    offset_2 = tm2.encoder_estimates.position

    while True:
        est_1 = tm1.encoder_estimates
        est_2 = tm2.encoder_estimates

        mean_pos = ((est_1.position - offset_1) +
                    (est_2.position - offset_2)) / 2.0
        mean_vel = (est_1.velocity + est_2.velocity) / 2.0

        tm1.set_pos_setpoint(mean_pos + offset_1, mean_vel, 0)
        tm2.set_pos_setpoint(mean_pos + offset_2, mean_vel, 0)

        sleep(0.0005)
コード例 #3
0
def main():
    global tm1, tm2

    channel = guess_channel(bustype_hint='slcan')
    can_bus: can.Bus = can.Bus(bustype='slcan',
                               channel=channel,
                               bitrate=1000000)
    iface: IFace = CAN(can_bus)
    tm1 = Tinymovr(node_id=1, iface=iface)
    tm2 = Tinymovr(node_id=2, iface=iface)

    assert (tm1.motor_config.flags == 1)
    assert (tm2.motor_config.flags == 1)

    tm1.set_limits(200000, 15)
    tm2.set_limits(200000, 15)

    sleep(0.1)

    tm1.current_control()
    tm2.current_control()

    sleep(0.1)

    offset_1 = tm1.encoder_estimates.position
    offset_2 = tm2.encoder_estimates.position

    while True:
        est_1 = tm1.encoder_estimates
        est_2 = tm2.encoder_estimates
        p_1 = est_1.position - offset_1
        p_2 = est_2.position - offset_2
        v_1 = est_1.velocity
        v_2 = est_2.velocity

        Iq_1 = (3e-3 * (p_2 - p_1) * (A / tick) + 5e-5 * (v_2 - v_1) *
                (A * s / tick))
        Iq_2 = (3e-3 * (p_1 - p_2) * (A / tick) + 5e-5 * (v_1 - v_2) *
                (A * s / tick))

        tm1.set_cur_setpoint(Iq_1)
        tm2.set_cur_setpoint(Iq_2)

        sleep(0.0001)
コード例 #4
0
ファイル: user_wrapper.py プロジェクト: BCCWAI/Tinymovr
 def __init__(self, **kwargs):
     self.tinymovr = Tinymovr(**kwargs)
コード例 #5
0
ファイル: user_wrapper.py プロジェクト: BCCWAI/Tinymovr
class UserWrapper:
    '''
    This is a user-friendly wrapper to the Tinymover class, that
    allows more intuitive functions to be used instead of plain
    getters/setters.
    This class sacrifices Pythonic-ness (e.g. raising exceptions)
    for better user-friendliness (e.g. using simple print statements).
    There are also additional checks performed prior to changing
    states, with errors displayed if checks fail.
    '''
    def __init__(self, **kwargs):
        self.tinymovr = Tinymovr(**kwargs)

    def __getattr__(self, attr):
        return getattr(self.tinymovr, attr)

    def calibrate(self):
        '''
        Enter calibration state, perform motor and encoder calibration
        '''
        state = self.tinymovr.state
        if state.error != 0:
            print("Error flag present, cannot continue with calibration. \
Please reset Tinymovr.")
        elif state.state != 0:
            print("Tinymovr state is not idle, \
calibration needs to be started from idle state.")
        else:
            input("Ready to calibrate. Please remove any loads \
from the motor and hit Enter to continue")
            self.tinymovr.calibrate()

    def idle(self):
        '''
        Enter idle state
        '''
        self.tinymovr.set_state(0)

    def position_control(self):
        '''
        Enter closed loop control state and position control mode
        '''
        state = self.tinymovr.state
        if state.error != 0:
            print("Error flag present, cannot enable position control. \
Please reset Tinymovr.")
        elif state.state == 1:
            print("Tinymovr is currently calibrating, \
please do not interrupt.")
        else:
            self.tinymovr.position_control()

    def velocity_control(self):
        '''
        Enter closed loop control state and velocity control mode
        '''
        state = self.tinymovr.state
        if state.error != 0:
            print("Error flag present, cannot enable velocity control. \
Please reset Tinymovr.")
        elif state.state == 1:
            print("Tinymovr is currently calibrating, \
please do not interrupt.")
        else:
            self.tinymovr.velocity_control()

    def current_control(self):
        '''
        Enter closed loop control state and current control mode
        '''
        state = self.tinymovr.state
        if state.error != 0:
            print("Error flag present, cannot enable current control. \
Please reset Tinymovr.")
        elif state.state == 1:
            print("Tinymovr is currently calibrating, \
please do not interrupt.")
        else:
            self.tinymovr.current_control()

    @property
    def error(self):
        '''
        Report controller error in human-readable form
        '''
        state = self.tinymovr.state
        error_id = ErrorIDs(state.error)
        print(error_descriptions[error_id] + " (error code: " + str(error_id) +
              ")")

    def __dir__(self):
        tm_keys = self.tinymovr.__dir__()
        self_keys = object.__dir__(self)
        self_keys.remove("tinymovr")
        return tm_keys + self_keys
コード例 #6
0
def get_tm() -> Tinymovr:
    can_bus: can.Bus = can.Bus(bustype=bustype, channel=channel)
    iface: IFace = CAN(can_bus)
    tm = Tinymovr(node_id=1, iface=iface)
    tm.iface.bus.legacy_errors = True
    return tm
コード例 #7
0
ファイル: test_simulation.py プロジェクト: yconst/Tinymovr
def get_tm() -> Tinymovr:
    can_bus: can.Bus = can.Bus(bustype=bustype, channel=channel)
    iface: IFace = CANBus(can_bus)
    return Tinymovr(node_id=1, iface=iface)
コード例 #8
0
dt = 0.01
step = 1 * deg
period = 2 * s
current_threshold = 8.0 * A
sign = 0
ratio = 9
goon = True
position = 0 * deg
modepygame = 0

# channel = guess_channel(bustype_hint='slcan')
channel = '/dev/ttyS7'
can_bus = can.Bus(bustype='slcan', channel=channel, bitrate=1000000)
iface = CAN(can_bus)
tm = Tinymovr(node_id=1, iface=iface)

tm.set_limits(velocity=2000 * turn / min, current=8.0 * A)
tm.set_gains(position=100.0, velocity=0.0001)
tm.set_integrator_gains(velocity=0.001)

print(tm.motor_info)
print(tm.device_info)

print("ZERO")
position = tm.encoder_estimates.position

while goon:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            goon = False
コード例 #9
0
t0 = 0
Y0 = 0.0 * m
Z0 = 0.0 * m
alpha = 0.0 * deg
D = 0.0 * m
E = 0.0 * m
F = 0.0 * m
Yfoot = 0.0 * m
Zfoot = (L1 + L2) * m
modepygame = -1

# channel = guess_channel(bustype_hint='slcan')
channel = '/dev/ttyS7'
can_bus = can.Bus(bustype='slcan', channel=channel, bitrate=1000000)
iface = CAN(can_bus)
tm1 = Tinymovr(node_id=2, iface=iface)
tm2 = Tinymovr(node_id=1, iface=iface)

maxspeed = 1500 * turn / min
tm1.set_limits(velocity=maxspeed * 1.5, current=22.0 * A)
tm2.set_limits(velocity=maxspeed, current=22.0 * A)
tm1.set_gains(position=100.0, velocity=0.0002)
tm2.set_gains(position=100.0, velocity=0.0002)
tm1.set_integrator_gains(velocity=0.001)
tm2.set_integrator_gains(velocity=0.001)

# print(tm1.motor_info)
# print(tm2.motor_info)
# print(tm1.device_info)
# print(tm2.device_info)
jump = 0.08
コード例 #10
0
ファイル: user_wrapper.py プロジェクト: yconst/Tinymovr
class UserWrapper:
    """
    This is a user-friendly wrapper to the Tinymover class, that
    allows more intuitive functions to be used instead of plain
    getters/setters.
    This class sacrifices Pythonic-ness (e.g. raising exceptions)
    for better user-friendliness (e.g. using simple print statements).
    There are also additional checks performed prior to changing
    states, with errors displayed if checks fail.
    """
    def __init__(self, *args, **kwargs):
        self.tinymovr = Tinymovr(*args, **kwargs)

    def __getattr__(self, attr):
        return getattr(self.tinymovr, attr)

    def calibrate(self):
        """
        Enter calibration state, perform motor and encoder calibration
        """
        state = self.tinymovr.state
        if state.errors:
            print(
                "Error flag present, cannot continue with calibration. Please reset Tinymovr."
            )
        elif state.state != ControlStates.Idle:
            print("Tinymovr not in idle state, calibration cannot start.")
        else:
            input(
                "Ready to calibrate. Please remove any loads from the motor and hit Enter to continue."
            )
            self.tinymovr.calibrate()

    def idle(self):
        """
        Enter idle state
        """
        if self.tinymovr.state.state == ControlStates.Calibration:
            print(msg_calibrating)
        else:
            self.tinymovr.idle()

    def position_control(self):
        """
        Enter closed loop control state and position control mode
        """
        state = self.tinymovr.state
        if state.errors:
            print(
                "Error flag present, cannot enable position control. Please reset Tinymovr."
            )
        elif state.state == ControlStates.Calibration:
            print(msg_calibrating)
        else:
            self.tinymovr.position_control()

    def velocity_control(self):
        """
        Enter closed loop control state and velocity control mode
        """
        state = self.tinymovr.state
        if state.errors:
            print(
                "Error flag present, cannot enable velocity control. Please reset Tinymovr."
            )
        elif state.state == ControlStates.Calibration:
            print(msg_calibrating)
        else:
            self.tinymovr.velocity_control()

    def current_control(self):
        """
        Enter closed loop control state and current control mode
        """
        state = self.tinymovr.state
        if state.errors:
            print(
                "Error flag present, cannot enable current control. Please reset Tinymovr."
            )
        elif state.state == ControlStates.Calibration:
            print(msg_calibrating)
        else:
            self.tinymovr.current_control()

    def __dir__(self):
        tm_attrs = self.tinymovr.__dir__()
        self_attrs = [k for k in object.__dir__(self) if not k.startswith("_")]
        self_attrs.remove("tinymovr")
        return sorted(list(set(tm_attrs + self_attrs)))
コード例 #11
0
T0 = 21.3 / 20  #20 oscillations in 21.3s
# pendulum natural pulsation
w0 = 2 * pi / T0 * rad / s
nrj0 = -w0 * w0

# pygame init
pygame.init()
ecran = pygame.display.set_mode((1000, 1000))
font = pygame.font.SysFont(None, 48)

# Instanciate Tinymovr interface
# channel = guess_channel(bustype_hint='slcan')
channel = '/dev/ttyS17'
can_bus = can.Bus(bustype='slcan', channel=channel, bitrate=1000000)
iface = CANBus(can_bus)
tm = Tinymovr(node_id=1, iface=iface)

# initialise motor control gains and limits
tm.set_limits(velocity=2000 * turn / min, current=10.0 * A)
tm.set_gains(position=40.0, velocity=0.002)
tm.set_integrator_gains(velocity=0.0000)
print(tm.motor_info)
print(tm.device_info)

# set the zero (assuming the pendulum is downward and still, else, press "z" key)
theta0 = tm.encoder_estimates.position.to(rad)
thetap0 = tm.encoder_estimates.velocity.to(rad / s)

# control loop (100Hz)
while goon:
    # recup keyboard input