2 from __future__
import division
18 from actionlib_msgs.msg
import GoalID
19 from geometry_msgs.msg
import TwistStamped
20 from sensor_msgs.msg
import Joy
21 from std_msgs.msg
import Bool
22 from std_msgs.msg
import Float32, String
25 rospy.init_node(
'xbox_mapper_node', anonymous=
True)
29 last_a_button = time.time()
30 last_b_button = time.time()
31 last_x_button = time.time()
32 last_y_button = time.time()
33 last_joycb_device_check = time.time()
40 driver = rospy.get_param(
'/xbox_mapper_node/driver',
'xboxdrv')
41 wired_or_wireless = rospy.get_param(
'/xbox_mapper_node/wired_or_wireless',
'wireless')
44 rospy.logfatal(
'[{node_name}] xpad driver not supported.'.format(node_name=rospy.get_name()))
45 rospy.signal_shutdown(
'xpad driver not supported.')
48 elif wired_or_wireless ==
'wired' and driver ==
'xboxdrv':
49 rospy.loginfo(
'XBOX CONFIG: wired & xboxdrv')
50 rospy.logwarn(
'If the wired controller becomes unplugged during operation ' 51 'xboxdrv may continue to publish the last command from the ' 52 'controller, causing the vehicle to run away.')
54 elif wired_or_wireless ==
'wireless' and driver ==
'xboxdrv':
55 rospy.loginfo(
'XBOX CONFIG: wireless & xboxdrv')
58 rospy.logfatal(
'Unsupported controller configuration: {driver}, {connection}' 59 .format(driver=driver, connection=wired_or_wireless))
60 rospy.signal_shutdown(
'Unsupported controller configuration.')
90 MAX_VEL_FWD = rospy.get_param(
'~max_vel_drive', 2.6)
91 MAX_VEL_TURN = rospy.get_param(
'~max_vel_turn', 9.0)
92 MAX_VEL_FLIPPER = rospy.get_param(
'~max_vel_flipper', 1.4)
93 DRIVE_THROTTLE = rospy.get_param(
'~default_drive_throttle', 0.15)
94 FLIPPER_THROTTLE = rospy.get_param(
'~default_flipper_throttle', 0.6)
95 ADJ_THROTTLE = rospy.get_param(
'~adjustable_throttle',
True)
96 A_BUTTON_TOGGLE = rospy.get_param(
'~a_button_toggle',
False)
97 B_BUTTON_TOGGLE = rospy.get_param(
'~b_button_toggle',
False)
98 X_BUTTON_TOGGLE = rospy.get_param(
'~x_button_toggle',
False)
99 Y_BUTTON_TOGGLE = rospy.get_param(
'~y_button_toggle',
False)
101 DRIVE_INCREMENTS = rospy.get_param(
'~drive_increment', 20.0)
102 FLIPPER_INCREMENTS = rospy.get_param(
'~drive_increment', 20.0)
108 a_button_msg = Bool()
109 a_button_msg.data =
False 110 b_button_msg = Bool()
111 b_button_msg.data =
False 112 x_button_msg = Bool()
113 x_button_msg.data =
False 114 y_button_msg = Bool()
115 y_button_msg.data =
False 118 pub = rospy.Publisher(
'/cmd_vel/joystick', TwistStamped, queue_size=3)
119 a_button_pub = rospy.Publisher(
'/joystick/a_button', Bool, queue_size=1, latch=
True)
120 b_button_pub = rospy.Publisher(
'/joystick/b_button', Bool, queue_size=1, latch=
True)
121 x_button_pub = rospy.Publisher(
'/joystick/x_button', Bool, queue_size=1, latch=
True)
122 y_button_pub = rospy.Publisher(
'/joystick/y_button', Bool, queue_size=1, latch=
True)
123 pub_delay = rospy.Publisher(
'/joystick/delay', Float32, queue_size=3)
124 pub_cancel_move_base = rospy.Publisher(
'/move_base/cancel', GoalID, queue_size=10)
129 global prev_fwd, prev_trn
131 fwd_acc = fwd - prev_fwd
132 if fwd_acc > FWD_ACC_LIM:
133 fwd = prev_fwd + FWD_ACC_LIM
134 elif fwd_acc < -FWD_ACC_LIM:
135 fwd = prev_fwd - FWD_ACC_LIM
137 trn_acc = trn - prev_trn
138 if trn_acc > TRN_ACC_LIM:
139 trn = prev_trn + TRN_ACC_LIM
140 elif trn_acc < -TRN_ACC_LIM:
141 trn = prev_trn - TRN_ACC_LIM
153 global MAX_VEL_FLIPPER
154 global DRIVE_THROTTLE
155 global FLIPPER_THROTTLE
156 global DRIVE_INCREMENTS
157 global FLIPPER_INCREMENTS
164 global last_a_button, last_b_button, last_x_button, last_y_button
165 global last_joycb_device_check
166 global a_button_pub, a_button_msg, b_button_pub, b_button_msg
167 global x_button_pub, x_button_msg, y_button_pub, y_button_msg
169 cmd_time = float(Joy.header.stamp.secs) + (float(Joy.header.stamp.nsecs) / 1000000000)
170 rbt_time = time.time()
171 signal_delay = rbt_time - cmd_time
173 joy_delay = Float32()
174 joy_delay.data = signal_delay
175 pub_delay.publish(joy_delay)
178 PREV_CMD_TIME = cmd_time
179 PREV_SEQ_NUM = Joy.header.seq
184 if Joy.buttons[A_BUTTON] == 1:
185 if time.time() - last_a_button > MIN_TOGGLE_DUR:
186 last_a_button = time.time()
187 a_button_state =
not a_button_msg.data
188 rospy.loginfo(
'A button toggled: {state}'.format(state=a_button_state))
189 a_button_msg.data = a_button_state
191 if Joy.buttons[A_BUTTON] == 1:
192 a_button_msg.data =
True 194 a_button_msg.data =
False 195 a_button_pub.publish(a_button_msg)
199 if Joy.buttons[B_BUTTON] == 1:
200 if time.time() - last_b_button > MIN_TOGGLE_DUR:
201 last_b_button = time.time()
202 b_button_state =
not b_button_msg.data
203 rospy.loginfo(
'B button toggled: {state}'.format(state=b_button_state))
204 b_button_msg.data = b_button_state
206 if Joy.buttons[B_BUTTON] == 1:
207 b_button_msg.data =
True 209 b_button_msg.data =
False 210 b_button_pub.publish(b_button_msg)
214 if Joy.buttons[X_BUTTON] == 1:
215 if time.time() - last_x_button > MIN_TOGGLE_DUR:
216 last_x_button = time.time()
217 x_button_state =
not x_button_msg.data
218 rospy.loginfo(
'X button toggled: {state}'.format(state=x_button_state))
219 x_button_msg.data = x_button_state
221 if Joy.buttons[X_BUTTON] == 1:
222 x_button_msg.data =
True 224 x_button_msg.data =
False 225 x_button_pub.publish(x_button_msg)
229 if Joy.buttons[Y_BUTTON] == 1:
230 if time.time() - last_y_button > MIN_TOGGLE_DUR:
231 last_y_button = time.time()
232 y_button_state =
not y_button_msg.data
233 rospy.loginfo(
'Y button toggled: {state}'.format(state=y_button_state))
234 y_button_msg.data = y_button_state
236 if Joy.buttons[Y_BUTTON] == 1:
237 y_button_msg.data =
True 239 y_button_msg.data =
False 240 y_button_pub.publish(y_button_msg)
244 if (driver ==
'xpad'):
245 if int(Joy.axes[DPAD_V_AXES]) == 1
and not DPAD_ACTIVE:
246 DRIVE_THROTTLE += (1 / DRIVE_INCREMENTS)
248 if int(Joy.axes[DPAD_V_AXES]) == -1
and not DPAD_ACTIVE:
249 DRIVE_THROTTLE -= (1 / DRIVE_INCREMENTS)
251 elif (driver ==
'xboxdrv'):
252 if int(Joy.axes[DPAD_V_AXES]) == 1
and not DPAD_ACTIVE:
253 DRIVE_THROTTLE += (1 / DRIVE_INCREMENTS)
255 if int(Joy.axes[DPAD_V_AXES]) == -1
and not DPAD_ACTIVE:
256 DRIVE_THROTTLE -= (1 / DRIVE_INCREMENTS)
259 if Joy.buttons[LB_BUTTON] == 1:
260 FLIPPER_THROTTLE -= (1 / FLIPPER_INCREMENTS)
261 rospy.loginfo(FLIPPER_THROTTLE)
262 if Joy.buttons[RB_BUTTON] == 1:
263 FLIPPER_THROTTLE += (1 / FLIPPER_INCREMENTS)
264 rospy.loginfo(FLIPPER_THROTTLE)
268 if DRIVE_THROTTLE <= 0.001:
269 DRIVE_THROTTLE = (1 / DRIVE_INCREMENTS)
270 if FLIPPER_THROTTLE <= 0.001:
271 FLIPPER_THROTTLE = (1 / FLIPPER_INCREMENTS)
275 if DRIVE_THROTTLE >= 1:
277 if FLIPPER_THROTTLE >= 1:
281 FWD_DEADBAND = 0.2 * DRIVE_THROTTLE * MAX_VEL_FWD
282 TURN_DEADBAND = 0.2 * DRIVE_THROTTLE * MAX_VEL_TURN
283 FLIPPER_DEADBAND = 0.2 * FLIPPER_THROTTLE * MAX_VEL_FLIPPER
286 rospy.loginfo(
'Drive Throttle: %f', DRIVE_THROTTLE)
288 if (Joy.axes[DPAD_V_AXES], Joy.axes[DPAD_H_AXES]) == (0, 0):
292 drive_cmd = DRIVE_THROTTLE * MAX_VEL_FWD * Joy.axes[L_STICK_V_AXES]
293 if drive_cmd < FWD_DEADBAND
and -FWD_DEADBAND < drive_cmd:
297 turn_cmd = (1.1 - (drive_cmd / MAX_VEL_FWD)) * DRIVE_THROTTLE * MAX_VEL_TURN * Joy.axes[
299 if turn_cmd < TURN_DEADBAND
and -TURN_DEADBAND < turn_cmd:
303 flipper_cmd = (FLIPPER_THROTTLE * MAX_VEL_FLIPPER * Joy.axes[L_TRIG_AXES]) - (
304 FLIPPER_THROTTLE * MAX_VEL_FLIPPER * Joy.axes[R_TRIG_AXES])
305 if flipper_cmd < FLIPPER_DEADBAND
and -FLIPPER_DEADBAND < flipper_cmd:
312 if (drive_cmd != 0)
or (turn_cmd != 0):
313 last_joycb_device_check = time.time()
317 cmd.header.stamp = rospy.Time.now()
318 cmd.twist.linear.x = drive_cmd
319 cmd.twist.angular.y = flipper_cmd
320 cmd.twist.angular.z = turn_cmd
330 a_button_pub.publish(a_button_msg)
331 b_button_pub.publish(b_button_msg)
332 x_button_pub.publish(x_button_msg)
333 y_button_pub.publish(y_button_msg)
335 while not rospy.is_shutdown():
337 sub_cmds = rospy.Subscriber(
'joystick', Joy, joy_cb)
344 if __name__ ==
'__main__':
347 except rospy.ROSInterruptException: