Autonomous Racing  1
f1tenth Project Group of Technical University Dortmund, Germany
joystick_controller.cpp
Go to the documentation of this file.
1 #include "joystick_controller.h"
2 
3 #include <ros/console.h>
4 #include <std_msgs/Int64.h>
5 #include <std_msgs/Time.h>
6 
7 #include <teleoperation/joystick_controllerConfig.h>
8 
13 {
14  this->m_drive_parameter_publisher =
15  this->m_node_handle.advertise<drive_msgs::drive_param>(TOPIC_DRIVE_PARAMETERS, 1);
16  this->m_enable_manual_publisher = this->m_node_handle.advertise<std_msgs::Time>(TOPIC_HEARTBEAT_MANUAL, 1);
17  this->m_enable_autonomous_publisher = this->m_node_handle.advertise<std_msgs::Time>(TOPIC_HEARTBEAT_AUTONOMOUS, 1);
18 
19  this->m_joystick_subscriber =
20  this->m_node_handle.subscribe<sensor_msgs::Joy>("joy", 10, &JoystickController::joystickCallback, this);
21 
22  this->selectJoystickMapping();
23  this->m_acceleration_locked = true;
24  this->m_deceleration_locked = true;
25 
26  this->updateDynamicConfig();
27  m_dyn_cfg_server.setCallback([&](teleoperation::joystick_controllerConfig& cfg, uint32_t) {
28  m_joystick_map.steeringAxis = cfg.joystick_steering_axis;
29  m_joystick_map.accelerationAxis = cfg.joystick_acceleration_axis;
30  m_joystick_map.decelerationAxis = cfg.joystick_deceleration_axis;
31  m_joystick_map.enableManualButton = cfg.joystick_enable_manual_button;
32  m_joystick_map.enableAutonomousButton = cfg.joystick_enable_autonomous_button;
33 
34  m_acceleration_scaling_factor = cfg.acceleration_scaling_factor;
35  m_deceleration_scaling_factor = cfg.deceleration_scaling_factor;
36  m_steering_scaling_factor = cfg.steering_scaling_factor;
37  });
38 }
39 
40 std_msgs::Time createHearbeatMessage()
41 {
42  std_msgs::Time message;
43  message.data = ros::Time::now();
44  return message;
45 }
46 
47 void JoystickController::joystickCallback(const sensor_msgs::Joy::ConstPtr& joystick)
48 {
49  ROS_ASSERT_MSG(m_joystick_map.accelerationAxis < joystick->axes.size(),
50  "Invalid index access on joystick axis array");
51  ROS_ASSERT_MSG(m_joystick_map.decelerationAxis < joystick->axes.size(),
52  "Invalid index access on joystick axis array");
53  ROS_ASSERT_MSG(m_joystick_map.steeringAxis < joystick->axes.size(), "Invalid index access on joystick axis array");
54 
55  ROS_ASSERT_MSG(m_joystick_map.enableManualButton < joystick->buttons.size(),
56  "Invalid index access on joystick button array");
57  ROS_ASSERT_MSG(m_joystick_map.enableAutonomousButton < joystick->buttons.size(),
58  "Invalid index access on joystick button array");
59 
60  if (joystick->buttons[m_joystick_map.enableManualButton] == 1)
61  {
62  this->m_enable_manual_publisher.publish(createHearbeatMessage());
63  }
64  if (joystick->buttons[m_joystick_map.enableAutonomousButton] == 1)
65  {
66  this->m_enable_autonomous_publisher.publish(createHearbeatMessage());
67  }
68 
69  // compute and publish the provided steering and velocity
70  float acceleration = (joystick->axes[m_joystick_map.accelerationAxis] - 1) * -0.5f * m_acceleration_scaling_factor;
71  float deceleration = (joystick->axes[m_joystick_map.decelerationAxis] - 1) * -0.5f * m_deceleration_scaling_factor;
72 
73  if (this->m_acceleration_locked)
74  {
75  if (std::abs(acceleration) < EPSILON)
76  {
77  this->m_acceleration_locked = false;
78  }
79  else
80  {
81  acceleration = 0;
82  }
83  }
84  if (this->m_deceleration_locked)
85  {
86  if (std::abs(deceleration) < EPSILON)
87  {
88  this->m_deceleration_locked = false;
89  }
90  else
91  {
92  deceleration = 0;
93  }
94  }
95 
96  float velocity = acceleration - deceleration;
97 
98  float steering_angle = joystick->axes[m_joystick_map.steeringAxis] * -1.0f * m_steering_scaling_factor;
99 
100  ROS_ASSERT_MSG(velocity >= -1.0f && velocity <= 1.0f, "Velocity should be between -1 and 1");
101  ROS_ASSERT_MSG(steering_angle >= -1.0f && steering_angle <= 1.0f, "Steering angle should be between -1 and 1");
102 
103  this->publishDriveParameters(acceleration - deceleration, steering_angle);
104 }
105 
106 void JoystickController::publishDriveParameters(double velocity, double steering_angle)
107 {
108  drive_msgs::drive_param drive_parameters;
109  drive_parameters.velocity = velocity;
110  drive_parameters.angle = steering_angle;
111 
112  this->m_drive_parameter_publisher.publish(drive_parameters);
113 }
114 
115 void JoystickController::selectJoystickMapping()
116 {
117  std::string joystick_type = "";
118  ros::NodeHandle private_node_handle("~");
119  private_node_handle.getParam(PARAMETER_JOYSTICK_TYPE, joystick_type);
120 
121  if (joystick_type == "xbox360")
122  {
123  m_joystick_map = joystick_mapping_xbox360;
124  }
125  else if (joystick_type == "ps3")
126  {
127  m_joystick_map = joystick_mapping_ps3;
128  }
129  else if (joystick_type == "xboxone")
130  {
131  m_joystick_map = joystick_mapping_xboxone;
132  }
133  else if (joystick_type == "custom")
134  {
135  m_joystick_map = joystick_mapping_xbox360;
136  {
137  m_joystick_map.name = "custom";
138  private_node_handle.getParam(PARAMETER_JOYSTICK_STEERING_AXIS, m_joystick_map.steeringAxis);
139  private_node_handle.getParam(PARAMETER_JOYSTICK_ACCELERATION_AXIS, m_joystick_map.accelerationAxis);
140  private_node_handle.getParam(PARAMETER_JOYSTICK_DECELERATION_AXIS, m_joystick_map.decelerationAxis);
141  private_node_handle.getParam(PARAMETER_JOYSTICK_ENABLE_MANUAL_BTN, m_joystick_map.enableManualButton);
142  private_node_handle.getParam(PARAMETER_JOYSTICK_ENABLE_AUTONOMOUS_BTN,
143  m_joystick_map.enableAutonomousButton);
144  }
145  }
146  else
147  {
148  ROS_WARN_STREAM("No valid joystick_type argument provided. Falling back to " << joystick_mapping_default.name
149  << " keybindings");
150  ROS_INFO_STREAM(PARAMETER_JOYSTICK_TYPE << " : " << joystick_type);
151  m_joystick_map = joystick_mapping_default;
152  }
153  this->updateDynamicConfig();
154 }
155 
156 void JoystickController::updateDynamicConfig()
157 {
158  teleoperation::joystick_controllerConfig cfg;
159  {
160  cfg.joystick_steering_axis = m_joystick_map.steeringAxis;
161  cfg.joystick_acceleration_axis = m_joystick_map.accelerationAxis;
162  cfg.joystick_deceleration_axis = m_joystick_map.decelerationAxis;
163  cfg.joystick_enable_manual_button = m_joystick_map.enableManualButton;
164  cfg.joystick_enable_autonomous_button = m_joystick_map.enableAutonomousButton;
165 
166  cfg.acceleration_scaling_factor = m_acceleration_scaling_factor;
167  cfg.deceleration_scaling_factor = m_deceleration_scaling_factor;
168  cfg.steering_scaling_factor = m_steering_scaling_factor;
169  }
170  m_dyn_cfg_server.updateConfig(cfg);
171 }
172 
173 int main(int argc, char** argv)
174 {
175  ros::init(argc, argv, "joystick_controller");
176  JoystickController joystick_controller;
177 
178  ros::spin();
179 
180  return EXIT_SUCCESS;
181 }
JoystickController()
Construct a new Remote Joy:: Remote Joy object.
constexpr const char * TOPIC_HEARTBEAT_MANUAL
constexpr const char * PARAMETER_JOYSTICK_TYPE
constexpr const char * TOPIC_HEARTBEAT_AUTONOMOUS
std_msgs::Time createHearbeatMessage()
constexpr const char * PARAMETER_JOYSTICK_DECELERATION_AXIS
constexpr float EPSILON
constexpr const char * PARAMETER_JOYSTICK_ACCELERATION_AXIS
constexpr const char * PARAMETER_JOYSTICK_ENABLE_MANUAL_BTN
constexpr const char * PARAMETER_JOYSTICK_ENABLE_AUTONOMOUS_BTN
constexpr const char * PARAMETER_JOYSTICK_STEERING_AXIS
int main(int argc, char **argv)