00001
00010
00011
00012
00013
00014 #include <pluginlib/class_list_macros.h>
00015
00016 #include "kobuki_bumper2pc/kobuki_bumper2pc.hpp"
00017
00018 namespace kobuki_bumper2pc
00019 {
00020
00021 void Bumper2PcNodelet::coreSensorCB(const kobuki_msgs::SensorState::ConstPtr& msg)
00022 {
00023 if (pointcloud_pub_.getNumSubscribers() == 0)
00024 return;
00025
00026
00027 if (! msg->bumper && ! msg->cliff && ! prev_bumper && ! prev_cliff)
00028 return;
00029
00030 prev_bumper = msg->bumper;
00031 prev_cliff = msg->cliff;
00032
00033
00034
00035 if ((msg->bumper & kobuki_msgs::SensorState::BUMPER_LEFT) ||
00036 (msg->cliff & kobuki_msgs::SensorState::CLIFF_LEFT))
00037 {
00038 memcpy(&pointcloud_.data[0 * pointcloud_.point_step + pointcloud_.fields[0].offset], &p_side_x_, sizeof(float));
00039 memcpy(&pointcloud_.data[0 * pointcloud_.point_step + pointcloud_.fields[1].offset], &p_side_y_, sizeof(float));
00040 }
00041 else
00042 {
00043 memcpy(&pointcloud_.data[0 * pointcloud_.point_step + pointcloud_.fields[0].offset], &P_INF_X, sizeof(float));
00044 memcpy(&pointcloud_.data[0 * pointcloud_.point_step + pointcloud_.fields[1].offset], &P_INF_Y, sizeof(float));
00045 }
00046
00047 if ((msg->bumper & kobuki_msgs::SensorState::BUMPER_CENTRE) ||
00048 (msg->cliff & kobuki_msgs::SensorState::CLIFF_CENTRE))
00049 {
00050 memcpy(&pointcloud_.data[1 * pointcloud_.point_step + pointcloud_.fields[0].offset], &pc_radius_, sizeof(float));
00051 }
00052 else
00053 {
00054 memcpy(&pointcloud_.data[1 * pointcloud_.point_step + pointcloud_.fields[0].offset], &P_INF_X, sizeof(float));
00055 }
00056
00057 if ((msg->bumper & kobuki_msgs::SensorState::BUMPER_RIGHT) ||
00058 (msg->cliff & kobuki_msgs::SensorState::CLIFF_RIGHT))
00059 {
00060 memcpy(&pointcloud_.data[2 * pointcloud_.point_step + pointcloud_.fields[0].offset], &p_side_x_, sizeof(float));
00061 memcpy(&pointcloud_.data[2 * pointcloud_.point_step + pointcloud_.fields[1].offset], &n_side_y_, sizeof(float));
00062 }
00063 else
00064 {
00065 memcpy(&pointcloud_.data[2 * pointcloud_.point_step + pointcloud_.fields[0].offset], &P_INF_X, sizeof(float));
00066 memcpy(&pointcloud_.data[2 * pointcloud_.point_step + pointcloud_.fields[1].offset], &N_INF_Y, sizeof(float));
00067 }
00068
00069 pointcloud_.header.stamp = msg->header.stamp;
00070 pointcloud_pub_.publish(pointcloud_);
00071 }
00072
00073 void Bumper2PcNodelet::onInit()
00074 {
00075 ros::NodeHandle nh = this->getPrivateNodeHandle();
00076
00077
00078
00079
00080
00081
00082 std::string base_link_frame;
00083 double r, h, angle;
00084 nh.param("pointcloud_radius", r, 0.25); pc_radius_ = r;
00085 nh.param("pointcloud_height", h, 0.04); pc_height_ = h;
00086 nh.param("side_point_angle", angle, 0.34906585);
00087 nh.param<std::string>("base_link_frame", base_link_frame, "/base_link");
00088
00089
00090 p_side_x_ = + pc_radius_*sin(angle);
00091 p_side_y_ = + pc_radius_*cos(angle);
00092 n_side_y_ = - pc_radius_*cos(angle);
00093
00094
00095 pointcloud_.header.frame_id = base_link_frame;
00096 pointcloud_.width = 3;
00097 pointcloud_.height = 1;
00098 pointcloud_.fields.resize(3);
00099
00100
00101 pointcloud_.fields[0].name = "x";
00102 pointcloud_.fields[1].name = "y";
00103 pointcloud_.fields[2].name = "z";
00104
00105 int offset = 0;
00106
00107 for (size_t d = 0; d < pointcloud_.fields.size(); ++d, offset += 4)
00108 {
00109 pointcloud_.fields[d].count = 1;
00110 pointcloud_.fields[d].offset = offset;
00111 pointcloud_.fields[d].datatype = sensor_msgs::PointField::FLOAT32;
00112 }
00113
00114 pointcloud_.point_step = offset;
00115 pointcloud_.row_step = pointcloud_.point_step * pointcloud_.width;
00116
00117 pointcloud_.data.resize(3 * pointcloud_.point_step);
00118 pointcloud_.is_bigendian = false;
00119 pointcloud_.is_dense = true;
00120
00121
00122
00123
00124 memcpy(&pointcloud_.data[1 * pointcloud_.point_step + pointcloud_.fields[1].offset], &ZERO, sizeof(float));
00125
00126
00127 memcpy(&pointcloud_.data[0 * pointcloud_.point_step + pointcloud_.fields[2].offset], &pc_height_, sizeof(float));
00128 memcpy(&pointcloud_.data[1 * pointcloud_.point_step + pointcloud_.fields[2].offset], &pc_height_, sizeof(float));
00129 memcpy(&pointcloud_.data[2 * pointcloud_.point_step + pointcloud_.fields[2].offset], &pc_height_, sizeof(float));
00130
00131 pointcloud_pub_ = nh.advertise <sensor_msgs::PointCloud2> ("pointcloud", 10);
00132 core_sensor_sub_ = nh.subscribe("core_sensors", 10, &Bumper2PcNodelet::coreSensorCB, this);
00133
00134 ROS_INFO("Bumper/cliff pointcloud configured at distance %f and height %f from base frame", pc_radius_, pc_height_);
00135 }
00136
00137 }
00138
00139
00140 PLUGINLIB_EXPORT_CLASS(kobuki_bumper2pc::Bumper2PcNodelet, nodelet::Nodelet);