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 #include "skin_demo_movebase/skin_demo_movebase.h"
00034
00036
00040 SkinDemoMovebase::SkinDemoMovebase()
00041 : buf_command_ (10, geometry_msgs::Twist())
00042 {
00043
00044 nh_private_ = ros::NodeHandle("~");
00045
00046
00047 loadParameterInt(nh_private_, std::string("num_sensors"), num_sensors_);
00048
00049 loadParameterIntArray(nh_private_, std::string("mapping/fw"), patches_fw_);
00050 loadParameterIntArray(nh_private_, std::string("mapping/bw"), patches_bw_);
00051 loadParameterIntArray(nh_private_, std::string("mapping/right"), patches_right_);
00052 loadParameterIntArray(nh_private_, std::string("mapping/left"), patches_left_);
00053 loadParameterIntArray(nh_private_, std::string("mapping/yawright"), patches_yawright_);
00054 loadParameterIntArray(nh_private_, std::string("mapping/yawleft"), patches_yawleft_);
00055
00056
00057 sub_skin_data_ = nh_.subscribe("skin_data", 1, &SkinDemoMovebase::skinNewMeasCallback, this);
00058 pub_cmd_vel_ = nh_.advertise<geometry_msgs::Twist>("/base_controller/command", 1);
00059 }
00060
00062 SkinDemoMovebase::~SkinDemoMovebase() {
00063
00064 }
00065
00067
00073 void SkinDemoMovebase::skinNewMeasCallback(const boost::shared_ptr<skin_driver::skin_meas const>& msg) {
00074
00075 if (num_sensors_ != (int)msg->sensor_number_msg)
00076 ROS_WARN("Number of sensors configured to '%i' but received measurement from '%i' sensors.", num_sensors_, (int)msg->sensor_number_msg);
00077
00078
00079
00080
00081
00082 std::vector<sensor_data_struct> sensor_data(num_sensors_);
00083
00084
00085 for(int i = 0; i < num_sensors_; i++)
00086 {
00087 sensor_data[i].stat = ((255) & (msg->sensor_data_msg[i] >> (8*0)));
00088 sensor_data[i].x = ((255) & (msg->sensor_data_msg[i] >> (8*1)));
00089 sensor_data[i].ini = ((255) & (msg->sensor_data_msg[i] >> (8*2)));
00090 sensor_data[i].limit = ((255) & (msg->sensor_data_msg[i] >> (8*3)));
00091 sensor_data[i].u1 = ((255) & (msg->sensor_data_msg[i] >> (8*4)));
00092 sensor_data[i].u2 = ((255) & (msg->sensor_data_msg[i] >> (8*5)));
00093 sensor_data[i].u3 = ((255) & (msg->sensor_data_msg[i] >> (8*6)));
00094 sensor_data[i].dyn = ((255) & (msg->sensor_data_msg[i] >> (8*7)));
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 std::vector<int>::iterator it;
00112 double drive_fw = 0, drive_left = 0, drive_right = 0, drive_bw = 0;
00113 double yaw_right = 0, yaw_left = 0;
00114
00115 it = patches_fw_.begin();
00116 while (it != patches_fw_.end()) {
00117 drive_fw = std::max(drive_fw, (double)abs(sensor_data[*it].x - sensor_data[*it].ini));
00118 ++it;
00119
00120 }
00121
00122 it = patches_bw_.begin();
00123 while (it != patches_bw_.end()) {
00124 drive_bw = std::max(drive_bw, (double)abs(sensor_data[*it].x - sensor_data[*it].ini));
00125 ++it;
00126
00127 }
00128
00129 it = patches_right_.begin();
00130 while (it != patches_right_.end()) {
00131 drive_right = std::max(drive_right, (double)abs(sensor_data[*it].x - sensor_data[*it].ini));
00132 ++it;
00133
00134 }
00135
00136 it = patches_left_.begin();
00137 while (it != patches_left_.end()) {
00138 drive_left = std::max(drive_left, (double)abs(sensor_data[*it].x - sensor_data[*it].ini));
00139 ++it;
00140
00141 }
00142
00143 it = patches_yawleft_.begin();
00144 while (it != patches_yawleft_.end()) {
00145 yaw_left = std::max(yaw_left, (double)abs(sensor_data[*it].x - sensor_data[*it].ini));
00146 ++it;
00147
00148 }
00149
00150 it = patches_yawright_.begin();
00151 while (it != patches_yawright_.end()) {
00152 yaw_right = std::max(yaw_right, (double)abs(sensor_data[*it].x - sensor_data[*it].ini));
00153 ++it;
00154
00155 }
00156
00157
00158
00159
00160
00161
00162 double vel_fw = 0.20 * (((double)drive_fw -5) / 50);
00163 double vel_bw = 0.20 * (((double)drive_bw -5) / 50);
00164 double vel_right = 0.20 * (((double)drive_right -5) / 50);
00165 double vel_left = 0.20 * (((double)drive_left -5) / 50);
00166 double vel_yawleft = 0.20 * (((double)yaw_left -5) / 50);
00167 double vel_yawright = 0.20 * (((double)yaw_right -5) / 50);
00168
00169
00170 vel_fw = std::min(std::max(vel_fw, 0.0), 0.25);
00171 vel_bw = std::min(std::max(vel_bw, 0.0), 0.25);
00172 vel_right = std::min(std::max(vel_right, 0.0), 0.25);
00173 vel_left = std::min(std::max(vel_left, 0.0), 0.25);
00174 vel_yawleft = std::min(std::max(vel_yawleft, 0.0), 0.25);
00175 vel_yawright = std::min(std::max(vel_yawright, 0.0), 0.25);
00176
00177
00178
00179
00180
00181 geometry_msgs::Twist base_cmd;
00182 base_cmd.linear.x = base_cmd.linear.y = base_cmd.angular.z = 0;
00183
00184
00185
00186 int action_thresh = 5;
00187
00188 bool new_command = false;
00189
00190
00191 if (drive_bw > action_thresh)
00192 {
00193 ROS_INFO("MOVE: back, vel: %.2f raw sensor value abs(x-ini): %f,", vel_bw, drive_bw);
00194 base_cmd.linear.x = -vel_bw;
00195 new_command = true;
00196 }
00197
00198
00199 if (drive_fw > action_thresh)
00200 {
00201 ROS_INFO("MOVE: forward, vel: %.2f, raw sensor value abs(x-ini): %f", vel_fw, drive_fw);
00202 base_cmd.linear.x = vel_fw;
00203 new_command = true;
00204 }
00205
00206
00207 if (drive_left > action_thresh)
00208 {
00209 ROS_INFO("MOVE: left, vel: %.2f, raw sensor value abs(x-ini): %f", vel_left, drive_left);
00210 base_cmd.linear.y = vel_left;
00211 new_command = true;
00212 }
00213
00214
00215 if (drive_right > action_thresh)
00216 {
00217 ROS_INFO("MOVE: right, vel: %.2f, raw sensor value abs(x-ini): %f", vel_right, drive_right);
00218 base_cmd.linear.y = -vel_right;
00219 new_command = true;
00220 }
00221
00222
00223 if (yaw_right > action_thresh)
00224 {
00225 ROS_INFO("TRUN: right, vel: %.2f, raw sensor value abs(x-ini): %f", vel_yawright, yaw_right);
00226 base_cmd.angular.z = -vel_yawright;
00227 new_command = true;
00228 }
00229
00230
00231 if (yaw_left > action_thresh)
00232 {
00233 ROS_INFO("TRUN: left, vel: %.2f, raw sensor value abs(x-ini): %f", vel_yawleft, yaw_left);
00234 base_cmd.angular.z = vel_yawleft;
00235 new_command = true;
00236 }
00237
00238
00239
00240
00241
00242 if (new_command) {
00243 for (int c = 0; c < 4; c++)
00244 {
00245 buf_command_.push_front(base_cmd);
00246 }
00247 }
00248 }
00249
00251
00255 void SkinDemoMovebase::publishBaseCommand() {
00256 ros::Rate loop_rate(20);
00257 geometry_msgs::Twist base_cmd;
00258
00259
00260 buf_command_.clear();
00261
00262 while (ros::ok()) {
00263
00264 if (! buf_command_.empty()) {
00265
00266 base_cmd = buf_command_.front();
00267 buf_command_.pop_front();
00268 }
00269 else {
00270
00271 base_cmd.linear.x = 0;
00272 base_cmd.linear.y = 0;
00273 base_cmd.linear.z = 0;
00274 base_cmd.angular.x = 0;
00275 base_cmd.angular.y = 0;
00276 base_cmd.angular.z = 0;
00277 }
00278
00279
00280 pub_cmd_vel_.publish(base_cmd);
00281
00282
00283 ros::spinOnce();
00284 loop_rate.sleep();
00285 }
00286 }
00287
00289
00296 void SkinDemoMovebase::loadParameterInt(ros::NodeHandle & nh_, std::string param, int & data)
00297 {
00298 bool param_available = nh_.hasParam(param);
00299 if (!param_available)
00300 {
00301 ROS_ERROR("Parameter '%s' not available. Aborting...", param.c_str());
00302 ros::shutdown();
00303 exit(1);
00304 }
00305
00306 nh_.getParam(param.c_str(), data);
00307 }
00308
00310
00318 void SkinDemoMovebase::loadParameterIntArray(ros::NodeHandle & nh_, std::string param, std::vector<int> & vec)
00319 {
00320 bool param_available = nh_.hasParam(param);
00321 if (!param_available)
00322 {
00323 ROS_ERROR("Parameter '%s' not available. Aborting...", param.c_str());
00324 ros::shutdown();
00325 exit(1);
00326 }
00327
00328 XmlRpc::XmlRpcValue raw;
00329 nh_.getParam(param.c_str(), raw);
00330 ROS_ASSERT(raw.getType() == XmlRpc::XmlRpcValue::TypeArray);
00331 for (int32_t i = 0; i < raw.size(); ++i)
00332 {
00333 ROS_ASSERT(raw[i].getType() == XmlRpc::XmlRpcValue::TypeInt);
00334 vec.push_back(static_cast<int>(raw[i]));
00335 }
00336 }
00337
00339
00342 int main(int argc, char** argv) {
00343
00344 ros::init(argc, argv, "skin_demo_movebase");
00345
00346
00347
00348
00349 SkinDemoMovebase skin_demo_movebase;
00350 skin_demo_movebase.publishBaseCommand();
00351 }