예제 #1
0
def connect_to_exos(file_ID: str = None,
                    target_freq: int = 200,
                    actpack_freq: int = 200,
                    log_en: bool = False,
                    log_level: int = 3,
                    do_read_fsrs: bool = False,
                    max_allowable_current: int = 20000):
    '''Connect to Exos, instantiate Exo objects.'''

    # Load Ports and baud rate
    if fxu.is_win():  # Need for WebAgg server to work in Python 3.8
        print('Detected win32')
        import asyncio
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
        port_cfg_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), "ports.yaml")
        ports, baud_rate = fxu.load_ports_from_file(port_cfg_path)
    elif fxu.is_pi64() or fxu.is_pi():
        ports = ['/dev/ttyACM0', '/dev/ttyACM1']
        baud_rate = 230400
    else:
        raise ValueError('Max Code only supporting Windows or pi64 so far')
    print(f"Using ports:\t{ports}")

    exo_list = []
    for port in ports:
        try:
            dev_id = fxs.open(port, baud_rate, log_level=log_level)
            fxs.start_streaming(dev_id=dev_id,
                                freq=actpack_freq,
                                log_en=log_en)
            exo_list.append(
                Exo(dev_id=dev_id,
                    file_ID=file_ID,
                    target_freq=target_freq,
                    do_read_fsrs=do_read_fsrs,
                    max_allowable_current=max_allowable_current))
        except IOError:
            print('Unable to open exo on port: ', port,
                  ' This is okay if only one exo is connected!')

    if not exo_list:  # (if empty)
        raise RuntimeError('No Exos connected')
    return exo_list
예제 #2
0
    def __init__(self,
                 dev_id: int,
                 max_allowable_current: int,
                 file_ID: str = None,
                 target_freq: float = 200,
                 do_read_fsrs: bool = False):
        '''Exo object is the primary interface with the Dephy ankle exos, and corresponds to a single physical exoboot.
        Args:
            dev_id: int. Unique integer to identify the exo in flexsea's library. Returned by connect_to_exo
            file_ID: str. Unique string added to filename. If None, no file will be saved.
            do_read_dsrs: bool indicating whether to read FSRs '''
        self.dev_id = dev_id
        self.max_allowable_current = max_allowable_current
        self.file_ID = file_ID
        self.do_read_fsrs = do_read_fsrs
        if self.dev_id is None:
            print(
                'Exo obj created but no exoboot connected. Some methods available'
            )
        elif self.dev_id in constants.LEFT_EXO_DEV_IDS:
            self.side = constants.Side.LEFT
            self.motor_sign = -1
            self.ankle_to_motor_angle_polynomial = constants.LEFT_ANKLE_TO_MOTOR
            self.ankle_angle_offset = constants.LEFT_ANKLE_ANGLE_OFFSET
        elif self.dev_id in constants.RIGHT_EXO_DEV_IDS:
            self.side = constants.Side.RIGHT
            self.motor_sign = 1
            self.ankle_to_motor_angle_polynomial = constants.RIGHT_ANKLE_TO_MOTOR
            self.ankle_angle_offset = constants.RIGHT_ANKLE_ANGLE_OFFSET
        else:
            raise ValueError(
                'dev_id: ', self.dev_id,
                'not found in constants.LEFT_EXO_DEV_IDS or constants.RIGHT_EXO_DEV_IDS'
            )
        self.motor_offset = 0
        # ankle velocity filter is hardcoded for simplicity, but can be factored out if necessary
        self.ankle_velocity_filter = filters.Butterworth(N=2,
                                                         Wn=10,
                                                         fs=target_freq)
        if self.do_read_fsrs:
            print('do_read_fsrs: True. Checking if rpi')
            if fxu.is_pi() or fxu.is_pi64():
                import gpiozero  # pylint: disable=import-error
                if self.side == constants.Side.LEFT:
                    self.heel_fsr_detector = gpiozero.InputDevice(
                        pin=constants.LEFT_HEEL_FSR_PIN, pull_up=True)
                    self.toe_fsr_detector = gpiozero.InputDevice(
                        pin=constants.LEFT_TOE_FSR_PIN, pull_up=True)
                else:
                    self.heel_fsr_detector = gpiozero.InputDevice(
                        pin=constants.RIGHT_HEEL_FSR_PIN, pull_up=True)
                    self.toe_fsr_detector = gpiozero.InputDevice(
                        pin=constants.RIGHT_TOE_FSR_PIN, pull_up=True)
            else:
                raise Exception('Can only use FSRs with rapberry pi!')

        self.data = self.DataContainer(do_include_FSRs=do_read_fsrs)
        self.has_calibrated = False
        self.is_clipping = False
        if self.file_ID is not None:
            self.setup_data_writer(file_ID=file_ID)
        if self.dev_id is not None:
            self.update_gains(Kp=constants.DEFAULT_KP,
                              Ki=constants.DEFAULT_KI,
                              Kd=constants.DEFAULT_KD,
                              k_val=0,
                              b_val=0,
                              ff=constants.DEFAULT_FF)
        self.TR_from_ankle_angle = interpolate.PchipInterpolator(
            constants.ANKLE_PTS, self.motor_sign * constants.TR_PTS)
#!/usr/bin/env python3
"""
FlexSEA Two Position Control Demo
"""
from time import sleep, time
import matplotlib
import matplotlib.pyplot as plt
from flexsea import fxUtils as fxu
from flexsea import fxEnums as fxe
from flexsea import flexsea as flex

matplotlib.use("WebAgg")
if fxu.is_pi():
    matplotlib.rcParams.update({"webagg.address": "0.0.0.0"})


def two_position_control(
    fxs,
    port,
    baud_rate,
    exp_time=13,
    time_step=0.1,
    delta=10000,
    transition_time=1.5,
    resolution=100,
):
    """
	Send two positions commands to test the positionc controller
	"""
    # Open device
    dev_id = fxs.open(port, baud_rate, 0)