Source code for robots.pr2.tuck_arms_ros

#!/usr/bin/env python
#
# Test PR2 arm tucking in MORSE.
#
# Based on pr2_tuck_arms:
#
# Copyright (c) 2009, Willow Garage, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following
#    disclaimer in the documentation and/or other materials provided
#    with the distribution.
#  * Neither the name of the Willow Garage nor the names of its
#    contributors may be used to endorse or promote products derived
#    from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# Author: Wim Meeussen
# Modified by Jonathan Bohren to be an action and for untucking


from morse.testing.ros import RosTestCase

import sys
import time
import math

import rospy

from control_msgs.msg import *

from trajectory_msgs.msg import *
import actionlib

# Joint names
joint_names = ["shoulder_pan", 
               "shoulder_lift",
               "upper_arm_roll",
               "elbow_flex", 
               "forearm_roll",
               "wrist_flex", 
               "wrist_roll" ]


l_arm_tucked = [0.06024, 1.248526, 1.789070, -1.683386, -1.7343417, -0.0962141, -0.0864407]
r_arm_tucked = [-0.023593, 1.1072800, -1.5566882, -2.124408, -1.4175, -1.8417, 0.21436]
l_arm_untucked = [ 0.4,  1.0,   0.0,  -2.05,  0.0,  -0.1,  0.0]
r_arm_untucked = [-0.4,  1.0,   0.0,  -2.05,  0.0,  -0.1,  0.0]
r_arm_approach = [0.039, 1.1072, 0.0, -2.067, -1.231, -1.998, 0.369]
r_arm_up_traj = [[-0.4,  0.0,   0.0,  -2.05,  0.0,  -0.1,  0.0]]

# Tuck trajectory
l_arm_tuck_traj = [l_arm_tucked]
r_arm_tuck_traj = [r_arm_approach,
                   r_arm_tucked]

# Untuck trajctory
l_arm_untuck_traj = [l_arm_untucked]
r_arm_untuck_traj = [r_arm_approach,
                     r_arm_untucked]

# clear trajectory
l_arm_clear_traj = [l_arm_untucked]
r_arm_clear_traj = [r_arm_untucked]

[docs]class PR2TuckTest(RosTestCase):
[docs] def setUpEnv(self): print("Adding a PR2 robot...") pr2 = BasePR2() pr2.add_interface('ros') env = Environment('empty', fastmode=True) env.set_camera_rotation([1.0470, 0, 0.7854])
[docs] def test_tuck(self): rospy.init_node('test_pr2_tuck', disable_signals=True) # arm state: -1 unknown, 0 tucked, 1 untucked self.l_arm_state = -1 self.r_arm_state = -1 self.success = True # Get controller name and start joint trajectory action clients self.move_duration = 2.5 r_action_name = 'r_arm_controller/joint_trajectory_action' l_action_name = 'l_arm_controller/joint_trajectory_action' self.left_joint_client = actionlib.SimpleActionClient(l_action_name, JointTrajectoryAction) self.right_joint_client = actionlib.SimpleActionClient(r_action_name, JointTrajectoryAction) # Connect to controller state rospy.Subscriber('l_arm_controller/state', JointTrajectoryControllerState ,self.stateCb) rospy.Subscriber('r_arm_controller/state', JointTrajectoryControllerState ,self.stateCb) self.assertTrue(self.left_joint_client.wait_for_server(rospy.Duration(5))) self.assertTrue(self.right_joint_client.wait_for_server(rospy.Duration(5))) self.assertEqual(self.l_arm_state, -1) self.assertEqual(self.r_arm_state, -1) self.tuckL() self.assertEqual(self.l_arm_state, 0) self.assertEqual(self.r_arm_state, 1) self.tuckR() self.assertEqual(self.l_arm_state, 0) self.assertEqual(self.r_arm_state, 0) self.untuckL() self.assertEqual(self.l_arm_state, 1) self.assertEqual(self.r_arm_state, -1) self.untuckR() self.assertEqual(self.l_arm_state, 1) self.assertEqual(self.r_arm_state, 1)
# clears r arm and l arm
[docs] def tuckL(self): if self.l_arm_state != 0: self.go('r', r_arm_up_traj) if self.l_arm_state != 1: self.go('l', l_arm_clear_traj) self.go('l', l_arm_tuck_traj) self.go('r', r_arm_clear_traj)
# clears r arm
[docs] def untuckL(self): if self.l_arm_state != 1: self.go('r', r_arm_up_traj) if self.l_arm_state == 0: self.go('l', l_arm_untuck_traj) elif self.l_arm_state == -1: self.go('l', l_arm_clear_traj)
# assumes l tucked or cleared
[docs] def tuckR(self): if self.r_arm_state != 0: self.go('r', r_arm_tuck_traj)
# assumes l tucked or cleared
[docs] def untuckR(self): if self.r_arm_state == 0: self.go('r', r_arm_untuck_traj) elif self.r_arm_state == -1: self.go('r', r_arm_clear_traj)
[docs] def go(self, side, positions, wait = True): goal = JointTrajectoryGoal() goal.trajectory.joint_names = [side+"_"+name+"_joint" for name in joint_names] goal.trajectory.points = [] for p, count in zip(positions, range(0,len(positions)+1)): goal.trajectory.points.append(JointTrajectoryPoint( positions = p, velocities = [], accelerations = [], time_from_start = rospy.Duration((count+1) * self.move_duration))) goal.trajectory.header.stamp = rospy.get_rostime() + rospy.Duration(0.01) if wait: if not {'l': self.left_joint_client, 'r': self.right_joint_client}[side].send_goal_and_wait(goal, rospy.Duration(30.0), rospy.Duration(5.0)): self.success = False else: {'l': self.left_joint_client, 'r': self.right_joint_client}[side].send_goal(goal)
# Returns angle between -pi and + pi
[docs] def angleWrap(self, angle): while angle > math.pi: angle -= math.pi*2.0 while angle < -math.pi: angle += math.pi*2.0 return angle
[docs] def stateCb(self, msg): l_sum_tucked = 0 l_sum_untucked = 0 r_sum_tucked = 0 r_sum_untucked = 0 for name_state, name_desi, value_state, value_l_tucked, value_l_untucked, value_r_tucked, value_r_untucked in zip(msg.joint_names, joint_names, msg.actual.positions , l_arm_tucked, l_arm_untucked, r_arm_tucked, r_arm_untucked): value_state = self.angleWrap(value_state) if 'l_'+name_desi+'_joint' == name_state: self.l_received = True l_sum_tucked = l_sum_tucked + math.fabs(value_state - value_l_tucked) l_sum_untucked = l_sum_untucked + math.fabs(value_state - value_l_untucked) if 'r_'+name_desi+'_joint' == name_state: self.r_received = True r_sum_tucked = r_sum_tucked + math.fabs(value_state - value_r_tucked) r_sum_untucked = r_sum_untucked + math.fabs(value_state - value_r_untucked) if l_sum_tucked > 0 and l_sum_tucked < 0.1: self.l_arm_state = 0 elif l_sum_untucked > 0 and l_sum_untucked < 0.3: self.l_arm_state = 1 elif l_sum_tucked >= 0.1 and l_sum_untucked >= 0.3: self.l_arm_state = -1 if r_sum_tucked > 0 and r_sum_tucked < 0.1: self.r_arm_state = 0 elif r_sum_untucked > 0 and r_sum_untucked < 0.3: self.r_arm_state = 1 elif r_sum_tucked >= 0.1 and r_sum_untucked >= 0.3: self.r_arm_state = -1
########################## Run these tests ########################## if __name__ == "__main__": from morse.testing.testing import main main(PR2TuckTest)