예제 #1
0
  def update_stance(self, translation_vel, rotate_vel, dt):
    """
    TODO: Document
    """

    # stance_vel_xyz = translation_vel + rotate_vel.cross(cmd_stance_xyz)
    self._stance_vel_xyz[:] = translation_vel + np.cross(rotate_vel, self._cmd_stance_xyz)

    # FIXME: Cut down on allocations here
    self._cmd_stance_xyz += translation_vel * dt
    self._cmd_stance_xyz[:] = rotate_z(rotate_vel[2] * dt) @ rotate_y(rotate_vel[1] * dt) @ rotate_x(rotate_vel[0] * dt) @ self._cmd_stance_xyz

    self._kinematics.get_end_effector(self._feedback_view.position, self._ee_frame)
    np.copyto(self._fbk_stance_xyz, self._ee_frame[0:3, 3])

    # Update home stance to match the current z height
    self._level_home_stance_xyz[2] += translation_vel[2] * dt
    self._home_stance_xyz[:] = rotate_x(0.2 * translation_vel[1]) @ rotate_y(-0.2 * translation_vel[0]) @ self._level_home_stance_xyz
예제 #2
0
    def _calculate_lean_angle(self):
        """
    The CoM of all individual bodies and pose estimate have been updated at this point
    """
        rpy_modules = self._rpy
        imu_modules = self._imu_modules

        # {roll,pitch}_angle are in radians here
        roll_angle = np.nanmean(rpy_modules[0, imu_modules])
        pitch_angle = np.nanmean(rpy_modules[1, imu_modules])

        # Update roll transform (rotation matrix)
        math_utils.rotate_x(roll_angle, output=self._roll_rot)
        # Update pitch transform (rotation matrix)
        math_utils.rotate_y(pitch_angle, output=self._pitch_rot)

        self._roll_angle = degrees(roll_angle)
        self._pitch_angle = degrees(pitch_angle)

        # Rotate by the pitch angle about the Y axis, followed by
        # rotating by the roll angle about the X axis
        np.matmul(self._pitch_rot, self._roll_rot, out=self._T_pose_rot)

        # rad/s
        self._feedback_lean_angle_velocity = self._pose_gyros_mean[1]

        # Find the mean of the two legs' translation vectors at the endeffector
        # and store it in `self._ground_point`
        np.add(self._left_leg.current_tip_fk[0:3, 3],
               self._right_leg.current_tip_fk[0:3, 3],
               out=self._ground_point)
        self._ground_point *= 0.5

        # Get the vector starting from the "ground point" and ending at the
        # position of the current center of mass, then rotate it according to
        # the current pitch angle of Igor, storing the result in `self._line_com`
        np.subtract(self._com, self._ground_point, out=self._line_com)
        np.dot(self._pitch_rot, self._line_com, out=self._line_com)

        # Get the magnitude of the "line CoM" and store it for later use.
        # This is used to scale parameters in the balance controller.
        self._height_com = np.linalg.norm(self._line_com)

        # Using the line center of mass, find the feedback lean angle
        self._feedback_lean_angle = degrees(
            atan2(self._line_com[0, 0], self._line_com[2, 0]))

        # Update Igor's center of mass by applying the transforms in the following order:
        #  1) pitch rotation
        #  2) roll rotation
        np.dot(self._T_pose_rot, self._com, out=self._com)

        # Copy the pose rotation matrix back into the pose transformation matrix
        self._pose_transform[0:3, 0:3] = self._T_pose_rot

        # Update CoM of legs based on current pose estimate from calculated lean angle
        l_leg_coms = self._left_leg.current_coms
        r_leg_coms = self._right_leg.current_coms
        # Both legs have the same amount of kinematic bodies, so
        # do calculations for both legs in same loop
        for i in range(len(l_leg_coms)):
            leg_com = l_leg_coms[i]
            np.matmul(self._pose_transform, leg_com, out=leg_com)
            leg_com = r_leg_coms[i]
            np.matmul(self._pose_transform, leg_com, out=leg_com)
    )
    print('matches what is given in the source file.')
    exit(1)

try:
    model = hebi.robot_model.import_from_hrdf("hrdf/A-2085-06.hrdf")
except Exception as e:
    print('Could not load HRDF: {0}'.format(e))
    exit(1)

# Go to the XYZ positions at four corners of the box, and create a rotation matrix
# that has the end effector point straight forward.
xyz_targets = np.array([[0.20, 0.40, 0.40, 0.20], [0.30, 0.30, -0.30, -0.30],
                        [0.10, 0.10, 0.10, 0.10]])
xyz_cols = xyz_targets.shape[1]
rotation_target = math_utils.rotate_y(pi / 2)

# Convert these to joint angle waypoints using IK solutions for each of the xyz locations
# as well as the desired orientation of the end effector. Copy the initial waypoint at the end so we close the square.

# Choose an "elbow up" initial configuration for IK
elbow_up_angles = [0, pi / 4.0, pi / 2.0, pi / 4.0, -pi, pi / 2.0]

joint_targets = np.empty((group.size, xyz_cols + 1))
for col in range(xyz_cols):
    so3_objective = hebi.robot_model.endeffector_so3_objective(rotation_target)
    ee_position_objective = hebi.robot_model.endeffector_position_objective(
        xyz_targets[:, col])
    ik_res_angles = model.solve_inverse_kinematics(elbow_up_angles,
                                                   so3_objective,
                                                   ee_position_objective)
예제 #4
0
print('Arm end-effector is now following the mobile device pose.')
print('The control interface has the following commands:')
print('  B1 - Reset/re-align poses.')
print('       This takes the arm to home and aligns with mobile device.')
print('  A3 - Scale down the translation commands to the arm.')
print('       Sliding all the way down means the end-effector only rotates.')
print('  A6 - Control the gripper (if the arm has gripper).')
print('       Sliding down closes the gripper, sliding up opens.')
print('  B8 - Quits the demo.')

cmd = hebi.GroupCommand(group.size)

# Move to current coordinates
xyz_target_init = np.asarray([0.5, 0.0, 0.1])
rot_mat_target_init = rotate_y(np.pi)


def get_ik(xyz_target, rot_target, ik_seed):
    # Helper function to rebuild the IK solver with the appropriate objective functions
    return kin.solve_inverse_kinematics(
        ik_seed_pos, endeffector_position_objective(xyz_target),
        endeffector_so3_objective(rot_target))


# Startup
while not abort_flag:
    group.get_next_feedback(reuse_fbk=fbk)

    cmd.position = None
    cmd.velocity = None