Example #1
0
damping = Damping(robot_config, kv=10)
# instantiate controller
ctrlr = OSC(
    robot_config,
    kp=200,
    null_controllers=[damping],
    vmax=[0.5, 0],  # [m/s, rad/s]
    # control (x, y, z) out of [x, y, z, alpha, beta, gamma]
    ctrlr_dof=[True, True, True, False, False, False])

# create our adaptive controller
adapt = signals.DynamicsAdaptation(
    n_neurons=1000,
    n_ensembles=5,
    n_input=2,  # we apply adaptation on the most heavily stressed joints
    n_output=2,
    pes_learning_rate=5e-5,
    intercepts_bounds=[-0.6, -0.2],
    intercepts_mode=-0.2,
    means=[3.14, 3.14],
    variances=[1.57, 1.57])

# create our VREP interface
interface = VREP(robot_config, dt=.005)
interface.connect()

# set up lists for tracking data
ee_track = []
target_track = []

# get Jacobians to each link for calculating perturbation
J_links = [
Example #2
0
# damp the movements of the arm
damping = Damping(robot_config, kv=10)
# create an operational space controller
ctrlr = OSC(
    robot_config,
    kp=50,
    null_controllers=[damping],
    # control (x, y) out of [x, y, z, alpha, beta, gamma]
    ctrlr_dof=[True, True, False, False, False, False],
)

# create our nonlinear adaptive controller
adapt = signals.DynamicsAdaptation(
    n_input=robot_config.N_JOINTS,
    n_output=robot_config.N_JOINTS,
    pes_learning_rate=1e-4,
    means=[0, 0, 0],
    variances=[np.pi, np.pi, np.pi],
)


def on_click(self, mouse_x, mouse_y):
    self.target[0] = self.mouse_x
    self.target[1] = self.mouse_y


def on_keypress(self, key):
    if key == pygame.K_SPACE:
        self.adaptation = not self.adaptation
        print("adaptation: ", self.adaptation)
Example #3
0
robot_config = arm.Config(use_cython=True)
# get Jacobians to each link for calculating perturbation
J_links = [
    robot_config._calc_J('link%s' % ii, x=[0, 0, 0])
    for ii in range(robot_config.N_LINKS)
]

# create our arm simulation
arm_sim = arm.ArmSim(robot_config)

# create an operational space controller
ctrlr = OSC(robot_config, kp=50, vmax=10)

# create our nonlinear adaptation controller
adapt = signals.DynamicsAdaptation(n_input=robot_config.N_JOINTS,
                                   n_output=robot_config.N_JOINTS,
                                   pes_learning_rate=1e-4,
                                   backend='nengo')


def on_click(self, mouse_x, mouse_y):
    self.target[0] = self.mouse_x
    self.target[1] = self.mouse_y


def on_keypress(self, key):
    if key == pygame.K_SPACE:
        self.adaptation = not self.adaptation
        print('adaptation: ', self.adaptation)


# create our interface
# instantiate controller
ctrlr = OSC(
    robot_config,
    kp=200,
    null_controllers=[damping],
    vmax=[0.5, 0],  # [m/s, rad/s]
    # control (x, y, z) out of [x, y, z, alpha, beta, gamma]
    ctrlr_dof=[True, True, True, False, False, False],
)

# create our adaptive controller
adapt = signals.DynamicsAdaptation(
    n_neurons=5000,
    n_ensembles=5,
    n_input=10,  # we apply adaptation on the most heavily stressed joints
    n_output=5,
    pes_learning_rate=1e-4,
    means=[0.12, 2.14, 1.87, 4.32, 0.59, 0.12, -0.38, -0.42, -0.29, 0.36],
    variances=[0.08, 0.6, 0.7, 0.3, 0.6, 0.08, 1.4, 1.6, 0.7, 1.2],
    spherical=True,
)

target_geom_id = interface.sim.model.geom_name2id("target")
green = [0, 0.9, 0, 0.5]
red = [0.9, 0, 0, 0.5]

# set up lists for tracking data
ee_track = []
target_track = []
q_track = []
dq_track = []
Example #5
0
robot_config.Tx('EE', q=zeros)

ctrlr.generate(zeros, zeros, zeros)

interface = abr_jaco2.Interface(robot_config)

target_xyz = np.array([.57, 0.03, .87])

time_limit = 30 # in seconds

# create our adaptive controller
adapt = signals.DynamicsAdaptation(
    n_input=4,
    n_output=2,
    n_neurons=1000,
    pes_learning_rate=1e-4,
    means=[3.14, 3.14, 0.05, 0.05],
    variances=[3.14, 3.14, 1, 1],
    weights=None)

# connect to and initialize the arm
interface.connect()
interface.init_position_mode()
interface.send_target_angles(robot_config.START_ANGLES)

if plot_error:
    error_track = []

try:
    interface.init_force_mode()
Example #6
0
    def run_test(self,
                 n_neurons=1000,
                 n_ensembles=1,
                 decimal_scale=1,
                 test_name="adaptive_training",
                 session=None,
                 run=None,
                 weights_file=None,
                 pes_learning_rate=1e-6,
                 backend=None,
                 autoload=False,
                 time_limit=30,
                 target_type='single',
                 offset=None,
                 avoid_limits=False,
                 additional_mass=0,
                 kp=20,
                 kv=6,
                 ki=0,
                 integrate_err=False,
                 ee_adaptation=False,
                 joint_adaptation=False,
                 simulate_wear=False,
                 probe_weights=False,
                 seed=None,
                 friction_bootstrap=False,
                 redis_adaptation=False,
                 SCALES=None,
                 MEANS=None):
        """
        The test script used to collect data for training. The use of the
        adaptive controller and the type of backend can be specified. The script is
        also automated to use the correct weights files for continuous learning.
        The standard naming convention used is runs are consecutive tests where the previous
        learned weights are used. The whole of these runs are a single session.
        Multiple sessions of these runs can then be used for averaging and
        statictical purposes.

        The adaptive controller uses a 6 dimensional input and returns a 3 dimensional
        output. The base, shoulder and elbow joints' positions and velocities are
        used as the input, and the control signal for the corresponding joints gets
        returned.

        Parameters
        ----------
        n_neurons: int, Optional (Default: 1000)
            the number of neurons in the adaptive population
        n_ensembles: int, Optional (Default: 1)
            the number of ensembles of n_neurons number of neurons
        decimal_scale: int, Optional (Default: 1)
            used for scaling the spinnaker input. Due to precision limit, spinnaker
            input gets scaled to allow for more decimals, then scaled back once
            extracted. Also can be used to account for learning speed since
            spinnaker runs in real time
        test_name: string, Optional (Default: "dewolf_2017_data")
            folder name where data is saved
        session: int, Optional (Default: None)
            The current session number, if left to None then it will be automatically
            updated based on the current session. If the next session is desired then
            this will need to be updated.
        run: int, Optional (Default: None)
            The current nth run that specifies to use the weights from the n-1 run.
            If set to None if will automatically increment based off the last saved
            weights.
        weights_file: string, Optional (Default: None)
            the path to the desired saved weights to use. If None will
            automatically take the most recent weights saved in the 'test_name'
            directory
        pes_learning_rate: float, Optional (Default: 1e-6)
            the learning rate for the adaptive population
        backend: string
            None: non adaptive control, Optional (Default: None)
            'nengo': use nengo as the backend for the adaptive population
            'spinnaker': use spinnaker as the adaptive population
        autoload: boolean, Optional (Default: False)
            True: used the specified weights, or the last set of learned weights if
                  not specified
            False: use the specified weights, if not specified start learning from
                   zero
        time_limit: float, Optional (Default: 30)
            the time limit for each run in seconds
        target_type: string, Optional (Default: single)
            single: one target
            multi: five targets
            figure8: move in figure8 pattern
            vision: get target from vision system
        offset: float array, Optional (Default: None)
            Set the offset to the end effector if something other than the default
            is desired. Use the form [x_offset, y_offset, z_offset]
        avoid_limits: boolean, Optional (Default: False)
            set true if there are limits you would like to avoid
        additional_mass: float, Optional (Default: 0)
            any extra mass added to the EE if known [kg]
        kp: float, Optional (Default: 20)
            proportional gain term
        kv: float, Optional (Default: 6)
            derivative gain term
        ki: float, Optional (Default: 0)
            integral gain term
        integrate_err: Boolean, Optional (Default: False)
            True to add I term to PD control (PD -> PID)
        ee_adaptation: Booleanm Optional (Default: False)
            True if doing neural adaptation in task space
        joint_adaptation: Boolean Optional (Default: False)
            True if doing neural adaptation in joint space
        simulate_wear: Boolean Optional (Default: False)
            True to add a simulated wearing of the joints that mimics friction
            by opposing motion
        probe_weights: Boolean Optional (Default: False)
            True to probe adaptive population for decoders
        seed: int Optional, (Default: None)
            seed used for random number generation in adaptive population
        friction_bootstrap: Boolean Optional (Default: False)
            True if want to pass an estimate of the friction signal as starting
            point for adaptive population
        redis_adaptation: Boolean Optional (Default: False)
            True to send adaptive inputs to redis and read outputs back, allows
            user to use any backend they like as long as it can read/write from
            redis

        Attributes
        ----------
        TARGET_XYZ: array of floats
            the goal target, used for calculating error
        target: array of floats [x, y, z, vx, vy, vz]
            the filtered target, used for calculating error for figure8
            test since following trajectory and not moving to a single final
            point
        """
        print("RUN PASSED IN IS: ", run)

        if redis_adaptation:
            try:
                import redis
                redis_server = redis.StrictRedis(host='localhost')
            except ImportError:
                print(
                    "You must install redis to do adaptation through a redis" +
                    " server")

        # Set the target based on the source and type of test
        PRESET_TARGET = np.array([[.57, 0.03, .87]])

        if target_type == 'multi':
            PRESET_TARGET = np.array([[.56, -.09, .95], [.12, .15, .80],
                                      [.80, .26, .61], [.38, .46, .81],
                                      [.0, .0, 1.15]])
            time_limit /= len(PRESET_TARGET)

        elif target_type == 'vision':
            # try to setup redis server if vision targets are desired
            try:
                import redis
                redis_server = redis.StrictRedis(host='localhost')
                self.redis_server = redis_server
            except ImportError:
                print(
                    'ERROR: Install redis to use vision targets, using preset targets'
                )

        elif target_type == 'figure8':
            try:
                import pydmps
            except ImportError:
                print('\npydmps library required, see ' +
                      'https://github.com/studywolf/pydmps\n')

            # create a dmp that traces a figure8
            x = np.linspace(0, np.pi * 2, 100)
            dmps_traj = np.array([0.2 * np.sin(x), 0.2 * np.sin(2 * x) + 0.7])
            dmps = pydmps.DMPs_rhythmic(n_dmps=2, n_bfs=50, dt=0.001)
            dmps.imitate_path(dmps_traj)

        # get averages and scale of target locations for scaling into network
        x_avg = np.mean(PRESET_TARGET[:, 0])
        y_avg = np.mean(PRESET_TARGET[:, 1])
        z_avg = np.mean(PRESET_TARGET[:, 2])

        x_scale = np.max(PRESET_TARGET[:, 0]) - np.min(PRESET_TARGET[:, 0])
        y_scale = np.max(PRESET_TARGET[:, 1]) - np.min(PRESET_TARGET[:, 1])
        z_scale = np.max(PRESET_TARGET[:, 2]) - np.min(PRESET_TARGET[:, 2])

        # initialize our robot config
        robot_config = abr_jaco2.Config(use_cython=True,
                                        hand_attached=True,
                                        SCALES=SCALES,
                                        MEANS=MEANS)
        self.robot_config = robot_config

        zeros = np.zeros(robot_config.N_JOINTS)

        # get Jacobians to each link for calculating perturbation
        self.J_links = [
            robot_config._calc_J('link%s' % ii, x=[0, 0, 0])
            for ii in range(robot_config.N_LINKS)
        ]

        self.JEE = robot_config._calc_J('EE', x=[0, 0, 0])

        # account for wrist to fingers offset
        R_func = robot_config._calc_R('EE')

        # Use user defined offset if one is specified
        if offset is None:
            OFFSET = robot_config.OFFSET
        else:
            OFFSET = offset

        robot_config.Tx('EE', q=zeros, x=OFFSET)

        # temporarily set backend to nengo if non adaptive if selected so we can
        # still use the weight saving function in dynamics_adaptation.py in the
        # abr_control repo
        if backend is None:
            adapt_backend = 'nengo'
        else:
            adapt_backend = backend

        # create our adaptive controller
        if ee_adaptation and joint_adaptation:
            n_input = 4
            n_output = 3
        elif ee_adaptation and not joint_adaptation:
            n_input = 3
            n_output = 3
            pes_learning_rate /= ki
        elif joint_adaptation and not ee_adaptation:
            n_input = 4
            n_output = 2
        else:
            n_input = 1
            n_output = 1

        # for use with weight estimation, is the number of joint angles being
        # passed to the adaptive controller (not including velocities)
        self.adapt_dim = n_output
        self.decimal_scale = decimal_scale

        # if user specifies an additional mass, use the estimation function to
        # give the adaptive controller a better starting point
        self.additional_mass = additional_mass
        if self.additional_mass != 0 and weights_file is None:
            # if the user knows about the mass at the EE, try and improve
            # our starting point
            self.fake_gravity = np.array(
                [[0, 0, -9.81 * self.additional_mass, 0, 0, 0]]).T
            print('Using mass estimate of %f kg as starting point' %
                  self.additional_mass)
            adapt = signals.DynamicsAdaptation(
                n_input=n_input,
                n_output=n_output,
                n_neurons=n_neurons,
                n_ensembles=n_ensembles,
                pes_learning_rate=pes_learning_rate,
                intercepts=(-0.5, -0.2),
                weights_file=weights_file,
                backend=adapt_backend,
                session=session,
                run=run,
                test_name=test_name,
                autoload=autoload,
                function=self.gravity_estimate,
                probe_weights=probe_weights,
                seed=seed)

        elif friction_bootstrap and weights_file is None:
            # if the user knows about the friction, try and improve
            # our starting point
            print('Using friction estimate as starting point')
            adapt = signals.DynamicsAdaptation(
                n_input=n_input,
                n_output=n_output,
                n_neurons=n_neurons,
                n_ensembles=n_ensembles,
                pes_learning_rate=pes_learning_rate,
                intercepts=(-0.5, -0.2),
                weights_file=weights_file,
                backend=adapt_backend,
                session=session,
                run=run,
                test_name=test_name,
                autoload=autoload,
                function=lambda x: self.friction(x) * -1,
                probe_weights=probe_weights,
                seed=seed)
        else:
            adapt = signals.DynamicsAdaptation(
                n_input=n_input,
                n_output=n_output,
                n_neurons=n_neurons,
                n_ensembles=n_ensembles,
                pes_learning_rate=pes_learning_rate,
                intercepts=(-0.5, -0.2),
                weights_file=weights_file,
                backend=adapt_backend,
                session=session,
                run=run,
                test_name=test_name,
                autoload=autoload,
                probe_weights=probe_weights,
                seed=seed)

        # get save location of saved data
        [location, run_num] = adapt.weights_location(test_name=test_name,
                                                     run=run,
                                                     session=session)
        # if using integral term for PID control, check if previous weights
        # have been saved
        if integrate_err:
            if run_num < 1:
                run_num = 0
                int_err_prev = [0, 0, 0]
            else:
                int_err_prev = np.squeeze(
                    np.load(location + '/run%i_data/int_err%i.npz' %
                            (run_num - 1, run_num - 1))['int_err'])[-1]
        else:
            int_err_prev = None

        # instantiate operational space controller
        print('using int err of: ', int_err_prev)
        ctrlr = OSC(robot_config,
                    kp=kp,
                    kv=kv,
                    ki=ki,
                    vmax=1,
                    null_control=True,
                    int_err=int_err_prev)

        # add joint avoidance controller if specified to do so
        if avoid_limits:
            avoid = signals.AvoidJointLimits(
                robot_config,
                # joint 4 flipped because does not cross 0-2pi line
                min_joint_angles=[None, 1.1, 0.5, 3.5, 2.0, 1.6],
                max_joint_angles=[None, 3.65, 6.25, 6.0, 5.0, 4.6],
                max_torque=[4] * robot_config.N_JOINTS,
                cross_zero=[True, False, False, False, True, False],
                gradient=[False, True, True, True, True, False])
        # if not planning the trajectory (figure8 target) then use a second
        # order filter to smooth out the trajectory to target(s)
        if target_type != 'figure8':
            path = path_planners.SecondOrder(robot_config)
            n_timesteps = 4000
            w = 1e4 / n_timesteps
            zeta = 2
            dt = 0.003

        # run controller once to generate functions / take care of overhead
        # outside of the main loop, because force mode auto-exits after 200ms
        ctrlr.generate(zeros, zeros, np.zeros(3), offset=OFFSET)

        interface = abr_jaco2.Interface(robot_config)

        # connect to and initialize the arm
        interface.connect()
        interface.init_position_mode()
        interface.send_target_angles(robot_config.INIT_TORQUE_POSITION)

        # set up lists for tracking data
        time_track = []
        q_track = []
        dq_track = []
        u_track = []
        adapt_track = []
        error_track = []
        training_track = []
        target_track = []
        ee_track = []
        input_signal = []
        if integrate_err:
            int_err_track = []
        if simulate_wear:
            self.F_prev = np.array([0, 0])
            friction_track = []

        try:
            interface.init_force_mode()
            for ii in range(0, len(PRESET_TARGET)):
                # counter for print statements
                count = 0

                # track loop_time for stopping test
                loop_time = 0

                # get joint angle and velocity feedback
                feedback = interface.get_feedback()
                q = feedback['q']
                dq = feedback['dq']
                dq[abs(dq) < 0.05] = 0
                # calculate end-effector position
                ee_xyz = robot_config.Tx('EE', q=q, x=OFFSET)

                # last three terms used as started point for target EE velocity
                target = np.concatenate((ee_xyz, np.array([0, 0, 0])), axis=0)

                # M A I N   C O N T R O L   L O O P
                while loop_time < time_limit:
                    start = timeit.default_timer()
                    prev_xyz = ee_xyz

                    if target_type == 'vision':
                        TARGET_XYZ = self.get_target_from_camera()
                        TARGET_XYZ = self.normalize_target(TARGET_XYZ)
                        target = path.step(y=target[:3],
                                           dy=target[3:],
                                           target=TARGET_XYZ,
                                           w=w,
                                           zeta=zeta,
                                           dt=dt,
                                           threshold=0.05)

                    elif target_type == 'figure8':
                        y, dy, ddy = dmps.step()
                        target = [0.65, y[0], y[1], 0, dy[0], dy[1]]
                        TARGET_XYZ = target[:3]

                    else:
                        TARGET_XYZ = PRESET_TARGET[ii]
                        target = path.step(y=target[:3],
                                           dy=target[3:],
                                           target=TARGET_XYZ,
                                           w=w,
                                           zeta=zeta,
                                           dt=dt,
                                           threshold=0.05)

                    # calculate euclidean distance to target
                    error = np.sqrt(np.sum((ee_xyz - TARGET_XYZ)**2))

                    # get joint angle and velocity feedback
                    feedback = interface.get_feedback()
                    q = feedback['q']
                    dq = feedback['dq']
                    dq[abs(dq) < 0.05] = 0

                    # calculate end-effector position
                    ee_xyz = robot_config.Tx('EE', q=q, x=OFFSET)

                    if ee_adaptation and joint_adaptation:
                        # adaptive control in state space
                        training_signal = TARGET_XYZ - ee_xyz
                        # calculate the adaptive control signal
                        adapt_input = np.array([
                            robot_config.scaledown('q', q)[1],
                            robot_config.scaledown('q', q)[2],
                            robot_config.scaledown('dq', dq)[1],
                            robot_config.scaledown('dq', dq)[2]
                        ])
                        u_adapt = adapt.generate(
                            input_signal=adapt_input,
                            training_signal=training_signal)
                        u_adapt /= decimal_scale

                    elif ee_adaptation and not joint_adaptation:
                        # adaptive control in state space
                        training_signal = TARGET_XYZ - ee_xyz
                        # scale inputs
                        adapt_input = np.array([(ee_xyz[0] - x_avg) / x_scale,
                                                (ee_xyz[1] - y_avg) / y_scale,
                                                (ee_xyz[2] - z_avg) / z_scale])

                        u_adapt = adapt.generate(
                            input_signal=adapt_input,
                            training_signal=training_signal)
                        u_adapt /= decimal_scale

                    else:
                        u_adapt = None

                    # Need to create controller here, in case using ee
                    # adaptation, it needs to be passed to the OSC controller
                    # calculate the base operation space control signal
                    u_base = ctrlr.generate(q=q,
                                            dq=dq,
                                            target_pos=target[:3],
                                            target_vel=target[3:],
                                            offset=OFFSET,
                                            ee_adapt=u_adapt)

                    # account for stiction in jaco2 base
                    if u_base[0] > 0:
                        u_base[0] *= 3.0
                    else:
                        u_base[0] *= 2.0

                    if joint_adaptation and not ee_adaptation:
                        training_signal = np.array([
                            ctrlr.training_signal[1], ctrlr.training_signal[2]
                        ])
                        # calculate the adaptive control signal
                        adapt_input = np.array([
                            robot_config.scaledown('q', q)[1],
                            robot_config.scaledown('q', q)[2],
                            robot_config.scaledown('dq', dq)[1],
                            robot_config.scaledown('dq', dq)[2]
                        ])
                        u_adapt = adapt.generate(
                            input_signal=adapt_input,
                            training_signal=training_signal)

                        # add adaptive signal to base controller
                        u_adapt = np.array([
                            0, u_adapt[0] / decimal_scale,
                            u_adapt[1] / decimal_scale, 0, 0, 0
                        ])
                        u = u_base + u_adapt

                    elif redis_adaptation:
                        training_signal = np.array([
                            ctrlr.training_signal[1], ctrlr.training_signal[2]
                        ])
                        adapt_input = np.array([
                            robot_config.scaledown('q', q)[1],
                            robot_config.scaledown('q', q)[2],
                            robot_config.scaledown('dq', dq)[1],
                            robot_config.scaledown('dq', dq)[2]
                        ])
                        # send input information to redis
                        redis_server.set(
                            'input_signal', '%.3f %.3f %.3f %.3f' %
                            (adapt_input[0], adapt_input[1], adapt_input[2],
                             adapt_input[3]))
                        redis_server.set(
                            'training_signal', '%.3f %.3f' %
                            (training_signal[0], training_signal[1]))
                        # get adaptive output back
                        u_adapt = redis_server.get('u_adapt').decode('ascii')
                        u_adapt = np.array(
                            [float(val) for val in u_adapt.split()])
                        u_adapt = np.array(
                            [0, u_adapt[0], u_adapt[1], 0, 0, 0])
                        u = u_base + u_adapt

                    else:
                        u = u_base
                        u_adapt = None
                        training_signal = np.zeros(3)
                        adapt_input = np.zeros(3)

                    # add limit avoidance if True
                    if avoid_limits:
                        u += avoid.generate(q)

                    if simulate_wear:
                        u_friction = self.friction(dq[1:3])
                        u += [0, u_friction[0], u_friction[1], 0, 0, 0]
                        friction_track.append(np.copy(u_friction))

                    # send forces
                    interface.send_forces(np.array(u, dtype='float32'))

                    # track data
                    q_track.append(np.copy(q))
                    dq_track.append(np.copy(dq))
                    u_track.append(np.copy(u))
                    adapt_track.append(np.copy(u_adapt))
                    error_track.append(np.copy(error))
                    training_track.append(np.copy(training_signal))
                    end = timeit.default_timer() - start
                    loop_time += end
                    time_track.append(np.copy(end))
                    target_track.append(np.copy(TARGET_XYZ))
                    input_signal.append(np.copy(adapt_input))
                    ee_track.append(np.copy(ee_xyz))
                    if integrate_err:
                        int_err_track.append(np.copy(ctrlr.int_err))

                    if count % 1000 == 0:
                        print('error: ', error)
                        print('dt: ', end)
                        #print('adapt: ', u_adapt)
                        #print('int_err/ki: ', ctrlr.int_err)
                        #print('q: ', q)
                        #print('hand: ', ee_xyz)
                        #print('target: ', target)
                        #print('control: ', u_base)

                    count += 1

        except:
            print(traceback.format_exc())

        finally:
            # close the connection to the arm
            interface.init_position_mode()

            print("RUN IN IS: ", run)
            # get save location of weights to save tracked data in same directory
            [location, run_num] = adapt.weights_location(test_name=test_name,
                                                         run=run,
                                                         session=session)
            print("RUN OUT IS: ", run_num)
            if backend != None:
                run_num += 1

                # Save the learned weights
                adapt.save_weights(test_name=test_name,
                                   session=session,
                                   run=run)

            interface.send_target_angles(robot_config.INIT_TORQUE_POSITION)
            interface.disconnect()

            print('**** RUN STATS ****')
            print('Average loop speed: ', sum(time_track) / len(time_track))
            print('AVG Error/Step: ', sum(error_track) / len(error_track))
            print('Run number ', run_num)
            print('Saving tracked data to ',
                  location + '/run%i_data' % (run_num))
            print('*******************')

            time_track = np.array(time_track)
            q_track = np.array(q_track)
            u_track = np.array(u_track)
            adapt_track = np.array(adapt_track)
            error_track = np.array(error_track)
            training_track = np.array(training_track)
            input_signal = np.array(input_signal)
            ee_track = np.array(ee_track)
            dq_track = np.array(dq_track)
            if integrate_err:
                int_err_track = np.array(int_err_track)
            if simulate_wear:
                friction_track = np.array(friction_track)

            if not os.path.exists(location + '/run%i_data' % (run_num)):
                os.makedirs(location + '/run%i_data' % (run_num))

            np.savez_compressed(location + '/run%i_data/q%i' %
                                (run_num, run_num),
                                q=[q_track])
            np.savez_compressed(location + '/run%i_data/time%i' %
                                (run_num, run_num),
                                time=[time_track])
            np.savez_compressed(location + '/run%i_data/u%i' %
                                (run_num, run_num),
                                u=[u_track])
            np.savez_compressed(location + '/run%i_data/adapt%i' %
                                (run_num, run_num),
                                adapt=[adapt_track])
            np.savez_compressed(location + '/run%i_data/target%i' %
                                (run_num, run_num),
                                target=[target_track])
            np.savez_compressed(location + '/run%i_data/error%i' %
                                (run_num, run_num),
                                error=[error_track])
            np.savez_compressed(location + '/run%i_data/training%i' %
                                (run_num, run_num),
                                training=[training_track])
            np.savez_compressed(location + '/run%i_data/input_signal%i' %
                                (run_num, run_num),
                                input_signal=[input_signal])
            np.savez_compressed(location + '/run%i_data/ee_xyz%i' %
                                (run_num, run_num),
                                ee_xyz=[ee_track])
            np.savez_compressed(location + '/run%i_data/dq%i' %
                                (run_num, run_num),
                                dq=[dq_track])
            if probe_weights:
                np.savez_compressed(
                    location + '/run%i_data/probe%i' % (run_num, run_num),
                    probe=[adapt.sim.data[adapt.nengo_model.weights_probe]])
            if integrate_err:
                np.savez_compressed(location + '/run%i_data/int_err%i' %
                                    (run_num, run_num),
                                    int_err=[int_err_track])
            if simulate_wear:
                np.savez_compressed(location + '/run%i_data/friction%i' %
                                    (run_num, run_num),
                                    friction=[friction_track])

            if backend != 'nengo_spinnaker':
                # give user time to pause before the next run starts, only
                # works if looping through tests using a bash script
                import time
                print('2 Seconds to pause: Hit ctrl z to pause, fg to resume')
                time.sleep(1)
                print('1 Second to pause')
                time.sleep(1)
                print('Starting next test...')
    mode=0.0,
    seed=seed)

# ----------- Create your encoders ---------------
hypersphere = ScatteredHypersphere(surface=True)
encoders = hypersphere.sample(n_ensembles*n_neurons, n_input)
encoders = encoders.reshape(n_ensembles, n_neurons, n_input)

# ----------- Instantiate your nengo simulator ---------------
# This example uses the network defined in
# abr_control/controllers/signals/dynamics_adaptation.py
network = signals.DynamicsAdaptation(
    n_input=n_input,
    n_output=n_output,
    n_neurons=n_neurons,
    n_ensembles=n_ensembles,
    pes_learning_rate=pes,
    intercepts=intercepts,
    seed=seed,
    encoders=encoders)

# create our figure object
fig = plt.figure(figsize=(8,12))
ax_list = [
      fig.add_subplot(311),
      fig.add_subplot(312),
      fig.add_subplot(313)
     ]
plt.tight_layout()

# pass your network and input signal to the network utils module
Example #8
0
# initialize our robot config for the jaco2
robot_config = arm.Config(use_cython=True, hand_attached=True)

# get Jacobians to each link for calculating perturbation
J_links = [robot_config._calc_J('link%s' % ii, x=[0, 0, 0])
           for ii in range(robot_config.N_LINKS)]

# instantiate controller
ctrlr = OSC(robot_config, kp=200, vmax=0.5)

# create our adaptive controller
adapt = signals.DynamicsAdaptation(
    backend='nengo',
    n_neurons=5000,
    n_input=2,  # we apply adaptation on the most heavily stressed joints
    n_output=2,
    weights_file=None,
    pes_learning_rate=1e-2,
    intercepts=(-.9, -.2))

# create our VREP interface
interface = VREP(robot_config, dt=.005)
interface.connect()

# set up lists for tracking data
ee_track = []
target_track = []


try:
    # get the end-effector's initial position
Example #9
0
robot_config.Tx('EE', q=zeros)

ctrlr.generate(zeros, zeros, zeros)

interface = abr_jaco2.Interface(robot_config)

target_xyz = np.array([.57, 0.03, .87])

time_limit = 30 # in seconds

# create our adaptive controller
adapt = signals.DynamicsAdaptation(
    n_input=4,
    n_output=2,
    n_neurons=1000,
    pes_learning_rate=5e-4,
    intercepts_bounds=(-0.9, 0.0),
    means=[3.14, 3.14, 0.05, 0.05],
    variances=[3.14, 3.14, 1, 1],
    weights=None)

# connect to and initialize the arm
interface.connect()
interface.init_position_mode()
interface.send_target_angles(robot_config.INIT_TORQUE_POSITION)

if plot_error:
    error_track = []

try:
    interface.init_force_mode()
Example #10
0
ctrlr = OSC(robot_config, kp=200, vmax=0.5)

if backend == 'nengo_spinnaker':
    # 1 sec of simulation takes 5 minutes 30 seconds, adjust
    # learning rate since spinnaker runs in real time
    # spinnaker_run_time/sim_run_time = (1sec/sec)/(330sec/sec)
    time_scale = 1/330
else:
    time_scale = 1

# create our adaptive controller
adapt = signals.DynamicsAdaptation(
    backend='nengo',
    n_neurons=500,
    n_ensembles=1,
    n_input=robot_config.N_JOINTS,
    n_output=robot_config.N_JOINTS,
    weights_file=None,
    pes_learning_rate=1e-4,
    intercepts=(-0.1, 1.0))

# create our VREP interface
interface = VREP(robot_config, dt=.001)
interface.connect()

# set up lists for tracking data
ee_track = []
target_track = []


try:
def run(encoders, intercept_vals, input_signal, seed=1,
        db_name='intercepts_scan', save_name='example', notes='',
        analysis_fncs=None, **kwargs):
    '''
    runs a scan for the proportion of neurons that are active over time

    PARAMETERS
    ----------
    encoders: array of floats (n_neurons x n_inputs)
        the values that specify along what vector a neuron will be
        sensitive to
    intercept_vals: array of floats (n_intercepts to try x 3)
        the [left_bound, mode, right_bound] to pass on to the triangluar
        intercept function in network_utils
    input_signal: array of floats (n_timesteps x n_inputs)
        the input signal that we want to check our networks response to
    seed: int
        the seed used for any randomization in the sim
    save_name: string, Optional (Default: proportion_neurons)
        the name to save the data under in the intercept_scan database
    notes: string, Optional (Default: '')
        any additional notes to save with the scan
    analysis_fncs: list of network_utils functions to apply to the spike trains
        the function must accept network and input signal, and return a list of
        data and activity
    '''
    if not isinstance(analysis_fncs, list):
        analysis_fncs = [analysis_fncs]

    print('Input Signal Shape: ', np.asarray(input_signal).shape)

    loop_time = 0
    elapsed_time = 0
    for ii, intercept in enumerate(intercept_vals):
        start = timeit.default_timer()
        elapsed_time += loop_time
        print('%i/%i | ' % (ii+1, len(intercept_vals))
              + '%.2f%% Complete | ' % (ii/len(intercept_vals)*100)
              + '%.2f min elapsed | ' % (elapsed_time/60)
              + '%.2f min for last sim | ' % (loop_time/60)
              + '~%.2f min remaining...'
              % ((len(intercept_vals)-ii)*loop_time/60),
              end='\r')

        # create our intercept distribution from the intercepts vals
        # Generates intercepts for a d-dimensional ensemble, such that, given a
        # random uniform input (from the interior of the d-dimensional ball), the
        # probability of a neuron firing has the probability density function given
        # by rng.triangular(left, mode, right, size=n)
        np.random.seed(seed)
        triangular = np.random.triangular(
            # intercept_vals = [left, right, mode]
            left=intercept[0],
            right=intercept[1],
            mode=intercept[2],
            size=encoders.shape[1],
        )
        intercepts = nengo.dists.CosineSimilarity(encoders.shape[2] + 2).ppf(1 - triangular)
        intercept_list = intercepts.reshape((1, encoders.shape[1]))

        print()
        print(intercept)
        print(intercept_list)

        # create a network with the new intercepts
        network = signals.DynamicsAdaptation(
            n_input=encoders.shape[2],
            n_output=1,  # number of output is irrelevant
            n_neurons=encoders.shape[1],
            intercepts=intercept_list,
            seed=seed,
            encoders=encoders,
            **kwargs)

        # get the spike trains from the sim
        spike_trains = network_utils.get_activities(
            network=network, input_signal=input_signal,
            synapse=0.005)

        # loop through the analysis functions
        for func in analysis_fncs:
            func_name = func.__name__
            y, activity = func(network=network, input_signal=input_signal,
                               pscs=spike_trains)

            # get the number of active and inactive neurons
            num_active, num_inactive = (
                network_utils.n_neurons_active_and_inactive(activity=activity))

            if ii == 0:
                dat = DataHandler(db_name)
                dat.save(
                    data={'total_intercepts': len(intercept_vals),
                          'notes': notes},
                    save_location='%s/%s' % (save_name, func_name),
                    overwrite=True)

            # not saving activity because takes up a lot of disk space
            data = {'intercept_bounds': intercept[:2],
                    'intercept_mode': intercept[2],
                    'y': y,
                    'num_active': num_active,
                    'num_inactive': num_inactive,
                    'title': func_name
                    }
            dat.save(data=data, save_location='%s/%s/%05d' %
                     (save_name, func_name, ii), overwrite=True)

            loop_time = timeit.default_timer() - start