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_safe_base/skin_safe_base.h"
00034
00036
00039 SkinSafeBase::SkinSafeBase()
00040 {
00041
00042 nh_private_ = ros::NodeHandle("~");
00043
00044
00045 loadParameterInt(nh_private_, std::string("num_sensors"), num_sensors_);
00046 loadParameterInt(nh_private_, std::string("sensor_threshold"), sensor_threshold_);
00047 loadParameterDouble(nh_private_, std::string("max_vel"), max_vel_);
00048 loadParameterIntArray(nh_private_, std::string("mapping/bl"), patches_bl_);
00049 loadParameterIntArray(nh_private_, std::string("mapping/br"), patches_br_);
00050 loadParameterIntArray(nh_private_, std::string("mapping/fl"), patches_fl_);
00051 loadParameterIntArray(nh_private_, std::string("mapping/fr"), patches_fr_);
00052 loadParameterIntArray(nh_private_, std::string("mapping/rb"), patches_rb_);
00053 loadParameterIntArray(nh_private_, std::string("mapping/rf"), patches_rf_);
00054 loadParameterIntArray(nh_private_, std::string("mapping/lb"), patches_lb_);
00055 loadParameterIntArray(nh_private_, std::string("mapping/lf"), patches_lf_);
00056
00057
00058 sub_skin_data_ = nh_.subscribe("skin_data", 1, &SkinSafeBase::skinNewMeasCallback, this);
00059
00060
00061 pub_cmd_vel_limits_ = nh_.advertise<safe_base_controller::TwistLimits>("/base_controller/command_limits", 1);
00062 }
00063
00065 SkinSafeBase::~SkinSafeBase() {
00066 }
00067
00069
00074 void SkinSafeBase::skinNewMeasCallback(const boost::shared_ptr<skin_driver::skin_meas const>& msg) {
00075
00076 sensor_data_.resize(num_sensors_);
00077
00078
00079 for (int i = 0; i < num_sensors_; i++){
00080 sensor_data_[i].id = i;
00081 sensor_data_[i].stat = ((255) & (msg->sensor_data_msg[i] >> (8*0)));
00082 sensor_data_[i].x = ((255) & (msg->sensor_data_msg[i] >> (8*1)));
00083 sensor_data_[i].ini = ((255) & (msg->sensor_data_msg[i] >> (8*2)));
00084 sensor_data_[i].limit = ((255) & (msg->sensor_data_msg[i] >> (8*3)));
00085 sensor_data_[i].u1 = ((255) & (msg->sensor_data_msg[i] >> (8*4)));
00086 sensor_data_[i].u2 = ((255) & (msg->sensor_data_msg[i] >> (8*5)));
00087 sensor_data_[i].u3 = ((255) & (msg->sensor_data_msg[i] >> (8*6)));
00088 sensor_data_[i].dyn = ((255) & (msg->sensor_data_msg[i] >> (8*7)));
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 blocked_bl_ = checkPatchesBlocked(patches_bl_);
00100 blocked_br_ = checkPatchesBlocked(patches_br_);
00101 blocked_fl_ = checkPatchesBlocked(patches_fl_);
00102 blocked_fr_ = checkPatchesBlocked(patches_fr_);
00103 blocked_rb_ = checkPatchesBlocked(patches_rb_);
00104 blocked_rf_ = checkPatchesBlocked(patches_rf_);
00105 blocked_lb_ = checkPatchesBlocked(patches_lb_);
00106 blocked_lf_ = checkPatchesBlocked(patches_lf_);
00107
00108
00109 safe_base_controller::TwistLimits vel_limits;
00110 vel_limits.linear.x_max = max_vel_;
00111 vel_limits.linear.x_min = -max_vel_;
00112 vel_limits.linear.y_max = max_vel_;
00113 vel_limits.linear.y_min = -max_vel_;
00114 vel_limits.angular.z_max = max_vel_;
00115 vel_limits.angular.z_min = -max_vel_;
00116
00117
00118 if (blocked_bl_ || blocked_br_) {
00119 vel_limits.linear.x_min = 0.0;
00120 ROS_WARN(" -> back blocked");
00121 }
00122
00123
00124 if (blocked_fl_ || blocked_fr_) {
00125 vel_limits.linear.x_max = 0.0;
00126 ROS_WARN(" -> front blocked");
00127 }
00128
00129
00130 if (blocked_lf_ || blocked_lb_) {
00131 vel_limits.linear.y_max = 0.0;
00132 ROS_WARN(" -> right blocked");
00133 }
00134
00135
00136 if (blocked_rf_ || blocked_rb_) {
00137 vel_limits.linear.y_min = 0.0;
00138 ROS_WARN(" -> left blocked");
00139 }
00140
00141
00142 if (blocked_rb_ || blocked_fr_ || blocked_lf_ || blocked_bl_) {
00143 vel_limits.angular.z_max = 0.0;
00144 ROS_WARN(" -> turn left blocked");
00145 }
00146
00147
00148 if (blocked_rf_ || blocked_fl_ || blocked_lb_ || blocked_br_) {
00149 vel_limits.angular.z_min = 0.0;
00150 ROS_WARN(" -> turn right blocked");
00151 }
00152
00153 pub_cmd_vel_limits_.publish(vel_limits);
00154 }
00155
00157
00162 bool SkinSafeBase::checkPatchesBlocked(std::vector<int> & patches)
00163 {
00164 bool free = true;
00165
00166 for (int i = 0; i < (int)patches.size(); i++)
00167 {
00168 int activation = (int)(abs(sensor_data_[patches[i]].x - sensor_data_[patches[i]].ini));
00169 if (activation < sensor_threshold_)
00170 {
00171 ROS_INFO(" Sensor '%i' clear", patches[i]);
00172 }
00173 else
00174 {
00175 free = false;
00176 ROS_WARN(" Sensor '%i' blocked", patches[i]);
00177 }
00178 }
00179
00180 return !free;
00181 }
00182
00184
00187 int main(int argc, char** argv) {
00188
00189 ros::init(argc, argv, "skin_safe_base");
00190
00191
00192 SkinSafeBase skin_safe_base;
00193
00194
00195 ros::spin();
00196 }
00197
00198
00199
00200
00201
00203
00210 void SkinSafeBase::loadParameterDouble(ros::NodeHandle & nh_, std::string param, double & data)
00211 {
00212 bool param_available = nh_.hasParam(param);
00213 if (!param_available)
00214 {
00215 ROS_ERROR("Parameter '%s' not available. Aborting...", param.c_str());
00216 ros::shutdown();
00217 exit(1);
00218 }
00219
00220 nh_.getParam(param.c_str(), data);
00221 }
00222
00224
00231 void SkinSafeBase::loadParameterInt(ros::NodeHandle & nh_, std::string param, int & data)
00232 {
00233 bool param_available = nh_.hasParam(param);
00234 if (!param_available)
00235 {
00236 ROS_ERROR("Parameter '%s' not available. Aborting...", param.c_str());
00237 ros::shutdown();
00238 exit(1);
00239 }
00240
00241 nh_.getParam(param.c_str(), data);
00242 }
00243
00245
00253 void SkinSafeBase::loadParameterIntArray(ros::NodeHandle & nh_, std::string param, std::vector<int> & vec)
00254 {
00255 bool param_available = nh_.hasParam(param);
00256 if (!param_available)
00257 {
00258 ROS_ERROR("Parameter '%s' not available. Aborting...", param.c_str());
00259 ros::shutdown();
00260 exit(1);
00261 }
00262
00263 XmlRpc::XmlRpcValue raw;
00264 nh_.getParam(param.c_str(), raw);
00265 ROS_ASSERT(raw.getType() == XmlRpc::XmlRpcValue::TypeArray);
00266 for (int32_t i = 0; i < raw.size(); ++i)
00267 {
00268 ROS_ASSERT(raw[i].getType() == XmlRpc::XmlRpcValue::TypeInt);
00269 vec.push_back(static_cast<int>(raw[i]));
00270 }
00271 }