00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <ros/ros.h>
00035 #include <sensor_msgs/Joy.h>
00036 #include <geometry_msgs/Twist.h>
00037 #include <std_msgs/Int32.h>
00038 #include <unistd.h>
00039 #include <vector>
00040 #include <robotnik_msgs/enable_disable.h>
00041 #include <robotnik_msgs/set_digital_output.h>
00042 #include "diagnostic_msgs/DiagnosticStatus.h"
00043 #include "diagnostic_updater/diagnostic_updater.h"
00044 #include "diagnostic_updater/update_functions.h"
00045 #include "diagnostic_updater/DiagnosticStatusWrapper.h"
00046 #include "diagnostic_updater/publisher.h"
00047 #include "ackermann_msgs/AckermannDriveStamped.h"
00048 #include <std_srvs/Empty.h>
00049 #include "robotnik_msgs/set_mode.h"
00050 #include "robotnik_msgs/get_mode.h"
00051
00052 #define DEFAULT_MAX_LINEAR_SPEED 3.0 //m/s
00053 #define DEFAULT_MAX_ANGULAR_POSITION 0.5 // rads/s
00054
00055 #define MAX_NUM_OF_BUTTONS 16
00056 #define MAX_NUM_OF_AXES 8
00057 #define MAX_NUM_OF_BUTTONS_PS3 19
00058 #define MAX_NUM_OF_AXES_PS3 20
00059
00060 #define DEFAULT_NUM_OF_BUTTONS 16
00061 #define DEFAULT_NUM_OF_AXES 8
00062
00063 #define DEFAULT_AXIS_LINEAR_X 1
00064 #define DEFAULT_AXIS_ANGULAR 2
00065 #define DEFAULT_SCALE_LINEAR 1.0
00066 #define DEFAULT_SCALE_ANGULAR 1.0
00067
00068 #define DEFAULT_JOY "/joy"
00069 #define DEFAULT_HZ 50.0
00070
00071
00073 class Button{
00074 int iPressed;
00075 bool bReleased;
00076
00077 public:
00078
00079 Button(){
00080 iPressed = 0;
00081 bReleased = false;
00082 }
00084 void Press(int value){
00085 if(iPressed and !value){
00086 bReleased = true;
00087
00088 }else if(bReleased and value)
00089 bReleased = false;
00090
00091 iPressed = value;
00092
00093 }
00094
00095 int IsPressed(){
00096 return iPressed;
00097 }
00098
00099 bool IsReleased(){
00100 bool b = bReleased;
00101 bReleased = false;
00102 return b;
00103 }
00104 };
00105
00106 class RbcarPad
00107 {
00108 public:
00109 RbcarPad();
00110
00111 void ControlLoop();
00112 int SetStateMode(int state, int arm_mode, int platform_mode);
00113
00114 private:
00115
00116 void joyCallback(const sensor_msgs::Joy::ConstPtr& joy);
00117
00118 char * StateToString(int state);
00119 int SwitchToState(int new_state);
00120
00121 void PublishState();
00123 bool EnableDisable(robotnik_msgs::enable_disable::Request &req, robotnik_msgs::enable_disable::Response &res );
00124 void Update();
00125
00126
00127 private:
00128 ros::NodeHandle nh_, pnh_;
00129
00130 int axis_linear_speed_, axis_angular_position_;
00131 double l_scale_, a_scale_;
00132 double current_speed_lvl;
00134 double max_linear_speed_, max_angular_position_;
00136 double desired_freq_;
00137
00138
00140 ros::Publisher vel_pub_;
00142 ros::Subscriber joy_sub_;
00144 std::string joy_topic_;
00146 std::string cmd_topic_vel;
00148 std::string cmd_service_io_;
00150 std::string topic_state_;
00152 ros::Publisher state_pub_;
00153
00154
00156 ros::ServiceServer enable_disable_srv_;
00157 ros::ServiceClient set_digital_outputs_client_;
00158
00159
00161 int num_of_buttons_;
00162 int num_of_axes_;
00163
00165 std::vector<float> fAxes;
00167 std::vector<Button> vButtons;
00169 int button_dead_man_;
00171 int button_speed_up_, button_speed_down_;
00172 int output_1_, output_2_;
00173 bool bOutput1, bOutput2;
00175 int ptz_tilt_up_, ptz_tilt_down_, ptz_pan_right_, ptz_pan_left_;
00177 std::string cmd_service_ptz_;
00179 int button_kinematic_mode_;
00181 int kinematic_mode_;
00183 ros::ServiceClient setKinematicMode;
00185 std::string cmd_set_mode_;
00186
00187
00189 diagnostic_updater::HeaderlessTopicDiagnostic *pub_command_freq;
00191 diagnostic_updater::HeaderlessTopicDiagnostic *sus_joy_freq;
00193 diagnostic_updater::Updater updater_pad;
00195 double min_freq_command, min_freq_joy;
00197 double max_freq_command, max_freq_joy;
00199 bool bEnable;
00200 };
00201
00202 RbcarPad::RbcarPad():
00203 axis_linear_speed_(1),
00204 axis_angular_position_(2),
00205 pnh_("~")
00206 {
00207 current_speed_lvl = 0.1;
00208
00209 pnh_.param("num_of_buttons", num_of_buttons_, DEFAULT_NUM_OF_BUTTONS);
00210 pnh_.param("num_of_axes", num_of_axes_, DEFAULT_NUM_OF_AXES);
00211 pnh_.param("desired_freq", desired_freq_, DEFAULT_HZ);
00212
00213 if(num_of_axes_ > MAX_NUM_OF_AXES){
00214 num_of_axes_ = MAX_NUM_OF_AXES;
00215 ROS_INFO("RbcarPad::RbcarPad: Limiting the max number of axes to %d", MAX_NUM_OF_AXES);
00216 }
00217 if(num_of_buttons_ > MAX_NUM_OF_BUTTONS){
00218 num_of_buttons_ = MAX_NUM_OF_BUTTONS;
00219 ROS_INFO("RbcarPad::RbcarPad: Limiting the max number of buttons to %d", MAX_NUM_OF_BUTTONS);
00220 }
00221
00222 pnh_.param("topic_joy", joy_topic_, std::string(DEFAULT_JOY));
00223
00224
00225
00226 pnh_.param("cmd_topic_vel", cmd_topic_vel, std::string("/rbcar_robot_control/command"));
00227
00228 pnh_.param("button_dead_man", button_dead_man_, button_dead_man_);
00229 pnh_.param("button_speed_up", button_speed_up_, button_speed_up_);
00230 pnh_.param("button_speed_down", button_speed_down_, button_speed_down_);
00231 pnh_.param("max_angular_position", max_angular_position_, DEFAULT_MAX_ANGULAR_POSITION);
00232 pnh_.param("max_linear_speed_", max_linear_speed_, DEFAULT_MAX_LINEAR_SPEED);
00233 pnh_.param("axis_linear_speed", axis_linear_speed_, DEFAULT_AXIS_LINEAR_X);
00234 pnh_.param("axis_angular_position", axis_angular_position_, DEFAULT_AXIS_ANGULAR);
00235 ROS_INFO("axis_linear_speed_ = %d, axis_angular = %d", axis_linear_speed_, axis_angular_position_);
00236 ROS_INFO("max_linear_speed = %lf, max_angular_speed = %lf", max_linear_speed_, max_angular_position_);
00237
00238
00239 pnh_.param("cmd_service_io", cmd_service_io_, cmd_service_io_);
00240 pnh_.param("output_1", output_1_, output_1_);
00241 pnh_.param("output_2", output_2_, output_2_);
00242 pnh_.param("topic_state", topic_state_, std::string("/rbcar_pad/state"));
00243
00244
00245 pnh_.param("cmd_service_ptz", cmd_service_ptz_, cmd_service_ptz_);
00246 pnh_.param("button_ptz_tilt_up", ptz_tilt_up_, ptz_tilt_up_);
00247 pnh_.param("button_ptz_tilt_down", ptz_tilt_down_, ptz_tilt_down_);
00248 pnh_.param("button_ptz_pan_right", ptz_pan_right_, ptz_pan_right_);
00249 pnh_.param("button_ptz_pan_left", ptz_pan_left_, ptz_pan_left_);
00250
00251
00252 ROS_INFO("RbcarPad num_of_buttons_ = %d, axes = %d, topic controller: %s, hz = %.2lf", num_of_buttons_, num_of_axes_, cmd_topic_vel.c_str(), desired_freq_);
00253
00254 for(int i = 0; i < MAX_NUM_OF_BUTTONS_PS3; i++){
00255 Button b;
00256 vButtons.push_back(b);
00257 }
00258
00259 for(int i = 0; i < MAX_NUM_OF_AXES_PS3; i++){
00260 fAxes.push_back(0.0);
00261 }
00262
00263
00264 this->vel_pub_ = nh_.advertise<ackermann_msgs::AckermannDriveStamped>(this->cmd_topic_vel, 1);
00265
00266
00267 joy_sub_ = nh_.subscribe<sensor_msgs::Joy>(joy_topic_, 1, &RbcarPad::joyCallback, this);
00268
00269
00270 set_digital_outputs_client_ = nh_.serviceClient<robotnik_msgs::set_digital_output>(cmd_service_io_);
00271
00272 bOutput1 = bOutput2 = false;
00273
00274
00275 updater_pad.setHardwareID("RbcarPad");
00276
00277 min_freq_command = min_freq_joy = 5.0;
00278 max_freq_command = max_freq_joy = 50.0;
00279 sus_joy_freq = new diagnostic_updater::HeaderlessTopicDiagnostic("/joy", updater_pad,
00280 diagnostic_updater::FrequencyStatusParam(&min_freq_joy, &max_freq_joy, 0.1, 10));
00281
00282 pub_command_freq = new diagnostic_updater::HeaderlessTopicDiagnostic(cmd_topic_vel.c_str(), updater_pad,
00283 diagnostic_updater::FrequencyStatusParam(&min_freq_command, &max_freq_command, 0.1, 10));
00284
00285
00286 enable_disable_srv_ = pnh_.advertiseService("enable_disable", &RbcarPad::EnableDisable, this);
00287
00288 bEnable = true;
00289
00290
00291
00292 }
00293
00294
00295
00296
00297
00298
00299 void RbcarPad::Update(){
00300 PublishState();
00301 }
00302
00304 void RbcarPad::PublishState(){
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 }
00315
00316
00317
00318
00319 bool RbcarPad::EnableDisable(robotnik_msgs::enable_disable::Request &req, robotnik_msgs::enable_disable::Response &res )
00320 {
00321 bEnable = req.value;
00322
00323 ROS_INFO("RbcarPad::EnablaDisable: Setting to %d", req.value);
00324 res.ret = true;
00325 return true;
00326 }
00327
00328 void RbcarPad::joyCallback(const sensor_msgs::Joy::ConstPtr& joy)
00329 {
00330
00331
00332 for(int i = 0; i < joy->axes.size(); i++){
00333 this->fAxes[i] = joy->axes[i];
00334 }
00335 for(int i = 0; i < joy->buttons.size(); i++){
00336 this->vButtons[i].Press(joy->buttons[i]);
00337 }
00338
00339
00340 }
00341
00343 void RbcarPad::ControlLoop(){
00344
00345 double desired_linear_speed = 0.0, desired_angular_position = 0.0;
00346 ackermann_msgs::AckermannDriveStamped ref_msg;
00347
00348 ros::Rate r(desired_freq_);
00349
00350 while(ros::ok()) {
00351
00352 Update();
00353
00354 if(bEnable){
00355
00356 if(vButtons[button_dead_man_].IsPressed()){
00357 ref_msg.header.stamp = ros::Time::now();
00358 ref_msg.drive.jerk = 0.0;
00359 ref_msg.drive.acceleration = 0.0;
00360 ref_msg.drive.steering_angle_velocity = 0.0;
00361
00362 desired_linear_speed = max_linear_speed_ * current_speed_lvl * fAxes[axis_linear_speed_];
00363 desired_angular_position = max_angular_position_ * fAxes[axis_angular_position_];
00364
00365
00366
00367 ref_msg.drive.steering_angle = desired_angular_position;
00368 ref_msg.drive.speed = desired_linear_speed;
00369
00370
00371 vel_pub_.publish(ref_msg);
00372
00373 if(vButtons[button_speed_up_].IsReleased()){
00374 current_speed_lvl += 0.1;
00375 if(current_speed_lvl > 1.0)
00376 current_speed_lvl = 1.0;
00377 }
00378 if(vButtons[button_speed_down_].IsReleased()){
00379 current_speed_lvl -= 0.1;
00380 if(current_speed_lvl < 0.0)
00381 current_speed_lvl = 0.0;
00382 }
00383
00384 }else if(vButtons[button_dead_man_].IsReleased()){
00385 ref_msg.header.stamp = ros::Time::now();
00386 ref_msg.drive.jerk = 0.0;
00387 ref_msg.drive.acceleration = 0.0;
00388 ref_msg.drive.steering_angle_velocity = 0.0;
00389
00390 ref_msg.drive.steering_angle = 0.0;
00391 ref_msg.drive.speed = 0.0;
00392
00393 vel_pub_.publish(ref_msg);
00394 }
00395 }
00396
00397 ros::spinOnce();
00398 r.sleep();
00399 }
00400 }
00401
00403 int main(int argc, char** argv)
00404 {
00405 ros::init(argc, argv, "rbcar_pad");
00406 RbcarPad joy;
00407
00408 joy.ControlLoop();
00409
00410 }
00411
00412