00001
00012
00013
00014
00015
00016 #include <pluginlib/class_list_macros.h>
00017 #include <ros/console.h>
00018
00019 #include "roch_sensorpc/roch_sensorpc.hpp"
00020
00021 #include <ros/ros.h>
00022
00023 namespace roch_sensorpc
00024 {
00025
00026 void SensorPcNodelet::coreSensorCB(const roch_msgs::SensorState::ConstPtr& msg)
00027 {
00028 if (pointcloud_pub_.getNumSubscribers() == 0)
00029 return;
00030
00031
00032 if (! msg->leftcliff && ! prev_leftcliff && ! msg->rightcliff && ! prev_rightcliff &&
00033 ! msg->leftult && ! prev_leftult && ! msg->centerult && ! prev_centerult && ! msg->rightult && ! prev_rightult &&
00034 ! msg->leftpsd && ! prev_leftpsd && ! msg->centerpsd && ! prev_centerpsd && ! msg->rightpsd && ! prev_rightpsd)
00035 return;
00036
00037 prev_leftcliff = msg->leftcliff;
00038 prev_rightcliff = msg->rightcliff;
00039 prev_leftult = msg->leftult;
00040 prev_centerult = msg->centerult;
00041 prev_rightult = msg->rightult;
00042 prev_leftpsd = msg->leftpsd;
00043 prev_centerpsd = msg->centerpsd;
00044 prev_rightpsd = msg->rightpsd;
00045
00046
00047
00048
00049 if ((cliff_enable_ && (msg->leftcliff & roch_msgs::SensorState::CLIFF )) ||
00050 (ult_enable_ && (msg->leftult & roch_msgs::SensorState::NEAR)) ||
00051 (psd_enable_ && (msg->leftpsd & roch_msgs::SensorState::NEAR)))
00052 {
00053 memcpy(&pointcloud_.data[0 * pointcloud_.point_step + pointcloud_.fields[0].offset], &p_side_x_, sizeof(float));
00054 memcpy(&pointcloud_.data[0 * pointcloud_.point_step + pointcloud_.fields[1].offset], &p_side_y_, sizeof(float));
00055 ROS_INFO_STREAM("Enter left interrupt: cliff_enable:" << cliff_enable_ << " ult_enable:"<<ult_enable_<<" psd_enable:"<<psd_enable_<<".");
00056 }
00057 else
00058 {
00059 memcpy(&pointcloud_.data[0 * pointcloud_.point_step + pointcloud_.fields[0].offset], &P_INF_X, sizeof(float));
00060 memcpy(&pointcloud_.data[0 * pointcloud_.point_step + pointcloud_.fields[1].offset], &P_INF_Y, sizeof(float));
00061 }
00062
00063 if ((ult_enable_ && (msg->centerult & roch_msgs::SensorState::NEAR )) ||
00064 (psd_enable_ && (msg->centerpsd & roch_msgs::SensorState::NEAR)))
00065 {
00066 memcpy(&pointcloud_.data[1 * pointcloud_.point_step + pointcloud_.fields[0].offset], &pc_radius_, sizeof(float));
00067
00068 ROS_INFO_STREAM("Enter center interrupt: ult_enable:"<<ult_enable_<<" psd_enable:"<<psd_enable_<<".");
00069 }
00070 else
00071 {
00072 memcpy(&pointcloud_.data[1 * pointcloud_.point_step + pointcloud_.fields[0].offset], &P_INF_X, sizeof(float));
00073 }
00074
00075 if ((cliff_enable_ && (msg->rightcliff & roch_msgs::SensorState::CLIFF)) ||
00076 (ult_enable_ && (msg->rightult & roch_msgs::SensorState::NEAR )) ||
00077 (psd_enable_ && (msg->rightpsd & roch_msgs::SensorState::NEAR)))
00078 {
00079 memcpy(&pointcloud_.data[2 * pointcloud_.point_step + pointcloud_.fields[0].offset], &p_side_x_, sizeof(float));
00080 memcpy(&pointcloud_.data[2 * pointcloud_.point_step + pointcloud_.fields[1].offset], &n_side_y_, sizeof(float));
00081 ROS_INFO_STREAM("Enter right interrupt: cliff_enable:" << cliff_enable_ << " ult_enable:"<<ult_enable_<<" psd_enable:"<<psd_enable_<<".");
00082 }
00083 else
00084 {
00085 memcpy(&pointcloud_.data[2 * pointcloud_.point_step + pointcloud_.fields[0].offset], &P_INF_X, sizeof(float));
00086 memcpy(&pointcloud_.data[2 * pointcloud_.point_step + pointcloud_.fields[1].offset], &N_INF_Y, sizeof(float));
00087 }
00088
00089 pointcloud_.header.stamp = msg->header.stamp;
00090 pointcloud_pub_.publish(pointcloud_);
00091 }
00092
00093 void SensorPcNodelet::onInit()
00094 {
00095
00096
00097
00098
00099
00100
00101 std::string base_link_frame;
00102 double r, h, angle;
00103 bool ult_en,psd_en,cliff_en;
00104 private_nh_.param("pointcloud_radius", r, 0.25); pc_radius_ = r;
00105 private_nh_.param("pointcloud_height", h, 0.04); pc_height_ = h;
00106 private_nh_.param("side_point_angle", angle, 0.34906585);
00107 private_nh_.param<std::string>("base_link_frame", base_link_frame, "/base_link");
00108 private_nh_.param<bool>("ult_enable", ult_enable_, true);
00109 private_nh_.param<bool>("psd_enable", psd_enable_, true);
00110 private_nh_.param<bool>("cliff_enable", cliff_enable_, true);
00111
00112
00113 p_side_x_ = + pc_radius_*sin(angle);
00114 p_side_y_ = + pc_radius_*cos(angle);
00115 n_side_y_ = - pc_radius_*cos(angle);
00116
00117
00118 pointcloud_.header.frame_id = base_link_frame;
00119 pointcloud_.width = 3;
00120 pointcloud_.height = 1;
00121 pointcloud_.fields.resize(3);
00122
00123
00124 pointcloud_.fields[0].name = "x";
00125 pointcloud_.fields[1].name = "y";
00126 pointcloud_.fields[2].name = "z";
00127
00128 int offset = 0;
00129
00130 for (size_t d = 0; d < pointcloud_.fields.size(); ++d, offset += 4)
00131 {
00132 pointcloud_.fields[d].count = 1;
00133 pointcloud_.fields[d].offset = offset;
00134 pointcloud_.fields[d].datatype = sensor_msgs::PointField::FLOAT32;
00135 }
00136
00137 pointcloud_.point_step = offset;
00138 pointcloud_.row_step = pointcloud_.point_step * pointcloud_.width;
00139
00140 pointcloud_.data.resize(3 * pointcloud_.point_step);
00141 pointcloud_.is_bigendian = false;
00142 pointcloud_.is_dense = true;
00143
00144
00145
00146
00147 memcpy(&pointcloud_.data[1 * pointcloud_.point_step + pointcloud_.fields[1].offset], &ZERO, sizeof(float));
00148
00149
00150 memcpy(&pointcloud_.data[0 * pointcloud_.point_step + pointcloud_.fields[2].offset], &pc_height_, sizeof(float));
00151 memcpy(&pointcloud_.data[1 * pointcloud_.point_step + pointcloud_.fields[2].offset], &pc_height_, sizeof(float));
00152 memcpy(&pointcloud_.data[2 * pointcloud_.point_step + pointcloud_.fields[2].offset], &pc_height_, sizeof(float));
00153
00154 pointcloud_pub_ = nh.advertise <sensor_msgs::PointCloud2> ("pointcloud", 10);
00155 core_sensor_sub_ = nh.subscribe("core_sensors", 10, &SensorPcNodelet::coreSensorCB, this);
00156 ROS_INFO("init params: cliff_enable:%d ult_enable:%d psd_enable:%d.",cliff_enable_, ult_enable_, psd_enable_);
00157
00158 ROS_INFO("Ult/psd/cliff pointcloud configured at distance %f and height %f from base frame", pc_radius_, pc_height_);
00159 }
00160
00161 }
00162
00163 int main(int argc, char** argv){
00164 ros::init(argc,argv,"roch_sensorpc_nodelet");
00165 ros::NodeHandle nh, private_nh("~");
00166 roch_sensorpc::SensorPcNodelet sensorpc(nh,private_nh);
00167
00168 ros::spin();
00169
00170 return 0;
00171 }