rbcar_pad.cpp
Go to the documentation of this file.
1 /*
2  * rbcar_pad
3  * Copyright (c) 2015, Robotnik Automation, SLL
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * * Neither the name of the Robotnik Automation, SLL. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  *
30  * \author Robotnik Automation, SLL
31  * \brief Allows to use a pad with the robot controller, sending the messages received from the joystick device
32  */
33 
34 #include <ros/ros.h>
35 #include <sensor_msgs/Joy.h>
36 #include <geometry_msgs/Twist.h>
37 #include <std_msgs/Int32.h>
38 #include <unistd.h>
39 #include <vector>
40 #include <robotnik_msgs/enable_disable.h>
41 #include <robotnik_msgs/set_digital_output.h>
42 #include "diagnostic_msgs/DiagnosticStatus.h"
47 #include "ackermann_msgs/AckermannDriveStamped.h"
48 #include <std_srvs/Empty.h>
49 #include "robotnik_msgs/set_mode.h"
50 #include "robotnik_msgs/get_mode.h"
51 
52 #define DEFAULT_MAX_LINEAR_SPEED 3.0 // m/s
53 #define DEFAULT_MAX_ANGULAR_POSITION 0.5 // rads/s
54 
55 #define MAX_NUM_OF_BUTTONS 16
56 #define MAX_NUM_OF_AXES 8
57 #define MAX_NUM_OF_BUTTONS_PS3 19
58 #define MAX_NUM_OF_AXES_PS3 20
59 
60 #define DEFAULT_NUM_OF_BUTTONS 16
61 #define DEFAULT_NUM_OF_AXES 8
62 
63 #define DEFAULT_AXIS_LINEAR_X 1
64 #define DEFAULT_AXIS_ANGULAR 2
65 #define DEFAULT_SCALE_LINEAR 1.0
66 #define DEFAULT_SCALE_ANGULAR 1.0
67 
68 #define DEFAULT_JOY "/joy"
69 #define DEFAULT_HZ 50.0
70 
72 class Button
73 {
74  int iPressed;
75  bool bReleased;
76 
77 public:
79  {
80  iPressed = 0;
81  bReleased = false;
82  }
84  void Press(int value)
85  {
86  if (iPressed and !value)
87  {
88  bReleased = true;
89  }
90  else if (bReleased and value)
91  bReleased = false;
92 
93  iPressed = value;
94  }
95 
96  int IsPressed()
97  {
98  return iPressed;
99  }
100 
101  bool IsReleased()
102  {
103  bool b = bReleased;
104  bReleased = false;
105  return b;
106  }
107 };
108 
109 class RbcarPad
110 {
111 public:
112  RbcarPad();
113 
114  void ControlLoop();
115  int SetStateMode(int state, int arm_mode, int platform_mode);
116 
117 private:
118  void joyCallback(const sensor_msgs::Joy::ConstPtr& joy);
119 
120  char* StateToString(int state);
121  int SwitchToState(int new_state);
122 
123  void PublishState();
125  bool EnableDisable(robotnik_msgs::enable_disable::Request& req, robotnik_msgs::enable_disable::Response& res);
126  void Update();
127 
128 private:
130 
131  int axis_linear_speed_, axis_angular_position_;
132  double l_scale_, a_scale_;
135  double max_linear_speed_, max_angular_position_;
138 
139  // TOPICS
145  std::string joy_topic_;
147  std::string cmd_topic_vel;
149  std::string cmd_service_io_;
151  std::string topic_state_;
154 
155  // SERVICES
159 
160  // JOYSTICK
164 
166  std::vector<float> fAxes;
168  std::vector<Button> vButtons;
172  int button_speed_up_, button_speed_down_;
173  int output_1_, output_2_;
174  bool bOutput1, bOutput2;
176  int ptz_tilt_up_, ptz_tilt_down_, ptz_pan_right_, ptz_pan_left_;
178  std::string cmd_service_ptz_;
186  std::string cmd_set_mode_;
187 
188  // DIAGNOSTICS
196  double min_freq_command, min_freq_joy;
198  double max_freq_command, max_freq_joy;
200  bool bEnable;
201 };
202 
203 RbcarPad::RbcarPad() : axis_linear_speed_(1), axis_angular_position_(2), pnh_("~")
204 {
205  current_speed_lvl = 0.1;
206  //
207  pnh_.param("num_of_buttons", num_of_buttons_, DEFAULT_NUM_OF_BUTTONS);
208  pnh_.param("num_of_axes", num_of_axes_, DEFAULT_NUM_OF_AXES);
209  pnh_.param("desired_freq", desired_freq_, DEFAULT_HZ);
210 
212  {
214  ROS_INFO("RbcarPad::RbcarPad: Limiting the max number of axes to %d", MAX_NUM_OF_AXES);
215  }
217  {
219  ROS_INFO("RbcarPad::RbcarPad: Limiting the max number of buttons to %d", MAX_NUM_OF_BUTTONS);
220  }
221 
222  pnh_.param("topic_joy", joy_topic_, std::string(DEFAULT_JOY));
223 
224  // MOTION CONF
225  pnh_.param("cmd_topic_vel", cmd_topic_vel, std::string("/rbcar_robot_control/command"));
226 
227  pnh_.param("button_dead_man", button_dead_man_, button_dead_man_);
228  pnh_.param("button_speed_up", button_speed_up_, button_speed_up_);
229  pnh_.param("button_speed_down", button_speed_down_, button_speed_down_);
231  pnh_.param("max_linear_speed_", max_linear_speed_, DEFAULT_MAX_LINEAR_SPEED);
232  pnh_.param("axis_linear_speed", axis_linear_speed_, DEFAULT_AXIS_LINEAR_X);
233  pnh_.param("axis_angular_position", axis_angular_position_, DEFAULT_AXIS_ANGULAR);
234  ROS_INFO("axis_linear_speed_ = %d, axis_angular = %d", axis_linear_speed_, axis_angular_position_);
235  ROS_INFO("max_linear_speed = %lf, max_angular_speed = %lf", max_linear_speed_, max_angular_position_);
236 
237  // DIGITAL OUTPUTS CONF
238  pnh_.param("cmd_service_io", cmd_service_io_, cmd_service_io_);
239  pnh_.param("output_1", output_1_, output_1_);
240  pnh_.param("output_2", output_2_, output_2_);
241  pnh_.param("topic_state", topic_state_, std::string("/rbcar_pad/state"));
242 
243  // PANTILT CONF
244  pnh_.param("cmd_service_ptz", cmd_service_ptz_, cmd_service_ptz_);
245  pnh_.param("button_ptz_tilt_up", ptz_tilt_up_, ptz_tilt_up_);
246  pnh_.param("button_ptz_tilt_down", ptz_tilt_down_, ptz_tilt_down_);
247  pnh_.param("button_ptz_pan_right", ptz_pan_right_, ptz_pan_right_);
248  pnh_.param("button_ptz_pan_left", ptz_pan_left_, ptz_pan_left_);
249 
250  ROS_INFO("RbcarPad num_of_buttons_ = %d, axes = %d, topic controller: %s, hz = %.2lf", num_of_buttons_, num_of_axes_,
251  cmd_topic_vel.c_str(), desired_freq_);
252 
253  for (int i = 0; i < MAX_NUM_OF_BUTTONS_PS3; i++)
254  {
255  Button b;
256  vButtons.push_back(b);
257  }
258 
259  for (int i = 0; i < MAX_NUM_OF_AXES_PS3; i++)
260  {
261  fAxes.push_back(0.0);
262  }
263 
264  // this->vel_pub_ = nh_.advertise<ackermann_msgs::AckermannDriveStamped>(this->cmd_topic_vel, 1);
265  this->vel_pub_ = nh_.advertise<geometry_msgs::Twist>(cmd_topic_vel, 1);
266 
267  // Listen through the node handle sensor_msgs::Joy messages from joystick
268  joy_sub_ = nh_.subscribe<sensor_msgs::Joy>(joy_topic_, 1, &RbcarPad::joyCallback, this);
269 
270  // Request service to activate / deactivate digital I/O
271  set_digital_outputs_client_ = nh_.serviceClient<robotnik_msgs::set_digital_output>(cmd_service_io_);
272 
273  bOutput1 = bOutput2 = false;
274 
275  // Diagnostics
276  updater_pad.setHardwareID("RbcarPad");
277  // Topics freq control
282 
284  cmd_topic_vel.c_str(), updater_pad,
286 
287  // Advertises new service to enable/disable the pad
289  //
290  bEnable = true; // Communication flag enabled by default
291 
292  // Info message
293  // ROS_INFO("A segfault after this line is usually caused either by bad definition of the pad yaml file or by
294  // incrorrect setting of the jsX device in the launch file");
295 }
296 
297 /*
298  * \brief Updates the diagnostic component. Diagnostics
299  * Publishes the state
300  *
301  */
303 {
304  PublishState();
305 }
306 
309 {
310  /*RbcarPad::rescuer_pad_state pad_state;
311 
312  pad_state.state = StateToString(iState);
313  pad_state.arm_mode = ModeToString(iArmMode);
314  pad_state.platform_mode = ModeToString(iPlatformMode);
315  pad_state.speed_level = current_speed_lvl;
316  pad_state.deadman_active = (bool) vButtons[button_dead_man_].IsPressed();
317 
318  state_pub_.publish(pad_state);*/
319 }
320 
321 /*
322  * \brief Enables/Disables the pad
323  */
324 bool RbcarPad::EnableDisable(robotnik_msgs::enable_disable::Request& req, robotnik_msgs::enable_disable::Response& res)
325 {
326  bEnable = req.value;
327 
328  ROS_INFO("RbcarPad::EnablaDisable: Setting to %d", req.value);
329  res.ret = true;
330  return true;
331 }
332 
333 void RbcarPad::joyCallback(const sensor_msgs::Joy::ConstPtr& joy)
334 {
335  // First joystick being saved
336  for (int i = 0; i < joy->axes.size(); i++)
337  {
338  this->fAxes[i] = joy->axes[i];
339  }
340  for (int i = 0; i < joy->buttons.size(); i++)
341  {
342  this->vButtons[i].Press(joy->buttons[i]);
343  }
344 
345  // ROS_INFO("RbcarPad::joyCallback: num_of_axes = %d, buttons = %d", (int)(joy->axes.size()),
346  // (int)(joy->buttons.size()));
347 }
348 
351 {
352  double desired_linear_speed = 0.0, desired_angular_position = 0.0;
353  ackermann_msgs::AckermannDriveStamped ref_msg;
354  geometry_msgs::Twist vel_msg;
355 
356  vel_msg.angular.x = 0.0;
357  vel_msg.angular.y = 0.0;
358  vel_msg.angular.z = 0.0;
359  vel_msg.linear.x = 0.0;
360  vel_msg.linear.y = 0.0;
361  vel_msg.linear.z = 0.0;
362 
364 
365  while (ros::ok())
366  {
367  Update();
368 
369  if (bEnable)
370  {
371  if (vButtons[button_dead_man_].IsPressed())
372  {
373  ref_msg.header.stamp = ros::Time::now();
374  ref_msg.drive.jerk = 0.0;
375  ref_msg.drive.acceleration = 0.0;
376  ref_msg.drive.steering_angle_velocity = 0.0;
377 
378  desired_linear_speed = max_linear_speed_ * current_speed_lvl * fAxes[axis_linear_speed_];
379  desired_angular_position = max_angular_position_ * fAxes[axis_angular_position_];
380 
381  // ROS_INFO("axis_angular_position_ %d desired_angular_position=%5.2f", axis_angular_position_,
382  // desired_angular_position);
383 
384  // ref_msg.drive.steering_angle = desired_angular_position;
385  // ref_msg.drive.speed = desired_linear_speed;
386  vel_msg.linear.x = desired_linear_speed;
387  vel_msg.angular.z = desired_angular_position;
388 
389  // Publish into command_vel topic
390  vel_pub_.publish(vel_msg);
391 
392  if (vButtons[button_speed_up_].IsReleased())
393  {
394  current_speed_lvl += 0.1;
395  if (current_speed_lvl > 1.0)
396  current_speed_lvl = 1.0;
397  }
398  if (vButtons[button_speed_down_].IsReleased())
399  {
400  current_speed_lvl -= 0.1;
401  if (current_speed_lvl < 0.0)
402  current_speed_lvl = 0.0;
403  }
404  }
405  else if (vButtons[button_dead_man_].IsReleased())
406  {
407  ref_msg.header.stamp = ros::Time::now();
408  ref_msg.drive.jerk = 0.0;
409  ref_msg.drive.acceleration = 0.0;
410  ref_msg.drive.steering_angle_velocity = 0.0;
411 
412  ref_msg.drive.steering_angle = 0.0;
413  ref_msg.drive.speed = 0.0;
414  vel_msg.linear.x = 0.0;
415  vel_msg.angular.z = 0.0;
416  // ROS_INFO("RbcarPad::ControlLoop: Deadman released!");
417  vel_pub_.publish(vel_msg); // Publish into command_vel topic
418  }
419  }
420 
421  ros::spinOnce();
422  r.sleep();
423  }
424 }
425 
427 int main(int argc, char** argv)
428 {
429  ros::init(argc, argv, "rbcar_pad");
430  RbcarPad joy;
431 
432  joy.ControlLoop();
433 }
int IsPressed()
Definition: rbcar_pad.cpp:96
#define DEFAULT_NUM_OF_AXES
Definition: rbcar_pad.cpp:61
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
diagnostic_updater::HeaderlessTopicDiagnostic * sus_joy_freq
Diagnostic to control the reception frequency of the subscribed joy topic.
Definition: rbcar_pad.cpp:192
#define DEFAULT_MAX_ANGULAR_POSITION
Definition: rbcar_pad.cpp:53
std::string cmd_topic_vel
Name of the topic where it will be publishing the velocity.
Definition: rbcar_pad.cpp:147
bool bOutput1
Definition: rbcar_pad.cpp:174
bool bOutput2
Definition: rbcar_pad.cpp:174
void publish(const boost::shared_ptr< M > &message) const
std::string joy_topic_
// Name of the joystick&#39;s topic
Definition: rbcar_pad.cpp:145
int ptz_tilt_up_
buttons to the pan-tilt camera
Definition: rbcar_pad.cpp:176
void ControlLoop()
Controls the actions and states.
Definition: rbcar_pad.cpp:350
int output_1_
Definition: rbcar_pad.cpp:173
int kinematic_mode_
kinematic mode
Definition: rbcar_pad.cpp:182
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
std::string topic_state_
topic name for the state
Definition: rbcar_pad.cpp:151
ros::NodeHandle pnh_
Definition: rbcar_pad.cpp:129
ros::Publisher state_pub_
Topic to publish the state.
Definition: rbcar_pad.cpp:153
void setHardwareID(const std::string &hwid)
bool IsReleased()
Definition: rbcar_pad.cpp:101
Class to save the state of the buttons.
Definition: rbcar_pad.cpp:72
ros::ServiceClient setKinematicMode
Service to modify the kinematic mode.
Definition: rbcar_pad.cpp:184
int ptz_pan_right_
Definition: rbcar_pad.cpp:176
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
ros::Subscriber joy_sub_
they will be suscribed to the joysticks
Definition: rbcar_pad.cpp:143
std::vector< Button > vButtons
Vector to save and control the axis values.
Definition: rbcar_pad.cpp:168
#define DEFAULT_NUM_OF_BUTTONS
Definition: rbcar_pad.cpp:60
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
std::string cmd_set_mode_
Name of the service to change the mode.
Definition: rbcar_pad.cpp:186
diagnostic_updater::Updater updater_pad
General status diagnostic updater.
Definition: rbcar_pad.cpp:194
bool bEnable
Flag to enable/disable the communication with the publishers topics.
Definition: rbcar_pad.cpp:200
double max_linear_speed_
Set the max speed sent to the robot.
Definition: rbcar_pad.cpp:135
Button()
Definition: rbcar_pad.cpp:78
int num_of_buttons_
Current number of buttons of the joystick.
Definition: rbcar_pad.cpp:162
int button_speed_up_
Number of the button for increase or decrease the speed max of the joystick.
Definition: rbcar_pad.cpp:172
ros::Publisher vel_pub_
It will publish into command velocity (for the robot)
Definition: rbcar_pad.cpp:141
double max_angular_position_
Definition: rbcar_pad.cpp:135
double max_freq_command
Diagnostics max freq.
Definition: rbcar_pad.cpp:198
double max_freq_joy
Definition: rbcar_pad.cpp:198
int output_2_
Definition: rbcar_pad.cpp:173
void Update()
Definition: rbcar_pad.cpp:302
void Press(int value)
Set the button as &#39;pressed&#39;/&#39;released&#39;.
Definition: rbcar_pad.cpp:84
int axis_angular_position_
Definition: rbcar_pad.cpp:131
int axis_linear_speed_
Definition: rbcar_pad.cpp:131
double current_speed_lvl
Definition: rbcar_pad.cpp:133
double min_freq_command
Diagnostics min freq.
Definition: rbcar_pad.cpp:196
int button_dead_man_
Number of the DEADMAN button.
Definition: rbcar_pad.cpp:170
int button_kinematic_mode_
button to change kinematic mode
Definition: rbcar_pad.cpp:180
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
int iPressed
Definition: rbcar_pad.cpp:74
bool bReleased
Definition: rbcar_pad.cpp:75
int num_of_axes_
Definition: rbcar_pad.cpp:163
ROSCPP_DECL bool ok()
#define MAX_NUM_OF_AXES_PS3
Definition: rbcar_pad.cpp:58
#define DEFAULT_MAX_LINEAR_SPEED
Definition: rbcar_pad.cpp:52
int ptz_tilt_down_
Definition: rbcar_pad.cpp:176
double l_scale_
Definition: rbcar_pad.cpp:132
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
int main(int argc, char **argv)
Definition: rbcar_pad.cpp:427
int button_speed_down_
Definition: rbcar_pad.cpp:172
bool sleep()
std::string cmd_service_io_
Name of the service where it will be modifying the digital outputs.
Definition: rbcar_pad.cpp:149
ros::ServiceClient set_digital_outputs_client_
Definition: rbcar_pad.cpp:158
double min_freq_joy
Definition: rbcar_pad.cpp:196
#define MAX_NUM_OF_BUTTONS
Definition: rbcar_pad.cpp:55
int ptz_pan_left_
Definition: rbcar_pad.cpp:176
#define MAX_NUM_OF_AXES
Definition: rbcar_pad.cpp:56
std::string cmd_service_ptz_
Name of the service to move ptz.
Definition: rbcar_pad.cpp:178
#define DEFAULT_AXIS_ANGULAR
Definition: rbcar_pad.cpp:64
double desired_freq_
Desired component&#39;s freq.
Definition: rbcar_pad.cpp:137
void PublishState()
Definition: rbcar_pad.cpp:308
static Time now()
#define DEFAULT_AXIS_LINEAR_X
Definition: rbcar_pad.cpp:63
#define MAX_NUM_OF_BUTTONS_PS3
Definition: rbcar_pad.cpp:57
ros::ServiceServer enable_disable_srv_
Service clients.
Definition: rbcar_pad.cpp:157
#define DEFAULT_HZ
Definition: rbcar_pad.cpp:69
#define DEFAULT_JOY
Definition: rbcar_pad.cpp:68
ROSCPP_DECL void spinOnce()
ros::NodeHandle nh_
Definition: rbcar_pad.cpp:129
bool EnableDisable(robotnik_msgs::enable_disable::Request &req, robotnik_msgs::enable_disable::Response &res)
Enables/Disables the joystick.
Definition: rbcar_pad.cpp:324
void joyCallback(const sensor_msgs::Joy::ConstPtr &joy)
Definition: rbcar_pad.cpp:333
std::vector< float > fAxes
Vector to save the axis values.
Definition: rbcar_pad.cpp:166
diagnostic_updater::HeaderlessTopicDiagnostic * pub_command_freq
Diagnostic to control the frequency of the published command velocity topic.
Definition: rbcar_pad.cpp:190


rbcar_pad
Author(s): Román Navarro
autogenerated on Wed Jun 17 2020 04:17:48