def runTest(self): x = [1, 0, 0] y = [0, 1, 0] z = [0, 0, 1] #subproblem0 assert (rox.subproblem0(x, y, z) == np.pi / 2) #subproblem1 k1 = (np.add(x, z)) / np.linalg.norm(np.add(x, z)) k2 = (np.add(y, z)) / np.linalg.norm(np.add(y, z)) assert (rox.subproblem1(k1, k2, z) == np.pi / 2) #subproblem2 p2 = x q2 = np.add(x, np.add(y, z)) q2 = q2 / np.linalg.norm(q2) a2 = rox.subproblem2(p2, q2, z, y) assert len(a2) == 2 r1 = rox.rot(z, a2[0][0]).dot(rox.rot(y, a2[0][1]))[:, 0] r2 = rox.rot(z, a2[1][0]).dot(rox.rot(y, a2[1][1]))[:, 0] np.testing.assert_allclose(r1, q2, atol=1e-4) np.testing.assert_allclose(r2, q2, atol=1e-4) a3 = rox.subproblem2(x, z, z, y) assert len(a3) == 1 r3 = rox.rot(z, a3[0][0]).dot(rox.rot(y, a3[0][1]))[:, 0] np.testing.assert_allclose(r3, z, atol=1e-4) #subproblem3 p4 = [.5, 0, 0] q4 = [0, .75, 0] a4 = rox.subproblem3(p4, q4, z, .5) a5 = rox.subproblem3(p4, q4, z, 1.25) assert len(a4) == 2 np.testing.assert_allclose( np.linalg.norm(np.add(q4, rox.rot(z, a4[0]).dot(p4))), 0.5) np.testing.assert_allclose( np.linalg.norm(np.add(q4, rox.rot(z, a4[1]).dot(p4))), 0.5) assert len(a5) == 1 np.testing.assert_allclose( np.linalg.norm(np.add(q4, rox.rot(z, a5[0]).dot(p4))), 1.25) #subproblem4 p6 = y q6 = [.8, .2, .5] d6 = .3 a6 = rox.subproblem4(p6, q6, z, d6) np.testing.assert_allclose(np.dot(p6, rox.rot(z, a6[0]).dot(q6)), d6, atol=1e-4) np.testing.assert_allclose(np.dot(p6, rox.rot(z, a6[1]).dot(q6)), d6, atol=1e-4)
def _compute_joint_command(self, controller_state=None): if controller_state is None: controller_state = self._state controller_state.controller_time = self._clock.now step_ts = controller_state.ts * controller_state.speed_scalar if controller_state.mode.value < 0: if controller_state.mode == ControllerMode.ROBOT_INVALID_STATE \ or controller_state.mode == ControllerMode.ROBOT_COMMUNICATION_ERROR \ or controller_state.mode == ControllerMode.ROBOT_FAULT: controller_state.joint_setpoint = None controller_state.joint_command = None controller_state.ft_wrench = None while True: self._update_active_trajectory(controller_state) if controller_state.active_trajectory is not None: controller_state.active_trajectory.abort( controller_state.mode) controller_state.active_trajectory = None else: break return controller_state.mode else: self._update_active_trajectory(controller_state) if controller_state.joint_setpoint is None: controller_state.joint_setpoint = controller_state.joint_position if controller_state.ft_wrench_threshold is not None \ and np.shape(controller_state.ft_wrench_threshold) == (6,) \ and controller_state.ft_wrench is None: controller_state.mode = ControllerMode.SENSOR_FAULT return ControllerMode.SENSOR_FAULT if controller_state.joystick_command is not None \ and controller_state.joystick_command.halt_command: controller_state.mode = ControllerMode.HALT if controller_state.mode.value > 0 and not self._check_ft_threshold( controller_state.ft_wrench, controller_state.ft_wrench_bias): if controller_state.active_trajectory is not None: controller_state.active_trajectory.abort(ControllerMode.FT_THRESHOLD_VIOLATION, \ "Force/Torque Threshold Violated") controller_state.active_trajectory = None controller_state.mode = ControllerMode.FT_THRESHOLD_VIOLATION return ControllerMode.FT_THRESHOLD_VIOLATION try: if controller_state.mode == ControllerMode.HALT: pass elif controller_state.mode.value < ControllerMode.HALT.value: if controller_state.active_trajectory is not None: controller_state.active_trajectory.abort( controller_state.mode) controller_state.active_trajectory = None elif controller_state.mode == ControllerMode.JOINT_TELEOP: if controller_state.joystick_command is not None \ and controller_state.joystick_command.joint_velocity_command is not None: #controller_state.joint_setpoint += \ #controller_state.joystick_command.joint_velocity_command.dot(step_ts) #################################################################### J = rox.robotjacobian(self._robot, controller_state.joint_position) cmd_vel = np.dot( J, controller_state.joystick_command. joint_velocity_command) controller_state.joint_setpoint += self._quadprog.compute_quadprog( controller_state.joint_position).dot(step_ts * 5) #################################################################### #self._clip_joint_angles(controller_state) elif controller_state.mode == ControllerMode.CARTESIAN_TELEOP: if controller_state.joystick_command is not None \ and controller_state.joystick_command.spatial_velocity_command is not None: #self._compute_joint_vel_from_spatial_vel(controller_state, step_ts, controller_state.joystick_command.spatial_velocity_command) #################################################### ########## change step_ts*5 ################# controller_state.joint_setpoint += self._quadprog.compute_quadprog( controller_state.joint_position).dot(step_ts * 2) #self._clip_joint_angles(controller_state) #################################################### elif controller_state.mode == ControllerMode.CYLINDRICAL_TELEOP: if controller_state.joystick_command is not None \ and controller_state.joystick_command.spatial_velocity_command is not None: if (not all(self._robot.H[:, 0] == (0, 0, 1)) or self._robot.joint_type[0] != 0): controller_state.mode = ControllerMode.INVALID_OPERATION else: cmd_vel = controller_state.joystick_command.spatial_velocity_command transform_0T = rox.fwdkin( self._robot, controller_state.joint_position) d = np.linalg.norm( (transform_0T.p[0], transform_0T.p[1])) d = np.max((d, 0.05)) theta = np.arctan2(transform_0T.p[1], transform_0T.p[0]) s_0 = transform_0T.p[1] / d c_0 = transform_0T.p[0] / d v_x = -d * s_0 * cmd_vel[3] + c_0 * cmd_vel[4] v_y = d * c_0 * cmd_vel[3] + s_0 * cmd_vel[4] v_z = cmd_vel[5] w_x = cmd_vel[0] w_y = cmd_vel[1] w_z = cmd_vel[2] + cmd_vel[3] cmd_vel2 = np.array([w_x, w_y, w_z, v_x, v_y, v_z]) #self._compute_joint_vel_from_spatial_vel(controller_state, step_ts, cmd_vel2) ########## change step_ts*5 ################# controller_state.joint_setpoint += self._quadprog.compute_quadprog( controller_state.joint_position).dot(step_ts * 5) #################################################### elif controller_state.mode == ControllerMode.SPHERICAL_TELEOP: if controller_state.joystick_command is not None \ and controller_state.joystick_command.spatial_velocity_command is not None: if (not all(self._robot.H[:, 0] == (0, 0, 1)) or self._robot.joint_type[0] != 0): controller_state.mode = ControllerMode.INVALID_OPERATION else: #TODO: more clever solution that doesn't require trigonometry? cmd_vel = controller_state.joystick_command.spatial_velocity_command transform_0T = rox.fwdkin( self._robot, controller_state.joint_position) d = np.linalg.norm(transform_0T.p) d = np.max((d, 0.05)) theta_phi_res = rox.subproblem2( np.dot([1, 0, 0], d), transform_0T.p, [0, 0, 1], [0, 1, 0]) if (len(theta_phi_res) == 0): controller_state.mode = ControllerMode.ROBOT_SINGULARITY else: theta_dot = cmd_vel[3] phi_dot = cmd_vel[4] d_dot = cmd_vel[5] if (len(theta_phi_res) == 1): theta, phi = theta_phi_res[0] elif (np.abs(theta_phi_res[0][1]) < np.deg2rad(90)): theta, phi = theta_phi_res[0] else: theta, phi = theta_phi_res[1] s_theta = np.sin(theta) c_theta = np.cos(theta) s_phi = np.sin(phi) c_phi = np.cos(phi) v_x = -d * s_phi * c_theta * phi_dot - d * s_theta * c_theta * theta_dot + c_phi * c_theta * d_dot v_y = -d * s_phi * s_theta * phi_dot + d * c_phi * c_theta * theta_dot + s_theta * c_phi * d_dot v_z = -d * c_phi * phi_dot - s_phi * d_dot w_x = cmd_vel[0] - phi_dot * s_theta w_y = cmd_vel[1] + phi_dot * c_theta w_z = cmd_vel[2] + theta_dot cmd_vel2 = np.array([w_x, w_y, w_z, v_x, v_y, v_z]) #self._compute_joint_vel_from_spatial_vel(controller_state, step_ts, cmd_vel2) ########## change step_ts*5 ################### controller_state.joint_setpoint += self._quadprog.compute_quadprog( controller_state.joint_position).dot(step_ts * 5) ############################################### elif controller_state.mode == ControllerMode.SHARED_TRAJECTORY: if controller_state.joystick_command is not None \ and controller_state.joystick_command.trajectory_velocity_command is not None: active_trajectory = controller_state.active_trajectory if active_trajectory is not None and active_trajectory.trajectory_valid: res, setpoint = active_trajectory.increment_trajectory_time( step_ts * controller_state.joystick_command. trajectory_velocity_command, controller_state) if res == ControllerMode.SUCCESS: controller_state.joint_setpoint = setpoint elif controller_state.mode == ControllerMode.AUTO_TRAJECTORY: active_trajectory = controller_state.active_trajectory if active_trajectory is not None and active_trajectory.trajectory_valid: res, setpoint = active_trajectory.increment_trajectory_time( step_ts, controller_state) if res == ControllerMode.SUCCESS: controller_state.joint_setpoint = setpoint elif controller_state.mode.value >= ControllerMode.EXTERNAL_SETPOINT_0.value \ and controller_state.mode.value <= ControllerMode.EXTERNAL_SETPOINT_7.value: i = controller_state.mode.value - ControllerMode.EXTERNAL_SETPOINT_0.value setpoint = controller_state.external_joint_setpoints[i] if setpoint is not None: controller_state.joint_setpoint = np.copy(setpoint) self._clip_joint_angles(controller_state) else: self._compute_setpoint_custom_mode(controller_state) except: traceback.print_exc() controller_state.mode = ControllerMode.INTERNAL_ERROR controller_state.joint_command = controller_state.joint_position #TODO: add in joint command filter controller_state.joint_command = controller_state.joint_setpoint return controller_state.mode
def robot6_sphericalwrist_invkin(robot, desired_pose, last_joints=None): """ Inverse kinematics for six axis articulated industrial robots with sherical wrists. Examples include Puma 260, ABB IRB6640, Staubli TX40, etc. Note that this is not for Universal Robot wrist configurations. :type robot: general_robotics_toolbox.Robot :param robot: The robot object representing the geometry of the robot :type desired_pose: general_robotics_toolbox.Transform :param desired_pose: The desired pose of the robot :type last_joints: list, tuple, or numpy.array :param last_joints: The joints of the robot at the last timestep. The returned first returned joint configuration will be the closests to last_joints. Optional :rtype: list of numpy.array :return: A list of zero or more joint angles that match the desired pose. An empty list means that the desired pose cannot be reached. If last_joints is specified, the first entry is the closest configuration to last_joints. """ R06 = desired_pose.R p0T = desired_pose.p if robot.R_tool is not None and robot.p_tool is not None: R06 = R06.dot(np.transpose(robot.R_tool)) p0T = p0T - R06.dot(robot.p_tool) H = robot.H P = robot.P theta_v = [] #Correct for spherical joint position vectors if not np.all(P[:, 4] == 0): P4_d = P[:, 4].dot(H[:, 3]) assert np.all(P[:, 4] - P4_d * H[:, 3] == 0) P[:, 3] += P[:, 4] P[:, 4] = np.zeros(3) if not np.all(P[:, 5] == 0): P5_d = P[:, 5].dot(H[:, 5]) # assert np.all(P[:,5] - P5_d*H[:,5] == 0) P[:, 6] += P[:, 5] P[:, 5] = np.zeros(3) d1 = np.dot(ey, P[:, 1] + P[:, 2] + P[:, 3]) v1 = p0T - R06.dot(P[:, 6]) p1 = ey Q1 = rox.subproblem4(p1, v1, -H[:, 0], d1) normalize = normalize_joints(robot, last_joints) for q1 in normalize(0, Q1): R01 = rox.rot(H[:, 0], q1) p26_q1 = R01.T.dot(p0T - R06.dot(P[:, 6])) - (P[:, 0] + P[:, 1]) d3 = np.linalg.norm(p26_q1) v3 = P[:, 2] p3 = P[:, 3] Q3 = rox.subproblem3(p3, v3, H[:, 2], d3) for q3 in normalize(2, Q3): R23 = rox.rot(H[:, 2], q3) v2 = p26_q1 p2 = P[:, 2] + R23.dot(P[:, 3]) q2 = rox.subproblem1(p2, v2, H[:, 1]) q2 = normalize(1, [q2]) if len(q2) == 0: continue q2 = q2[0] R12 = rox.rot(H[:, 1], q2) R03 = R01.dot(R12).dot(R23) R36 = R03.T.dot(R06) v4 = R36.dot(H[:, 5]) p4 = H[:, 5] Q4_Q5 = rox.subproblem2(p4, v4, H[:, 3], H[:, 4]) for q4, q5 in normalize((3, 4), Q4_Q5): R35 = rox.rot(H[:, 3], q4).dot(rox.rot(H[:, 4], q5)) R05 = R03.dot(R35) R56 = R05.T.dot(R06) p6 = H[:, 4] v6 = R56.dot(H[:, 4]) q6 = rox.subproblem1(p6, v6, H[:, 5]) q6 = normalize(5, [q6]) if len(q6) == 0: continue q6 = q6[0] theta_v.append(np.array([q1, q2, q3, q4, q5, q6])) if last_joints is not None: theta_dist = np.linalg.norm(np.subtract(theta_v, last_joints), axis=1) return [theta_v[i] for i in list(np.argsort(theta_dist))] else: return theta_v