head_control_by_trackball.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 import threading
4 from operator import add
5 import math
6 import rospy
7 from sensor_msgs.msg import Joy, CameraInfo, JointState
8 import actionlib
9 import control_msgs.msg
10 import hrpsys_ros_bridge.srv
11 # try:
12 # from image_view2.msg import ImageMarker2
13 # except:
14 # import roslib; roslib.load_manifest("jsk_teleop_joy")
15 # from image_view2.msg import ImageMarker2
16 
17 from control_msgs.msg import FollowJointTrajectoryAction, FollowJointTrajectoryGoal
18 from trajectory_msgs.msg import JointTrajectoryPoint
19 
20 def inRange(val, min, max):
21  if val < min:
22  return min
23  elif val > max:
24  return max
25  else:
26  return val
27 
29  camera_info = None
30  joint_state = None
31  current_cursor = (0, 0)
32  camera_info_lock = threading.Lock()
33  joint_state_lock = threading.Lock()
34  def camCB(self, msg):
35  with self.camera_info_lock:
36  if self.camera_info == None:
37  # initialize current_cursor
38  self.current_cursor = (msg.width / 2, msg.height / 2)
39  self.camera_info = msg
40  def getCameraInfo(self):
41  with self.camera_info_lock:
42  return self.camera_info
43  def procSequence(self, sequence):
44  if len(sequence) > 0:
45  # integral the sequence
46  dx = - reduce(add, [msg.axes[0] for msg in sequence])
47  dy = reduce(add, [msg.axes[1] for msg in sequence])
48  print((dx, dy))
49  dpitch_deg = dx / 2.0
50  dyaw_deg = dy / 2.0
51  dpitch_rad = dpitch_deg / 180.0 * math.pi
52  dyaw_rad = dyaw_deg / 180.0 * math.pi
53  joint_state = self.getJointState()
54  if not joint_state: #not yet /joint_state is ready
55  rospy.logwarn("joint_state is not yet available")
56  return
57  if (self.pitch_joint_name in joint_state.name and
58  self.yaw_joint_name in joint_state.name):
59  pitch_index = joint_state.name.index(self.pitch_joint_name)
60  yaw_index = joint_state.name.index(self.yaw_joint_name)
61  current_pitch = joint_state.position[pitch_index]
62  current_yaw = joint_state.position[yaw_index]
63  print((current_pitch, current_yaw))
64  next_pitch = current_pitch + dpitch_rad
65  next_yaw = current_yaw + dyaw_rad
66  print((next_pitch, next_yaw))
67  # move
68  goal = FollowJointTrajectoryGoal()
69  goal.trajectory.header.stamp = joint_state.header.stamp
70  goal.trajectory.joint_names = [self.pitch_joint_name,
71  self.yaw_joint_name]
72  p = JointTrajectoryPoint()
73  p.positions = [next_pitch, next_yaw]
74  p.time_from_start = rospy.Duration(0.2) #0.2 sec
75  goal.trajectory.points = [p]
76  self.ac_client.send_goal(goal)
77  self.ac_client.wait_for_result()
78  else:
79  rospy.logwarn("the joint for pitch and yaw cannot be found in joint_states")
80  return
82  print('enable head joint group')
83  self.enable_head_joint_group_srv(gname='head', jnames=[self.pitch_joint_name, self.yaw_joint_name])
86  print('disable head joint group')
87  self.disable_head_joint_group_srv(gname='head')
88  self.enable_head_control_flag = False
89  def jointCB(self, msg):
90  with self.joint_state_lock:
91  self.joint_state = msg
92  def getJointState(self):
93  with self.joint_state_lock:
94  return self.joint_state
95  def joyCB(self, msg):
96  if not self.prev_buttons:
97  self.prev_buttons = msg.buttons
98  if (msg.buttons[0] == 1 and self.prev_buttons[0] == 0):
100  elif (msg.buttons[2] == 1 and self.prev_buttons[2] == 0):
102  elif (abs(msg.axes[0]) > 1.0 or abs(msg.axes[1]) > 1.0):
103  self.procSequence([msg])
104  self.prev_buttons = msg.buttons
105  def joyCB2(self, msg):
106  camera_info = self.getCameraInfo()
107  if not camera_info:
108  rospy.logfatal("camera_info is not yet available")
109  return
110  (raw_dx, raw_dy) = (msg.axes[0], msg.axes[1])
111  current_x = self.current_cursor[0]
112  current_y = self.current_cursor[1]
113  next_x = inRange(raw_dx + current_x, 0, camera_info.width)
114  next_y = inRange(-raw_dy + current_y, 0, camera_info.height)
115  self.current_cursor = (next_x, next_y)
116  self.publishCursor(msg.header.stamp, self.current_cursor)
117  def publishCursor(self, stamp, pos):
118  marker = ImageMarker2()
119  marker.header.stamp = stamp
120  marker.type = ImageMarker2.CIRCLE
121  marker.position.x = pos[0]
122  marker.position.y = pos[1]
123  marker.scale = 10 #5 px
124  self.marker_pub.publish(marker)
125  def main(self):
126  self.pitch_joint_name = rospy.get_param("~pitch_joint", "head_pan_joint")
127  self.yaw_joint_name = rospy.get_param("~yaw_joint", "head_tilt_joint")
128  self.enable_head_joint_group_srv = rospy.ServiceProxy('/SequencePlayerServiceROSBridge/addJointGroup',
129  hrpsys_ros_bridge.srv.OpenHRP_SequencePlayerService_addJointGroup)
130  self.disable_head_joint_group_srv = rospy.ServiceProxy('/SequencePlayerServiceROSBridge/removeJointGroup',
131  hrpsys_ros_bridge.srv.OpenHRP_SequencePlayerService_removeJointGroup)
133  self.prev_buttons = False
134  self.joint_trajectory_action_name = rospy.get_param("~joint_trajectory_action", "/head_traj_controller/follow_joint_trajectory")
136  control_msgs.msg.FollowJointTrajectoryAction)
137  self.ac_client.wait_for_server()
138  #self.marker_pub = rospy.Publisher("/image_marker", ImageMarker2)
139  s = rospy.Subscriber("/trackball_joy", Joy, self.joyCB, queue_size=1)
140  scam = rospy.Subscriber("camera_info", CameraInfo, self.camCB)
141  sjs = rospy.Subscriber("/joint_states", JointState, self.jointCB)
142  rospy.spin()
143 
144 
145 
146 def main():
147  controller = TrackballController()
148  controller.main()
149 
150 
151 if __name__ == "__main__":
152  rospy.init_node("head_control_by_trackball")
153  main()
154 
155 


jsk_teleop_joy
Author(s): Ryohei Ueda
autogenerated on Fri May 14 2021 02:52:11