00001
00002 #include <ros/ros.h>
00003 #include <std_msgs/Float64.h>
00004 #include <std_msgs/Float32.h>
00005 #include <std_srvs/Empty.h>
00006 #include <std_msgs/Empty.h>
00007 #include <std_msgs/Int32.h>
00008 #include <std_msgs/MultiArrayLayout.h>
00009 #include <std_msgs/MultiArrayDimension.h>
00010 #include <std_msgs/Int32MultiArray.h>
00011 #include <std_msgs/Float32MultiArray.h>
00012 #include <std_msgs/Bool.h>
00013
00014 #include <nav_msgs/Odometry.h>
00015 #include <sensor_msgs/Range.h>
00016
00017
00018 #include <controller_manager/controller_manager.h>
00019 #include <hardware_interface/joint_command_interface.h>
00020 #include <hardware_interface/joint_state_interface.h>
00021 #include <hardware_interface/imu_sensor_interface.h>
00022 #include <hardware_interface/robot_hw.h>
00023 #include <realtime_tools/realtime_buffer.h>
00024
00025
00026 #include <limits>
00027
00028
00029 #include <sstream>
00030
00031 #include <mrp2_hardware/mrp2_serial.h>
00032
00033 #include <dynamic_reconfigure/server.h>
00034 #include <mrp2_hardware/ParametersConfig.h>
00035
00036 class MRP2HW : public hardware_interface::RobotHW
00037 {
00038 public:
00039 MRP2HW()
00040 : running_(true)
00041 , start_srv_(nh_.advertiseService("start", &MRP2HW::start_callback, this))
00042 , stop_srv_(nh_.advertiseService("stop", &MRP2HW::stop_callback, this))
00043 {
00044
00045 pos_[0] = 0.0; pos_[1] = 0.0;
00046 vel_[0] = 0.0; vel_[1] = 0.0;
00047 eff_[0] = 0.0; eff_[1] = 0.0;
00048 cmd_[0] = 0.0; cmd_[1] = 0.0;
00049
00050 hardware_interface::JointStateHandle state_handle_1("wheel_right_joint", &pos_[0], &vel_[0], &eff_[0]);
00051 jnt_state_interface_.registerHandle(state_handle_1);
00052
00053 hardware_interface::JointStateHandle state_handle_2("wheel_left_joint", &pos_[1], &vel_[1], &eff_[1]);
00054 jnt_state_interface_.registerHandle(state_handle_2);
00055
00056 registerInterface(&jnt_state_interface_);
00057
00058 hardware_interface::JointHandle vel_handle_1(jnt_state_interface_.getHandle("wheel_right_joint"), &cmd_[0]);
00059 jnt_vel_interface_.registerHandle(vel_handle_1);
00060
00061 hardware_interface::JointHandle vel_handle_2(jnt_state_interface_.getHandle("wheel_left_joint"), &cmd_[1]);
00062 jnt_vel_interface_.registerHandle(vel_handle_2);
00063
00064 registerInterface(&jnt_vel_interface_);
00065
00066
00067
00068
00069
00070
00071
00072 sym_tuning = false;
00073 publish_pos = false;
00074 publish_ref = false;
00075 publish_feed = false;
00076
00077
00078
00079 f = boost::bind(&MRP2HW::callback, this, _1, _2);
00080 server.setCallback(f);
00081
00082 pos_reset_sub = nh_.subscribe<std_msgs::Empty>("positions_reset", 1, &MRP2HW::positions_reset_callback, this);
00083 estop_clear_sub = nh_.subscribe<std_msgs::Empty>("estop_clear", 1, &MRP2HW::estop_clear_callback, this);
00084
00085 sep_cmd_vel_pub = nh_.advertise<std_msgs::Float32MultiArray>("motor_controller/sep_cmd_vel", 100);
00086
00087 bumpers_pub = nh_.advertise<std_msgs::Int32MultiArray>("bumpers", 100);
00088 estop_pub = nh_.advertise<std_msgs::Bool>("estop", 100);
00089 estop_btn_pub = nh_.advertise<std_msgs::Bool>("estop_btn", 100);
00090 motor_stall_l_pub = nh_.advertise<std_msgs::Bool>("hw_monitor/diagnostics/motor_stall_l", 100);
00091 motor_stall_r_pub = nh_.advertise<std_msgs::Bool>("hw_monitor/diagnostics/motor_stall_r", 100);
00092 batt_low_pub = nh_.advertise<std_msgs::Bool>("hw_monitor/diagnostics/batt_low", 100);
00093 batt_high_pub = nh_.advertise<std_msgs::Bool>("hw_monitor/diagnostics/batt_high", 100);
00094 controller_pub = nh_.advertise<std_msgs::Bool>("hw_monitor/diagnostics/controller", 100);
00095 aux_lights_pub = nh_.advertise<std_msgs::Bool>("hw_monitor/diagnostics/aux_lights", 100);
00096
00097
00098 robot_serial = new MRP2_Serial("/dev/mrp2_powerboard", 921600, "8N1");
00099
00100 robot_serial->update();
00101
00102 bumper_states.resize(4);
00103 bumper_states = robot_serial->get_bumpers();
00104
00105
00106 std::vector<int> imax ;
00107
00108
00109
00110
00111
00112
00113
00114
00115 init_config.BUMPER_ESTOP = robot_serial->get_bumper_estop(true);
00116
00117
00118
00119
00120 server.updateConfig(init_config);
00121
00122
00123 estop_state = robot_serial->get_estop(true);
00124 estop_release = false;
00125 robot_serial->reset_positions();
00126 robot_serial->clear_diag(0);
00127
00128 current_time = ros::Time::now();
00129 last_time = ros::Time::now();
00130 pos_left = 0;
00131 pos_right = 0;
00132
00133 }
00134
00135 ros::Time getTime() const {return ros::Time::now();}
00136 ros::Duration getPeriod() const {return ros::Duration(0.01);}
00137
00138 bool estop_release;
00139
00140 void read()
00141 {
00142 std_msgs::Int32MultiArray array32;
00143 std_msgs::Bool b;
00144 std_msgs::Int32 i;
00145 std_msgs::Float32 f;
00146
00147 current_time = ros::Time::now();
00148
00149 bumper_states = robot_serial->get_bumpers(true);
00150
00151
00152 long last_pos_l=0, now_pos_l=0;
00153 long last_pos_r=0, now_pos_r=0;
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 double dt = (current_time - last_time).toSec();
00167 last_time = current_time;
00168
00169 double qpps_l, qpps_r;
00170 qpps_l = robot_serial->get_speed_l(true);
00171 qpps_r = robot_serial->get_speed_r(true);
00172
00173
00174 double speed_l = (qpps_l/(21600.0))*2*M_PI;
00175 double speed_r = (qpps_r/(21600.0))*2*M_PI;
00176
00177 vel_[0] = speed_r;
00178 vel_[1] = speed_l;
00179
00180 pos_left += speed_l*dt;
00181 pos_right += speed_r*dt;
00182
00183
00184
00185 pos_[0] = pos_right;
00186 pos_[1] = pos_left;
00187
00188 array32.data.clear();
00189 array32.data.push_back(bumper_states[2]);
00190 array32.data.push_back(bumper_states[3]);
00191 array32.data.push_back(bumper_states[0]);
00192 array32.data.push_back(bumper_states[1]);
00193 bumpers_pub.publish(array32);
00194
00195 estop_state = robot_serial->get_estop(false);
00196 if(estop_state == true)
00197 {
00198 estop_state = robot_serial->get_estop(true);
00199 if(estop_state == false)
00200 estop_release = true;
00201 }else{
00202 estop_state = robot_serial->get_estop(true);
00203 }
00204
00205 b.data = estop_state;
00206 estop_pub.publish(b);
00207
00208 bool estop_button = robot_serial->get_estop_button(true);
00209 b.data = estop_button;
00210 estop_btn_pub.publish(b);
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 }
00233
00234 void write()
00235 {
00236
00237 std_msgs::Float32MultiArray spd_array;
00238 spd_array.data.clear();
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 if(estop_state)
00258 {
00259 spd_array.data.push_back(0);
00260 spd_array.data.push_back(0);
00261 }else{
00262 spd_array.data.push_back(cmd_[0]*60*15/(2*M_PI));
00263 spd_array.data.push_back(cmd_[1]*60*15/(2*M_PI));
00264 }
00265
00266 sep_cmd_vel_pub.publish(spd_array);
00267
00268 }
00269
00270 bool start_callback(std_srvs::Empty::Request& req, std_srvs::Empty::Response& res)
00271 {
00272 running_ = true;
00273 return true;
00274 }
00275
00276 bool stop_callback(std_srvs::Empty::Request& req, std_srvs::Empty::Response& res)
00277 {
00278 running_ = false;
00279 return true;
00280 }
00281
00282 void positions_reset_callback(const std_msgs::Empty::ConstPtr& msg)
00283 {
00284 ROS_WARN("Positions reset.");
00285 robot_serial->reset_positions();
00286 }
00287
00288 void estop_clear_callback(const std_msgs::Empty::ConstPtr& msg)
00289 {
00290 ROS_WARN("Estop is cleared.");
00291 robot_serial->set_estop(0);
00292 }
00293
00294 void callback(mrp2_hardware::ParametersConfig &config, uint32_t level)
00295 {
00296 switch (level)
00297 {
00298 case MRP2_Serial::setBUMPER_ESTOP:
00299 robot_serial->set_bumper_estop(config.BUMPER_ESTOP);
00300 break;
00301 }
00302
00303
00304 }
00305
00306
00307 private:
00308 hardware_interface::JointStateInterface jnt_state_interface_;
00309 hardware_interface::VelocityJointInterface jnt_vel_interface_;
00310 hardware_interface::ImuSensorInterface imu_sens_interface_;
00311 double cmd_[2];
00312 double pos_[2];
00313 double vel_[2];
00314 double eff_[2];
00315 bool running_;
00316
00317 bool sym_tuning, publish_pos, publish_ref, publish_feed;
00318 bool estop_state;
00319
00320 double pos_left, pos_right;
00321
00322
00323 MRP2_Serial *robot_serial;
00324 std::vector<int> bumper_states, speeds, diags;
00325
00326 ros::NodeHandle nh_;
00327 ros::ServiceServer start_srv_;
00328 ros::ServiceServer stop_srv_;
00329
00330 ros::Publisher bumpers_pub;
00331
00332 ros::Publisher estop_pub;
00333 ros::Publisher estop_btn_pub;
00334 ros::Publisher motor_stall_l_pub;
00335 ros::Publisher motor_stall_r_pub;
00336 ros::Publisher batt_low_pub;
00337 ros::Publisher batt_high_pub;
00338 ros::Publisher controller_pub;
00339 ros::Publisher aux_lights_pub;
00340
00341 ros::Publisher sep_cmd_vel_pub;
00342
00343 ros::Subscriber pos_reset_sub;
00344 ros::Subscriber estop_clear_sub;
00345
00346 ros::Time current_time, last_time;
00347
00348 dynamic_reconfigure::Server<mrp2_hardware::ParametersConfig> server;
00349 dynamic_reconfigure::Server<mrp2_hardware::ParametersConfig>::CallbackType f;
00350 boost::recursive_mutex dynamic_reconfigure_mutex_;
00351 boost::mutex connect_mutex_;
00352
00353 mrp2_hardware::ParametersConfig init_config;
00354
00355 double _ftod(float fValue)
00356 {
00357 char cz_dummy[30];
00358 sprintf(cz_dummy,"%9.5f",fValue);
00359 double dValue = strtod(cz_dummy,NULL);
00360 return dValue;
00361 }
00362
00363 };