1 from .controller
import Controller
4 from sensor_msgs.msg
import BatteryState
5 from sensor_msgs.msg
import Joy
6 from sensor_msgs.msg
import JoyFeedback
7 from sensor_msgs.msg
import JoyFeedbackArray
8 from sensor_msgs.msg
import Imu
9 from ds4_driver.msg
import Feedback
10 from ds4_driver.msg
import Report
11 from ds4_driver.msg
import Status
19 super(ControllerRos, self).
__init__()
22 self.
deadzone = rospy.get_param(
'~deadzone', 0.1)
23 self.
frame_id = rospy.get_param(
'~frame_id',
'ds4')
31 self.
pub_report = rospy.Publisher(
'raw_report', Report, queue_size=1)
32 self.
pub_battery = rospy.Publisher(
'battery', BatteryState, queue_size=1)
33 self.
pub_joy = rospy.Publisher(
'joy', Joy, queue_size=1)
34 self.
pub_imu = rospy.Publisher(
'imu', Imu, queue_size=1)
41 self.
pub_status = rospy.Publisher(
'status', Status, queue_size=1)
46 Callback method for ds4drv event loop 51 report_msg.header.frame_id = self.
frame_id 52 report_msg.header.stamp = rospy.Time.now()
53 for attr
in dir(report):
54 if attr.startswith(
'_'):
56 if hasattr(report_msg, attr):
57 val = getattr(report, attr)
58 setattr(report_msg, attr, val)
60 imu_data = Controller.get_imu_data(report)
61 report_msg.lin_acc_x = imu_data[
'lin_acc'][
'x']
62 report_msg.lin_acc_y = imu_data[
'lin_acc'][
'y']
63 report_msg.lin_acc_z = imu_data[
'lin_acc'][
'z']
64 report_msg.ang_vel_x = imu_data[
'ang_vel'][
'x']
65 report_msg.ang_vel_y = imu_data[
'ang_vel'][
'y']
66 report_msg.ang_vel_z = imu_data[
'ang_vel'][
'z']
79 or joy_msg.buttons != self.
_prev_joy.buttons:
89 Callback method for ds4_driver/Feedback 97 def to_int(v):
return int(v * 255)
100 led_red=to_int(msg.led_r)
if msg.set_led
else None,
101 led_green=to_int(msg.led_g)
if msg.set_led
else None,
102 led_blue=to_int(msg.led_b)
if msg.set_led
else None,
104 rumble_small=to_int(msg.rumble_small)
if msg.set_rumble
else None,
105 rumble_big=to_int(msg.rumble_big)
if msg.set_rumble
else None,
107 flash_on=to_int(msg.led_flash_on / 2.5)
if msg.set_led_flash
else None,
108 flash_off=to_int(msg.led_flash_off / 2.5)
if msg.set_led_flash
else None,
112 if msg.set_rumble
and msg.rumble_duration != 0:
113 rospy.Timer(rospy.Duration(msg.rumble_duration),
119 self.
control(rumble_small=0, rumble_big=0)
120 except AttributeError:
126 Callback method for sensor_msgs/JoyFeedbackArray 127 The message contains the following feedback: 131 RUMBLE0: rumble small 134 :type msg: JoyFeedbackArray 137 feedback = Feedback()
139 if jf.type == JoyFeedback.TYPE_LED:
140 feedback.set_led =
True 142 feedback.led_r = jf.intensity
144 feedback.led_g = jf.intensity
146 feedback.led_b = jf.intensity
147 elif jf.type == JoyFeedback.TYPE_RUMBLE:
148 feedback.set_rumble =
True 150 feedback.rumble_small = jf.intensity
152 feedback.rumble_big = jf.intensity
162 status_msg = Status()
163 status_msg.header = copy.deepcopy(report_msg.header)
166 status_msg.axis_left_x = -ControllerRos._normalize_axis_(report_msg.left_analog_x, deadzone)
167 status_msg.axis_left_y = -ControllerRos._normalize_axis_(report_msg.left_analog_y, deadzone)
168 status_msg.axis_right_x = -ControllerRos._normalize_axis_(report_msg.right_analog_x, deadzone)
169 status_msg.axis_right_y = -ControllerRos._normalize_axis_(report_msg.right_analog_y, deadzone)
172 status_msg.axis_l2 = report_msg.l2_analog / 255.0
173 status_msg.axis_r2 = report_msg.r2_analog / 255.0
176 status_msg.button_dpad_up = report_msg.dpad_up
177 status_msg.button_dpad_down = report_msg.dpad_down
178 status_msg.button_dpad_left = report_msg.dpad_left
179 status_msg.button_dpad_right = report_msg.dpad_right
180 plug_attrs = [attr
for attr
in dir(report_msg)
if attr.startswith(
'button_')]
181 for attr
in plug_attrs:
182 val = getattr(report_msg, attr)
183 setattr(status_msg, attr, val)
186 status_msg.imu.header = copy.deepcopy(status_msg.header)
188 def to_mpss(v):
return float(v) / (2**13 - 1) * 9.80665 * 0.98
190 def to_radps(v):
return float(v) / (2**15 - 1) * math.pi / 180 * 2000
192 status_msg.imu.linear_acceleration.x = to_mpss(report_msg.lin_acc_x)
193 status_msg.imu.linear_acceleration.y = to_mpss(report_msg.lin_acc_y)
194 status_msg.imu.linear_acceleration.z = to_mpss(report_msg.lin_acc_z)
195 status_msg.imu.angular_velocity.x = to_radps(report_msg.ang_vel_x)
196 status_msg.imu.angular_velocity.y = to_radps(report_msg.ang_vel_y)
197 status_msg.imu.angular_velocity.z = to_radps(report_msg.ang_vel_z)
199 status_msg.imu.orientation_covariance[0] = -1
202 status_msg.touch0.id = report_msg.trackpad_touch0_id
203 status_msg.touch0.active = report_msg.trackpad_touch0_active
204 status_msg.touch0.x = report_msg.trackpad_touch0_x / float(Controller.TOUCHPAD_MAX_X)
205 status_msg.touch0.y = report_msg.trackpad_touch0_y / float(Controller.TOUCHPAD_MAX_Y)
206 status_msg.touch1.id = report_msg.trackpad_touch1_id
207 status_msg.touch1.active = report_msg.trackpad_touch1_active
208 status_msg.touch1.x = report_msg.trackpad_touch1_x / float(Controller.TOUCHPAD_MAX_X)
209 status_msg.touch1.y = report_msg.trackpad_touch1_y / float(Controller.TOUCHPAD_MAX_Y)
212 if report_msg.battery == Controller.BATTERY_FULL_CHARGING:
213 status_msg.battery_full_charging =
True 214 status_msg.battery_percentage = 1.0
216 status_msg.battery_full_charging =
False 217 status_msg.battery_percentage = float(report_msg.battery) / Controller.BATTERY_MAX
220 plug_attrs = [attr
for attr
in dir(report_msg)
if attr.startswith(
'plug_')]
221 for attr
in plug_attrs:
222 val = getattr(report_msg, attr)
223 setattr(status_msg, attr, val)
230 Convert a value of [0, 255] to [-1.0, 1.0] 235 norm_val = 2 * (val - 127.5) / 255
236 if abs(norm_val) < deadzone:
244 Converts a ds4_driver/Status message to sensor_msgs/Joy 250 msg.header = copy.deepcopy(status.header)
260 status.button_square,
261 status.button_triangle,
262 status.button_circle,
269 status.button_options,
271 status.button_trackpad,
274 status.button_dpad_left,
275 status.button_dpad_up,
276 status.button_dpad_right,
277 status.button_dpad_down,
284 Converts a ds4_driver/Status to sensor_msgs/BatteryState 285 Reference: https://www.psdevwiki.com/ps4/DualShock_4#Specifications 291 msg.header = status.header
292 msg.percentage = status.battery_percentage
293 msg.voltage = Controller.MAX_VOLTAGE * msg.percentage
294 msg.current = float(
'NaN')
295 msg.charge = float(
'NaN')
296 msg.capacity = float(
'NaN')
297 msg.design_capacity = 1.0
298 if not status.plug_usb:
299 msg.power_supply_status = BatteryState.POWER_SUPPLY_STATUS_NOT_CHARGING
300 elif not status.battery_full_charging:
301 msg.power_supply_status = BatteryState.POWER_SUPPLY_STATUS_CHARGING
302 elif status.battery_full_charging:
303 msg.power_supply_status = BatteryState.POWER_SUPPLY_STATUS_FULL
304 msg.power_supply_technology = BatteryState.POWER_SUPPLY_TECHNOLOGY_LION
310 Converts a ds4_driver/Status to sensor_msgs/Imu
def cb_report(self, report)
def _status_to_joy_(status)
def cb_stop_rumble(self, event)
def cb_joy_feedback(self, msg)
def control(self, led_red=None, led_green=None, led_blue=None, rumble_small=None, rumble_big=None, flash_on=None, flash_off=None)
def _status_to_battery_(status)
def _normalize_axis_(val, deadzone=0.0)
def _status_to_imu_(status)
def _report_to_status_(report_msg, deadzone=0.05)
def cb_joy_pub_timer(self, _)
def cb_feedback(self, msg)