1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 import rospy
29
30 from std_msgs.msg import (
31 Bool
32 )
33
34 import baxter_dataflow
35
36 from baxter_core_msgs.msg import (
37 HeadPanCommand,
38 HeadState,
39 )
40 from baxter_interface import settings
41
42
44 """
45 Interface class for the head on the Baxter Robot.
46
47 Used to control the head pan angle and to enable/disable the head nod
48 action.
49 """
51 """
52 Constructor.
53 """
54 self._state = dict()
55
56 self._pub_pan = rospy.Publisher(
57 '/robot/head/command_head_pan',
58 HeadPanCommand)
59
60 self._pub_nod = rospy.Publisher(
61 '/robot/head/command_head_nod',
62 Bool)
63
64 state_topic = '/robot/head/head_state'
65 self._sub_state = rospy.Subscriber(
66 state_topic,
67 HeadState,
68 self._on_head_state)
69
70 baxter_dataflow.wait_for(
71 lambda: len(self._state) != 0,
72 timeout=5.0,
73 timeout_msg=("Failed to get current head state from %s" %
74 (state_topic,)),
75 )
76
78 self._state['pan'] = msg.pan
79 self._state['panning'] = msg.isPanning
80 self._state['nodding'] = msg.isNodding
81
83 """
84 Get the current pan angle of the head.
85
86 @rtype: float
87 @return: current angle in radians
88 """
89 return self._state['pan']
90
92 """
93 Check if the head is currently nodding.
94
95 @rtype: bool
96 @return: True if the head is currently nodding, False otherwise.
97 """
98 return self._state['nodding']
99
101 """
102 Check if the head is currently panning.
103
104 @rtype: bool
105 @return: True if the head is currently panning, False otherwise.
106 """
107 return self._state['panning']
108
109 - def set_pan(self, angle, speed=100, timeout=10.0):
110 """
111 Pan at the given speed to the desired angle.
112
113 @type angle: float
114 @param angle: Desired pan angle in radians.
115 @type speed: int
116 @param speed: Desired speed to pan at, range is 0-100 [100]
117 @type timeout: float
118 @param timeout: Seconds to wait for the head to pan to the
119 specified angle. If 0, just command once and
120 return. [10]
121 """
122 msg = HeadPanCommand(angle, speed)
123 self._pub_pan.publish(msg)
124
125 if not timeout == 0:
126 baxter_dataflow.wait_for(
127 lambda: (abs(self.pan() - angle) <=
128 settings.HEAD_PAN_ANGLE_TOLERANCE),
129 timeout=timeout,
130 rate=100,
131 timeout_msg="Failed to move head to pan command %f" % angle,
132 body=lambda: self._pub_pan.publish(msg)
133 )
134
136 """
137 Command the head to nod once.
138
139 @type timeout: float
140 @param timeout: Seconds to wait for the head to nod.
141 If 0, just command once and return. [0]
142 """
143 self._pub_nod.publish(True)
144
145 if not timeout == 0:
146
147 baxter_dataflow.wait_for(
148 test=self.nodding,
149 timeout=timeout,
150 rate=100,
151 timeout_msg="Failed to initiate head nod command",
152 body=lambda: self._pub_nod.publish(True)
153 )
154
155
156 baxter_dataflow.wait_for(
157 test=lambda: not self.nodding(),
158 timeout=timeout,
159 rate=100,
160 timeout_msg="Failed to complete head nod command",
161 body=lambda: self._pub_nod.publish(False)
162 )
163