Exemple #1
0
class BaxterLearning():
    """docstring for BaxterLearning"""
    def __init__(self):

        if not self.load_parameters(): sys.exit(1)

        self._limb = baxter_interface.Limb(self._arm)
        self._kin = baxter_kinematics(self._arm)

        self._planner = PathPlanner('{}_arm'.format(self._arm))

        rospy.on_shutdown(self.shutdown)

        plan = self._planner.plan_to_joint_pos(
            np.array([-0.6, -0.4, -0.5, 0.6, -0.4, 1.1, -0.5]))
        self._planner.execute_plan(plan)
        rospy.sleep(5)

        ################################## Tensorflow bullshit
        if self._learning_bool:
            # I DON'T KNOW HOW THESE WORK
            #define placeholders
            observation_space = spaces.Box(low=-100,
                                           high=100,
                                           shape=(21, ),
                                           dtype=np.float32)
            action_space = spaces.Box(low=-50,
                                      high=50,
                                      shape=(56, ),
                                      dtype=np.float32)
            self._x_ph, self._u_ph = core.placeholders_from_spaces(
                observation_space, action_space)

            #define actor critic
            #TODO add in central way to accept arguments
            self._pi, self._logp, self._logp_pi, self._v = core.mlp_actor_critic(
                self._x_ph,
                self._u_ph,
                hidden_sizes=(128, 2),
                action_space=action_space)
            # POLY_ORDER = 2
            # self._pi, self._logp, self._logp_pi, self._v = core.polynomial_actor_critic(
            #     self._x_ph, self._u_ph, POLY_ORDER, action_space=action_space)

            #start up tensorflow graph

            var_counts = tuple(core.count_vars(scope) for scope in [u'pi'])
            print(u'\nYoyoyoyyoyo Number of parameters: \t pi: %d\n' %
                  var_counts)

            self._tf_vars = [
                v for v in tf.trainable_variables() if u'pi' in v.name
            ]
            self._num_tf_vars = sum(
                [np.prod(v.shape.as_list()) for v in self._tf_vars])
            print("tf vars is of length: ", len(self._tf_vars))
            print("total trainable vars: ", len(tf.trainable_variables()))

            self._sess = tf.Session()
            self._sess.run(tf.global_variables_initializer())

            print("total trainable vars: ", len(tf.trainable_variables()))

        self._last_time = rospy.Time.now().to_sec()

        current_position = utils.get_joint_positions(self._limb).reshape(
            (7, 1))
        current_velocity = utils.get_joint_velocities(self._limb).reshape(
            (7, 1))

        self._last_x = np.vstack([current_position, current_velocity])
        self._last_xbar = self._last_x

        if self._learning_bool:
            self._last_a = self._sess.run(self._pi,
                                          feed_dict={
                                              self._x_ph:
                                              self.preprocess_state(
                                                  self._last_x).reshape(1, -1)
                                          })
        else:
            self._last_a = np.zeros((1, 56))

        #################################### Set Tensorflow from saved params
        self._READ_PARAMS = self._is_test_set
        PARAM_INDEX = 201  ## This is the index of the learned parameters that you'll use (which epoch)
        if self._learning_bool:
            if self._READ_PARAMS:
                import dill
                # Put ABSOLUTE path to location of learned_params.pkl here,
                # then remove the NotImplementedError. (This will probably be the
                # same as the PREFIX variable in data_collector.py)
                # eg. PREFIX = "/home/cc/ee106a/fa19/staff/ee106a-taf/Desktop/data"
                PREFIX = "/home/cc/ee106b/sp20/staff/ee106b-laa/Desktop/data/read_params"
                # raise NotImplementedError

                lp = dill.load(open(PREFIX + "/learned_params.pkl", "rb"))
                print("Running training set using data from epoch number: " +
                      str(PARAM_INDEX))
                param_list = []
                for param in lp[PARAM_INDEX][1]:
                    p_msg = Parameters(param)
                    param_list.append(p_msg)
                lp_msg = LearnedParameters(param_list)

                self._sess.run(
                    tf.assign(
                        tf.get_default_graph().get_tensor_by_name(
                            'pi/log_std:0'), tf.zeros((56, ))))

                self.params_callback(lp_msg)

                self._last_a = self._sess.run(
                    self._pi,
                    feed_dict={
                        self._x_ph:
                        self.preprocess_state(self._last_x).reshape(1, -1)
                    })

        ##################################### Controller params

        self._A = np.vstack([
            np.hstack([np.zeros((7, 7)), np.eye(7)]),
            np.hstack([np.zeros((7, 7)), np.zeros((7, 7))])
        ])
        self._B = np.vstack([np.zeros((7, 7)), np.eye(7)])
        Q = 0.2 * np.diag([
            1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
            1.0
        ])
        R = np.eye(7)

        def solve_lqr(A, B, Q, R):
            P = solve_continuous_are(A, B, Q, R)
            K = np.dot(np.dot(np.linalg.inv(R), B.T), P)
            return K

        self._K = solve_lqr(self._A, self._B, Q, R)

        # self._Kp = 6*np.diag(np.array([1, 1, 1.5, 1.5, 1, 1, 1]))
        # self._Kv = 5*np.diag(np.array([2, 2, 1, 1, 0.8, 0.3, 0.3]))

        # self._Kp = 9*np.diag(np.array([4, 6, 4, 8, 1, 5, 1]))
        # self._Kv = 5*np.diag(np.array([2, 3, 2, 4, 0.8, 1.5, 0.3]))

        # WORKS WELL FOR TRAINING
        self._Kp = 6 * np.diag(np.array([1, 1, 1, 1, 1, 1, 1]))
        self._Kv = 6 * np.diag(np.array([1, 1, 1, 1, 1, 1, 1]))

        # Tune down for testing except I didn't
        # self._Kp = 5*np.diag(np.array([1, 1, 1, 1, 1, 1, 1]))
        # self._Kv = 5*np.diag(np.array([1, 1, 1, 1, 1, 1, 1]))

        if not self.register_callbacks(): sys.exit(1)

    def load_parameters(self):
        if not rospy.has_param("~baxter/arm"):
            return False
        self._arm = rospy.get_param("~baxter/arm")

        if not rospy.has_param("~learning"):
            return False
        self._learning_bool = rospy.get_param("~learning")

        if not rospy.has_param("~topics/ref"):
            return False
        self._ref_topic = rospy.get_param("~topics/ref")

        if not rospy.has_param("~topics/params"):
            return False
        self._params_topic = rospy.get_param("~topics/params")

        if not rospy.has_param("~topics/transitions"):
            return False
        self._transitions_topic = rospy.get_param("~topics/transitions")

        if not rospy.has_param("~topics/linear_system_reset"):
            return False
        self._reset_topic = rospy.get_param("~topics/linear_system_reset")

        if not rospy.has_param("~topics/integration_reset"):
            return False
        self._int_reset_topic = rospy.get_param("~topics/integration_reset")

        if not rospy.has_param("~topics/data"):
            return False
        self._data_topic = rospy.get_param("~topics/data")

        if not rospy.has_param("~test_set"):
            return False
        self._is_test_set = rospy.get_param("~test_set")

        return True

    def register_callbacks(self):

        if not self._is_test_set:
            self._params_sub = rospy.Subscriber(self._params_topic,
                                                LearnedParameters,
                                                self.params_callback)

        self._ref_sub = rospy.Subscriber(self._ref_topic, Reference,
                                         self.ref_callback)

        self._reset_sub = rospy.Subscriber(self._reset_topic, Empty,
                                           self.linear_system_reset_callback)

        self._int_reset_sub = rospy.Subscriber(self._int_reset_topic, Empty,
                                               self.integration_reset_callback)

        self._transitions_pub = rospy.Publisher(self._transitions_topic,
                                                Transition)

        self._data_pub = rospy.Publisher(self._data_topic, DataLog)

        return True

    def params_callback(self, msg):

        t = rospy.Time.now().to_sec()
        sq_norm_old_params = 0.0
        sq_norm_difference = 0.0
        norm_params = []
        num_params = 0

        for p, v in zip(msg.params, self._tf_vars):
            num_params += len(p.params)
            print("P is len ", len(p.params), ", and v is len ",
                  np.prod(v.shape.as_list()))
            assert (len(p.params) == np.prod(v.shape.as_list()))

            reshaped_p = np.array(p.params).reshape(v.shape.as_list())
            norm_params.append(np.linalg.norm(reshaped_p))
            v_actual = self._sess.run(v)
            sq_norm_old_params += np.linalg.norm(v_actual)**2
            sq_norm_difference += np.linalg.norm(v_actual -
                                                 np.array(reshaped_p))**2
            self._sess.run(tf.assign(v, reshaped_p))

        rospy.loginfo("Updated tf params in controller.")
        rospy.loginfo("Parameters changed by %f on average." %
                      (sq_norm_difference / float(num_params)))
        rospy.loginfo("Parameter group norms: " + str(norm_params))
        rospy.loginfo("Params callback took %f seconds." %
                      (rospy.Time.now().to_sec() - t))

    def ref_callback(self, msg):

        # Get/log state data
        ref = msg

        dt = rospy.Time.now().to_sec() - self._last_time
        self._last_time = rospy.Time.now().to_sec()

        current_position = utils.get_joint_positions(self._limb).reshape(
            (7, 1))
        current_velocity = utils.get_joint_velocities(self._limb).reshape(
            (7, 1))

        current_state = State(current_position, current_velocity)

        # get dynamics info

        positions_dict = utils.joint_array_to_dict(current_position,
                                                   self._limb)
        velocity_dict = utils.joint_array_to_dict(current_velocity, self._limb)

        inertia = self._kin.inertia(positions_dict)
        # coriolis = self._kin.coriolis(positions_dict, velocity_dict)[0][0]
        # coriolis = np.array([float(coriolis[i]) for i in range(7)]).reshape((7,1))
        coriolis = self._kin.coriolis(positions_dict, velocity_dict).reshape(
            (7, 1))

        # gravity_wrench = np.array([0,0,0.981,0,0,0]).reshape((6,1))
        # gravity_jointspace = (np.matmul(self._kin.jacobian_transpose(positions_dict), gravity_wrench))
        # gravity = (np.matmul(inertia, gravity_jointspace)).reshape((7,1))

        gravity = 0.075 * self._kin.gravity(positions_dict).reshape((7, 1))

        # Linear Control

        error = np.array(ref.setpoint.position).reshape(
            (7, 1)) - current_position
        d_error = np.array(ref.setpoint.velocity).reshape(
            (7, 1)) - current_velocity
        # d_error = np.zeros((7,1))
        error_stack = np.vstack([error, d_error])

        v = np.matmul(self._Kv, d_error).reshape(
            (7, 1)) + np.matmul(self._Kp, error).reshape(
                (7, 1)) + np.array(ref.feed_forward).reshape((7, 1))
        # v = np.array(ref.feed_forward).reshape((7,1))
        # v = np.matmul(self._K, error_stack).reshape((7,1))
        # v = np.zeros((7,1))

        # print current_position

        ##### Nonlinear control

        x = np.vstack([current_position, current_velocity])
        xbar = np.vstack([
            np.array(ref.setpoint.position).reshape((7, 1)),
            np.array(ref.setpoint.velocity).reshape((7, 1))
        ])

        if self._learning_bool:
            a = self._sess.run(self._pi,
                               feed_dict={
                                   self._x_ph:
                                   self.preprocess_state(x).reshape(1, -1)
                               })
        else:
            a = np.zeros((1, 56))

        m2, f2 = np.split(0.1 * a[0], [49])
        m2 = m2.reshape((7, 7))
        f2 = f2.reshape((7, 1))

        K = np.hstack([self._Kp, self._Kv])

        x_predict = np.matmul(expm((self._A - np.matmul(self._B, K))*dt), self._last_x) + \
                    np.matmul(np.matmul(self._B, K), self._last_xbar)*dt

        t_msg = Transition()
        t_msg.x = list(self._last_x.flatten())
        t_msg.a = list(self._last_a.flatten())
        t_msg.r = -np.linalg.norm(x - x_predict, 2)

        if self._learning_bool and not self._is_test_set:
            self._transitions_pub.publish(t_msg)

        data = DataLog(current_state, ref.setpoint, t_msg)

        self._last_x = x
        self._last_xbar = xbar
        self._last_a = a

        self._data_pub.publish(data)

        torque_lim = np.array([4, 4, 4, 4, 2, 2, 2]).reshape((7, 1))

        torque = np.matmul(inertia + m2, v) + coriolis + gravity + f2

        torque = np.clip(torque, -torque_lim, torque_lim).reshape((7, 1))

        torque_dict = utils.joint_array_to_dict(torque, self._limb)
        self._limb.set_joint_torques(torque_dict)

    def linear_system_reset_callback(self, msg):
        # plan = self._planner.plan_to_joint_pos(np.zeros(7))
        # self._planner.execute_plan(plan)
        pass

    def integration_reset_callback(self, msg):
        self._last_time = rospy.Time.now().to_sec()

    def preprocess_state(self, x0):
        q = x0[0:7]
        dq = x0[7:14]
        x = np.hstack([np.sin(q), np.cos(q), dq])
        return x

    def shutdown(self):
        """
        Code to run on shutdown. This is good practice for safety
        """
        rospy.loginfo("Stopping Controller")

        # Set velocities to zero
        zero_vel_dict = utils.joint_array_to_dict(np.zeros(7), self._limb)
        self._limb.set_joint_velocities(zero_vel_dict)

        # self._planner.stop()

        rospy.sleep(0.1)
class ReferenceGenerator(object):
    """docstring for ReferenceGenerator"""
    def __init__(self):

        if not self.load_parameters(): sys.exit(1)

        self._planner = PathPlanner('{}_arm'.format(self._arm))

        rospy.on_shutdown(self.shutdown)

        if not self.register_callbacks(): sys.exit(1)

    def load_parameters(self):

        if not rospy.has_param("~baxter/arm"):
            return False
        self._arm = rospy.get_param("~baxter/arm")

        if not rospy.has_param("~topics/ref"):
            return False
        self._ref_topic = rospy.get_param("~topics/ref")

        if not rospy.has_param("~topics/linear_system_reset"):
            return False
        self._reset_topic = rospy.get_param("~topics/linear_system_reset")

        if not rospy.has_param("~topics/integration_reset"):
            return False
        self._int_reset_topic = rospy.get_param("~topics/integration_reset")

        if not rospy.has_param("~test_set"):
            return False
        self._is_test_set = rospy.get_param("~test_set")

        return True

    def register_callbacks(self):

        self._reset_sub = rospy.Subscriber(self._reset_topic, Empty,
                                           self.linear_system_reset_callback)

        self._ref_pub = rospy.Publisher(self._ref_topic, Reference)

        self._int_reset_pub = rospy.Publisher(self._int_reset_topic, Empty)

        return True

    def send_zeros(self):
        setpoint = State(np.zeros(7), np.zeros(7))
        feed_forward = np.zeros(7)
        msg = Reference(setpoint, feed_forward)
        while not rospy.is_shutdown():
            self._ref_pub.publish(msg)
            rospy.sleep(0.05)

    def random_span(self, rate=20, number=50):
        min_range = np.array([-0.9, -0.6, -0.9, 0.2, -1.0, 0.1, -0.8])
        max_range = np.array([0.9, 0.6, 0.9, 1.0, 1.0, 1.3, 0.8])

        r = rospy.Rate(rate)

        while not rospy.is_shutdown():
            position = (max_range - min_range) * np.random.random_sample(
                min_range.shape) + min_range
            setpoint = State(position, np.zeros(7))
            feed_forward = np.zeros(7)
            msg = Reference(setpoint, feed_forward)
            count = 0
            while not count > number and not rospy.is_shutdown():
                self._ref_pub.publish(msg)
                count = count + 1
                r.sleep()

    def dual_setpoints(self, rate=20, number=50):
        min_range = np.array([-0.9, -0.6, -0.9, 0.2, -1.0, 0.1, -0.8])
        max_range = np.array([0.9, 0.6, 0.9, 1.0, 1.0, 1.3, 0.8])

        r = rospy.Rate(rate)

        flag = True
        while not rospy.is_shutdown():
            if flag:
                position = (max_range - min_range) * 0.2 + min_range
            else:
                position = (max_range - min_range) * 0.8 + min_range
            setpoint = State(position, np.zeros(7))
            feed_forward = np.zeros(7)
            msg = Reference(setpoint, feed_forward)
            count = 0
            while not count > number and not rospy.is_shutdown():
                self._ref_pub.publish(msg)
                count = count + 1
                r.sleep()

            flag = not flag

    # Doesn't work
    def sinusoids(self, rate=20, period=2):
        r = rospy.Rate(rate)

        min_range = np.array([-0.9, -0.6, -0.9, 0.2, -1.0, 0.1, -0.8])
        max_range = np.array([0.9, 0.6, 0.9, 1.0, 1.0, 1.3, 0.8])

        middle = (min_range + max_range) / 2.0
        amp = np.array([0.6, 0.4, 0.6, 0.3, 0.7, 0.3, 0.6])

        count = 0
        max_count = period * rate
        while not rospy.is_shutdown():
            position = middle + amp * np.sin(count / max_count * 2 * np.pi)
            setpoint = State(position, np.zeros(7))
            feed_forward = np.zeros(7)
            msg = Reference(setpoint, feed_forward)
            self._ref_pub.publish(msg)
            count = count + 1
            if count >= max_count:
                count = 0
            r.sleep()

    # Doesn't work
    def test_path(self):

        position1 = np.array([-0.7, -0.5, -0.7, 0.4, -0.9, 0.3, -0.6])
        position2 = np.array([0.7, 0.5, 0.7, 0.8, 0.9, 1.1, 0.6])

        print "moving to A via moveit"
        self._planner.set_max_velocity_scaling_factor(1.0)
        while not rospy.is_shutdown():
            try:
                plan = self._planner.plan_to_joint_pos(position1)
                # raw_input("Press enter to execute plan via moveit")
                if not self._planner.execute_plan(plan):
                    raise Exception("Execution failed")
            except Exception as e:
                pass
            else:
                break
        rospy.sleep(1)

        print "moving to B via control"
        self._planner.set_max_velocity_scaling_factor(0.5)
        plan = self._planner.plan_to_joint_pos(position2)
        # raw_input("Press enter to execute plan via control")
        self._int_reset_pub.publish(Empty())
        self.execute_path(plan)
        rospy.sleep(1)

        rospy.spin()

    # Doesn't work
    def alternate(self):
        position1 = np.array([-0.3, -0.2, -0.3, 0.7, -0.6, 0.7, -0.3])
        position2 = np.array([-0.6, -0.4, -0.5, 0.6, -0.4, 1.1, -0.5])

        while not rospy.is_shutdown():
            print "moving to A via moveit"
            self._planner.set_max_velocity_scaling_factor(1.0)
            while not rospy.is_shutdown():
                try:
                    plan = self._planner.plan_to_joint_pos(position1)
                    # raw_input("Press enter to execute plan via moveit")
                    if not self._planner.execute_plan(plan):
                        raise Exception("Execution failed")
                except Exception as e:
                    pass
                else:
                    break
            rospy.sleep(1)
            # self._planner.stop()
            rospy.sleep(0.5)

            print "moving to B via control"
            self._planner.set_max_velocity_scaling_factor(0.5)
            plan = self._planner.plan_to_joint_pos(position2)
            # raw_input("Press enter to execute plan via control")
            self._int_reset_pub.publish(Empty())
            self.execute_path(plan)
            rospy.sleep(1)
            # self._planner.stop()
            rospy.sleep(0.5)

            print "moving to B via moveit"
            self._planner.set_max_velocity_scaling_factor(1.0)
            while not rospy.is_shutdown():
                try:
                    plan = self._planner.plan_to_joint_pos(position2)
                    # raw_input("Press enter to execute plan via moveit")
                    if not self._planner.execute_plan(plan):
                        raise Exception("Execution failed")
                except Exception as e:
                    pass
                else:
                    break
            rospy.sleep(1)
            # self._planner.stop()
            rospy.sleep(0.5)

            print "moving to A via control"
            self._planner.set_max_velocity_scaling_factor(0.5)
            plan = self._planner.plan_to_joint_pos(position1)
            # raw_input("Press enter to execute plan via control")
            self._int_reset_pub.publish(Empty())
            self.execute_path(plan)
            rospy.sleep(1)
            # self._planner.stop()
            rospy.sleep(0.5)

    def linear_system_reset_callback(self, msg):
        rospy.sleep(0.5)

    def interpolate_path(self, path, t, current_index=0):
        """
        interpolates over a :obj:`moveit_msgs.msg.RobotTrajectory` to produce desired
        positions, velocities, and accelerations at a specified time

        Parameters
        ----------
        path : :obj:`moveit_msgs.msg.RobotTrajectory`
        t : float
            the time from start
        current_index : int
            waypoint index from which to start search

        Returns
        -------
        target_position : 7x' or 6x' :obj:`numpy.ndarray` 
            desired positions
        target_velocity : 7x' or 6x' :obj:`numpy.ndarray` 
            desired velocities
        target_acceleration : 7x' or 6x' :obj:`numpy.ndarray` 
            desired accelerations
        current_index : int
            waypoint index at which search was terminated 
        """

        # a very small number (should be much smaller than rate)
        epsilon = 0.0001

        max_index = len(path.joint_trajectory.points) - 1

        # If the time at current index is greater than the current time,
        # start looking from the beginning
        if (path.joint_trajectory.points[current_index].time_from_start.to_sec(
        ) > t):
            current_index = 0

        # Iterate forwards so that you're using the latest time
        while (
            not rospy.is_shutdown() and \
            current_index < max_index and \
            path.joint_trajectory.points[current_index+1].time_from_start.to_sec() < t+epsilon
        ):
            current_index = current_index + 1

        # Perform the interpolation
        if current_index < max_index:
            time_low = path.joint_trajectory.points[
                current_index].time_from_start.to_sec()
            time_high = path.joint_trajectory.points[
                current_index + 1].time_from_start.to_sec()

            target_position_low = np.array(
                path.joint_trajectory.points[current_index].positions)
            target_velocity_low = np.array(
                path.joint_trajectory.points[current_index].velocities)
            target_acceleration_low = np.array(
                path.joint_trajectory.points[current_index].accelerations)

            target_position_high = np.array(
                path.joint_trajectory.points[current_index + 1].positions)
            target_velocity_high = np.array(
                path.joint_trajectory.points[current_index + 1].velocities)
            target_acceleration_high = np.array(
                path.joint_trajectory.points[current_index + 1].accelerations)

            target_position = target_position_low + \
                (t - time_low)/(time_high - time_low)*(target_position_high - target_position_low)
            target_velocity = target_velocity_low + \
                (t - time_low)/(time_high - time_low)*(target_velocity_high - target_velocity_low)
            target_acceleration = target_acceleration_low + \
                (t - time_low)/(time_high - time_low)*(target_acceleration_high - target_acceleration_low)

        # If you're at the last waypoint, no interpolation is needed
        else:
            target_position = np.array(
                path.joint_trajectory.points[current_index].positions)
            target_velocity = np.array(
                path.joint_trajectory.points[current_index].velocities)
            target_acceleration = np.array(
                path.joint_trajectory.points[current_index].velocities)

        return (target_position, target_velocity, target_acceleration,
                current_index)

    def execute_path(self, path, rate=20):
        """
        takes in a path and moves the baxter in order to follow the path.  

        Parameters
        ----------
        path : :obj:`moveit_msgs.msg.RobotTrajectory`
        rate : int
            This specifies the control frequency in hz.  It is important to
            use a rate and not a regular while loop because you want the
            loop to refresh at a constant rate, otherwise you would have to
            tune your PD parameters if the loop runs slower / faster

        Returns
        -------
        bool
            whether the controller completes the path or not
        """

        # For interpolation
        max_index = len(path.joint_trajectory.points) - 1
        current_index = 0

        # For timing
        start_t = rospy.Time.now()
        r = rospy.Rate(rate)

        while not rospy.is_shutdown():
            # Find the time from start
            t = (rospy.Time.now() - start_t).to_sec()

            # Get the desired position, velocity, and acceleration
            (target_position, target_velocity, target_acceleration,
             current_index) = self.interpolate_path(path, t, current_index)

            # Run controller
            setpoint = State(target_position, target_velocity)
            feed_forward = target_acceleration
            msg = Reference(setpoint, feed_forward)
            self._ref_pub.publish(msg)

            # Sleep for a bit (to let robot move)
            r.sleep()

            if current_index >= max_index:
                break

        return True

    def shutdown(self):
        pass
Exemple #3
0
def main():
    """
    Examples of how to run me:
    python scripts/main.py --help <------This prints out all the help messages
    and describes what each parameter is
    python scripts/main.py -t 1 -ar 1 -c workspace -a left --log
    python scripts/main.py -t 2 -ar 2 -c velocity -a left --log
    python scripts/main.py -t 3 -ar 3 -c torque -a right --log
    python scripts/main.py -t 1 -ar 4 5 --path_only --log

    NOTE: If running with the --moveit flag, it makes no sense
    to also choose your controller to be workspace, since moveit
    cannot accept workspace trajectories. This script simply ignores
    the controller selection if you specify both --moveit and
    --controller_name workspace, so if you want to run with moveit
    simply leave --controller_name as default.

    You can also change the rate, timeout if you want
    """
    parser = argparse.ArgumentParser()
    parser.add_argument('-task',
                        '-t',
                        type=str,
                        default='line',
                        help='Options: line, circle, square.  Default: line')
    parser.add_argument('-ar_marker',
                        '-ar',
                        nargs='+',
                        help='Which AR marker to use.  Default: 1')
    parser.add_argument(
        '-controller_name',
        '-c',
        type=str,
        default='jointspace',
        help='Options: workspace, jointspace, or torque.  Default: jointspace')
    parser.add_argument('-arm',
                        '-a',
                        type=str,
                        default='left',
                        help='Options: left, right.  Default: left')
    parser.add_argument('-rate',
                        type=int,
                        default=200,
                        help="""
        This specifies how many ms between loops.  It is important to use a rate
        and not a regular while loop because you want the loop to refresh at a
        constant rate, otherwise you would have to tune your PD parameters if 
        the loop runs slower / faster.  Default: 200""")
    parser.add_argument(
        '-timeout',
        type=int,
        default=None,
        help=
        """after how many seconds should the controller terminate if it hasn\'t already.  
        Default: None""")
    parser.add_argument(
        '-num_way',
        type=int,
        default=300,
        help=
        'How many waypoints for the :obj:`moveit_msgs.msg.RobotTrajectory`.  Default: 300'
    )
    parser.add_argument(
        '--moveit',
        action='store_true',
        help=
        """If you set this flag, moveit will take the path you plan and execute it on 
        the real robot""")
    parser.add_argument('--log',
                        action='store_true',
                        help='plots controller performance')
    args = parser.parse_args()

    rospy.init_node('moveit_node')
    # this is used for sending commands (velocity, torque, etc) to the robot
    limb = baxter_interface.Limb(args.arm)
    # this is used to get the dynamics (inertia matrix, manipulator jacobian, etc) from the robot
    # in the current position, UNLESS you specify other joint angles.  see the source code
    # https://github.com/valmik/baxter_pykdl/blob/master/src/baxter_pykdl/baxter_pykdl.py
    # for info on how to use each method
    kin = baxter_kinematics(args.arm)

    # ADD COMMENT EHRE
    tag_pos = [lookup_tag(marker) for marker in args.ar_marker]
    # Get an appropriate RobotTrajectory for the task (circular, linear, or square)
    # If the controller is a workspace controller, this should return a trajectory where the
    # positions and velocities are workspace positions and velocities.  If the controller
    # is a jointspace or torque controller, it should return a trajectory where the positions
    # and velocities are the positions and velocities of each joint.
    robot_trajectory = get_trajectory(args.task, limb, kin, tag_pos,
                                      args.num_way, args.controller_name)

    # This is a wrapper around MoveIt! for you to use.  We use MoveIt! to go to the start position
    # of the trajectory
    planner = PathPlanner('{}_arm'.format(args.arm))
    if args.controller_name == "workspace":
        pose = create_pose_stamped_from_pos_quat(
            robot_trajectory.joint_trajectory.points[0].positions,
            [0, 1, 0, 0], 'base')
        plan = planner.plan_to_pose(pose)
    else:
        plan = planner.plan_to_joint_pos(
            robot_trajectory.joint_trajectory.points[0].positions)
    planner.execute_plan(plan)

    if args.moveit:
        # LAB 1 PART A
        # by publishing the trajectory to the move_group/display_planned_path topic, you should
        # be able to view it in RViz.  You will have to click the "loop animation" setting in
        # the planned path section of MoveIt! in the menu on the left side of the screen.
        pub = rospy.Publisher('move_group/display_planned_path',
                              DisplayTrajectory,
                              queue_size=10)
        disp_traj = DisplayTrajectory()
        disp_traj.trajectory.append(robot_trajectory)
        # disp_traj.trajectory_start = planner._group.get_current_joint_values()
        disp_traj.trajectory_start = RobotState()
        pub.publish(disp_traj)

        try:
            raw_input('Press <Enter> to execute the trajectory using MOVEIT')
        except KeyboardInterrupt:
            sys.exit()
        # uses MoveIt! to execute the trajectory.  make sure to view it in RViz before running this.
        # the lines above will display the trajectory in RViz
        planner.execute_plan(robot_trajectory)
    else:
        # LAB 1 PART B
        controller = get_controller(args.controller_name, limb, kin)
        try:
            raw_input(
                'Press <Enter> to execute the trajectory using YOUR OWN controller'
            )
        except KeyboardInterrupt:
            sys.exit()
        # execute the path using your own controller.
        done = controller.execute_path(robot_trajectory,
                                       rate=args.rate,
                                       timeout=args.timeout,
                                       log=args.log)
        if not done:
            print 'Failed to move to position'
            sys.exit(0)
Exemple #4
0
    # is a jointspace or torque controller, it should return a trajectory where the positions
    # and velocities are the positions and velocities of each joint.
    robot_trajectory = get_trajectory(args.task, current_pos, tag_pos,
                                      args.num_way, args.controller_name, limb,
                                      kin, args.rate)

    # This is a wrapper around MoveIt! for you to use.  We use MoveIt! to go to the start position
    # of the trajectory
    planner = PathPlanner('{}_arm'.format(args.arm))
    if args.controller_name == "workspace":
        pose = create_pose_stamped_from_pos_quat(
            robot_trajectory.joint_trajectory.points[0].positions,
            [0, 1, 0, 0], 'base')
        plan = planner.plan_to_pose(pose)
    else:
        plan = planner.plan_to_joint_pos(
            robot_trajectory.joint_trajectory.points[0].positions)
    planner.execute_plan(plan)

    if args.moveit:
        # LAB 1 PART A
        # by publishing the trajectory to the move_group/display_planned_path topic, you should
        # be able to view it in RViz.  You will have to click the "loop animation" setting in
        # the planned path section of MoveIt! in the menu on the left side of the screen.
        pub = rospy.Publisher('move_group/display_planned_path',
                              DisplayTrajectory,
                              queue_size=10)
        disp_traj = DisplayTrajectory()
        disp_traj.trajectory.append(robot_trajectory)
        # disp_traj.trajectory_start = planner._group.get_current_joint_values()
        disp_traj.trajectory_start = RobotState()
        pub.publish(disp_traj)
Exemple #5
0
        -0.7995570902191504, -1.0230128644807106, 0, 1.9412961426428978, 0,
        0.6088981529125705, 0
    ]
    qr = [
        0.7995570902191504, -1.0230128644807106, 0, 1.9412961426428978, 0,
        0.6088981529125705, 0
    ]

elif sys.argv[1] == 'high_stretch':
    ql = [
        -0.7995570902191504, -0.3583801252107035, 0, 0.8317392022589729, 0,
        1.072678159715874, 0
    ]
    qr = [
        0.7995570902191504, -0.3583801252107035, 0, 0.8317392022589729, 0,
        1.072678159715874, 0
    ]
else:
    print(
        "Please run this script with either 'low_stretch' or 'high_stretch' specified as a command line argument."
    )
    sys.exit()

planner = PathPlanner('left_arm')
success, plan, time_taken, error_code = planner.plan_to_joint_pos(ql)
planner.execute_plan(plan)

planner = PathPlanner('right_arm')
success, plan, time_taken, error_code = planner.plan_to_joint_pos(qr)
planner.execute_plan(plan)
Exemple #6
0
def main():
    """
    python scripts/main.py --help <------This prints out all the help messages
    and describes what each parameter is.

    NOTE: If running with the --moveit flag, it makes no sense
    to also choose your controller to be workspace, since moveit
    cannot accept workspace trajectories. This script simply ignores
    the controller selection if you specify both --moveit and
    --controller_name workspace, so if you want to run with moveit
    simply leave --controller_name as default.

    You can also change the rate, timeout if you want
    """
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-task',
        '-t',
        type=str,
        default='line',
        help='Options: line, circle, arbitrary.  Default: line')
    parser.add_argument(
        '-goal_point',
        '-g',
        type=float,
        default=[0, 0, 0],
        nargs=3,
        help=
        'Specify a goal point for line and circle trajectories. Ex: -g 0 0 0')
    parser.add_argument(
        '-controller_name',
        '-c',
        type=str,
        default='jointspace',
        help='Options: workspace, jointspace, or torque.  Default: jointspace')
    parser.add_argument('-arm',
                        '-a',
                        type=str,
                        default='left',
                        help='Options: left, right.  Default: left')
    parser.add_argument('-rate',
                        type=int,
                        default=200,
                        help="""
        (Hz) This specifies how many loop iterations should occur per second.  
        It is important to use a rate
        and not a regular while loop because you want the loop to refresh at a
        constant rate, otherwise you would have to tune your PD parameters if 
        the loop runs slower / faster.  Default: 200""")
    parser.add_argument(
        '-timeout',
        type=int,
        default=None,
        help=
        """after how many seconds should the controller terminate if it hasn\'t already.  
        Default: None""")
    parser.add_argument(
        '-num_way',
        type=int,
        default=300,
        help=
        'How many waypoints for the :obj:`moveit_msgs.msg.RobotTrajectory`.  Default: 300'
    )
    parser.add_argument(
        '--moveit',
        action='store_true',
        help=
        """If you set this flag, moveit will take the path you plan and execute it on 
        the real robot""")
    parser.add_argument('--log',
                        action='store_true',
                        help='plots controller performance')
    args = parser.parse_args()

    if args.moveit:
        # We can't give moveit a workspace trajectory, so we make it
        # impossible.
        args.controller_name = 'jointspace'

    rospy.init_node('moveit_node')

    # this is used for sending commands (velocity, torque, etc) to the robot
    limb = baxter_interface.Limb(args.arm)

    # Choose an inverse kinematics solver. If you leave ik_solver as None, then the default
    # KDL solver will be used. Otherwise, you can uncomment the next line which sets ik_solver.
    # Then, the TRAC-IK inverse kinematics solver will be used. If you have trouble with inconsistency
    # or poor solutions with one method, feel free to try the other one.
    ik_solver = None
    # ik_solver = IK("base", args.arm + "_gripper")

    # A KDL instance for Baxter. This can be used for forward and inverse kinematics,
    # computing jacobians etc.
    kin = baxter_kinematics(args.arm)

    # This is a wrapper around MoveIt! for you to use.
    planner = PathPlanner('{}_arm'.format(args.arm))

    # Get an appropriate RobotTrajectory for the task (circular, linear, or arbitrary MoveIt)
    # If the controller is a workspace controller, this should return a trajectory where the
    # positions and velocities are workspace configurations and velocities.  If the controller
    # is a jointspace or torque controller, it should return a trajectory where the positions
    # and velocities are the positions and velocities of each joint.
    robot_trajectory = get_trajectory(limb, kin, ik_solver, planner, args)

    if args.controller_name == "workspace":
        config = robot_trajectory.joint_trajectory.points[0].positions
        pose = create_pose_stamped_from_pos_quat(
            [config[0], config[1], config[2]],  # XYZ location
            [config[3], config[4], config[5], config[6]
             ],  # XYZW quaterion orientation
            'base')
        success, plan, time_taken, error_code = planner.plan_to_pose(pose)
        planner.execute_plan(plan)
    else:
        start = robot_trajectory.joint_trajectory.points[0].positions
        while not rospy.is_shutdown():
            try:
                # ONLY FOR EMERGENCIES!!! DON'T UNCOMMENT THE NEXT LINE UNLESS YOU KNOW WHAT YOU'RE DOING!!!
                # limb.move_to_joint_positions(joint_array_to_dict(start, limb), timeout=7.0, threshold=0.0001)
                success, plan, time_taken, error_code = planner.plan_to_joint_pos(
                    start)
                planner.execute_plan(plan)
                break
            except moveit_commander.exception.MoveItCommanderException as e:
                print(e)
                print("Failed planning, retrying...")

    if args.moveit:
        # PROJECT 1 PART A
        # by publishing the trajectory to the move_group/display_planned_path topic, you should
        # be able to view it in RViz.  You will have to click the "loop animation" setting in
        # the planned path section of MoveIt! in the menu on the left side of the screen.
        pub = rospy.Publisher('move_group/display_planned_path',
                              DisplayTrajectory,
                              queue_size=10)
        disp_traj = DisplayTrajectory()
        disp_traj.trajectory.append(robot_trajectory)
        disp_traj.trajectory_start = RobotState()
        pub.publish(disp_traj)

        try:
            input('Press <Enter> to execute the trajectory using MOVEIT')
        except KeyboardInterrupt:
            sys.exit()
        # uses MoveIt! to execute the trajectory.  make sure to view it in RViz before running this.
        # the lines above will display the trajectory in RViz
        if args.log:
            node = roslaunch.core.Node("proj1_pkg",
                                       "moveit_plot.py",
                                       args="{} {}".format(
                                           args.arm, args.rate))
            launch = roslaunch.scriptapi.ROSLaunch()
            launch.start()
            process = launch.launch(node)
            rospy.wait_for_service('start_logging')
            start_service = rospy.ServiceProxy('start_logging', TriggerLogging)
            request = TriggerLoggingRequest(path=robot_trajectory)
            start_service(robot_trajectory)

        planner.execute_plan(robot_trajectory)

        if args.log:
            r = rospy.Rate(1)
            while process.is_alive():
                r.sleep()

    else:
        # PROJECT 1 PART B
        controller = get_controller(args.controller_name, limb, kin)
        try:
            input(
                'Press <Enter> to execute the trajectory using YOUR OWN controller'
            )
        except KeyboardInterrupt:
            sys.exit()
        # execute the path using your own controller.
        done = controller.execute_path(robot_trajectory,
                                       rate=args.rate,
                                       timeout=args.timeout,
                                       log=args.log)
        if not done:
            print('Failed to move to position')
            sys.exit(0)