roch_sensorpc.cpp
Go to the documentation of this file.
1 
12 /*****************************************************************************
13 ** Includes
14 *****************************************************************************/
15 
17 #include <ros/console.h>
18 
20 
21 #include <ros/ros.h>
22 
23 namespace roch_sensorpc
24 {
25 
26 void SensorPcNodelet::coreSensorCB(const roch_msgs::SensorState::ConstPtr& msg)
27 {
29  return;
30 
31  // We publish just one "no events" pc (with all three points far away) and stop spamming when bumper/cliff conditions disappear
32  if (! msg->leftcliff && ! prev_leftcliff && ! msg->rightcliff && ! prev_rightcliff &&
33  ! msg->leftult && ! prev_leftult && ! msg->centerult && ! prev_centerult && ! msg->rightult && ! prev_rightult &&
34  ! msg->leftpsd && ! prev_leftpsd && ! msg->centerpsd && ! prev_centerpsd && ! msg->rightpsd && ! prev_rightpsd)
35  return;
36 
37  prev_leftcliff = msg->leftcliff;
38  prev_rightcliff = msg->rightcliff;
39  prev_leftult = msg->leftult;
40  prev_centerult = msg->centerult;
41  prev_rightult = msg->rightult;
42  prev_leftpsd = msg->leftpsd;
43  prev_centerpsd = msg->centerpsd;
44  prev_rightpsd = msg->rightpsd;
45 
46 
47  // We replicate the sensors order of bumper/cliff event messages: LEFT = 0, CENTER = 1 and RIGHT = 2
48  // For any of {left/center/right} with no bumper/cliff event, we publish a faraway point that won't get used
49  if ((cliff_enable_ && (msg->leftcliff & roch_msgs::SensorState::CLIFF )) ||
50  (ult_enable_ && (msg->leftult & roch_msgs::SensorState::NEAR)) ||
51  (psd_enable_ && (msg->leftpsd & roch_msgs::SensorState::NEAR)))
52  {
53  memcpy(&pointcloud_.data[0 * pointcloud_.point_step + pointcloud_.fields[0].offset], &p_side_x_, sizeof(float));
54  memcpy(&pointcloud_.data[0 * pointcloud_.point_step + pointcloud_.fields[1].offset], &p_side_y_, sizeof(float));
55  ROS_INFO_STREAM("Enter left interrupt: cliff_enable:" << cliff_enable_ << " ult_enable:"<<ult_enable_<<" psd_enable:"<<psd_enable_<<".");
56  }
57  else
58  {
59  memcpy(&pointcloud_.data[0 * pointcloud_.point_step + pointcloud_.fields[0].offset], &P_INF_X, sizeof(float));
60  memcpy(&pointcloud_.data[0 * pointcloud_.point_step + pointcloud_.fields[1].offset], &P_INF_Y, sizeof(float));
61  }
62 
63  if ((ult_enable_ && (msg->centerult & roch_msgs::SensorState::NEAR )) ||
64  (psd_enable_ && (msg->centerpsd & roch_msgs::SensorState::NEAR)))
65  {
66  memcpy(&pointcloud_.data[1 * pointcloud_.point_step + pointcloud_.fields[0].offset], &pc_radius_, sizeof(float));
67 
68  ROS_INFO_STREAM("Enter center interrupt: ult_enable:"<<ult_enable_<<" psd_enable:"<<psd_enable_<<".");
69  }
70  else
71  {
72  memcpy(&pointcloud_.data[1 * pointcloud_.point_step + pointcloud_.fields[0].offset], &P_INF_X, sizeof(float));
73  }
74 
75  if ((cliff_enable_ && (msg->rightcliff & roch_msgs::SensorState::CLIFF)) ||
76  (ult_enable_ && (msg->rightult & roch_msgs::SensorState::NEAR )) ||
77  (psd_enable_ && (msg->rightpsd & roch_msgs::SensorState::NEAR)))
78  {
79  memcpy(&pointcloud_.data[2 * pointcloud_.point_step + pointcloud_.fields[0].offset], &p_side_x_, sizeof(float));
80  memcpy(&pointcloud_.data[2 * pointcloud_.point_step + pointcloud_.fields[1].offset], &n_side_y_, sizeof(float));
81  ROS_INFO_STREAM("Enter right interrupt: cliff_enable:" << cliff_enable_ << " ult_enable:"<<ult_enable_<<" psd_enable:"<<psd_enable_<<".");
82  }
83  else
84  {
85  memcpy(&pointcloud_.data[2 * pointcloud_.point_step + pointcloud_.fields[0].offset], &P_INF_X, sizeof(float));
86  memcpy(&pointcloud_.data[2 * pointcloud_.point_step + pointcloud_.fields[1].offset], &N_INF_Y, sizeof(float));
87  }
88 
89  pointcloud_.header.stamp = msg->header.stamp;
91 }
92 
94 {
95 
96  // Bumper/cliff pointcloud distance to base frame; should be something like the robot radius plus
97  // costmap resolution plus an extra to cope with robot inertia. This is a bit tricky parameter: if
98  // it's too low, costmap will ignore this pointcloud (the robot footprint runs over the hit obstacle),
99  // but if it's too big, hit obstacles will be mapped too far from the robot and the navigation around
100  // them will probably fail.
101  std::string base_link_frame;
102  double r, h, angle;
103  bool ult_en,psd_en,cliff_en;
104  private_nh_.param("pointcloud_radius", r, 0.25); pc_radius_ = r;
105  private_nh_.param("pointcloud_height", h, 0.04); pc_height_ = h;
106  private_nh_.param("side_point_angle", angle, 0.34906585);
107  private_nh_.param<std::string>("base_link_frame", base_link_frame, "/base_link");
108  private_nh_.param<bool>("ult_enable", ult_enable_, true);
109  private_nh_.param<bool>("psd_enable", psd_enable_, true);
110  private_nh_.param<bool>("cliff_enable", cliff_enable_, true);
111 
112  // Lateral points x/y coordinates; we need to store float values to memcopy later
113  p_side_x_ = + pc_radius_*sin(angle); // angle degrees from vertical
114  p_side_y_ = + pc_radius_*cos(angle); // angle degrees from vertical
115  n_side_y_ = - pc_radius_*cos(angle); // angle degrees from vertical
116 
117  // Prepare constant parts of the pointcloud message to be published
118  pointcloud_.header.frame_id = base_link_frame;
119  pointcloud_.width = 3;
120  pointcloud_.height = 1;
121  pointcloud_.fields.resize(3);
122 
123  // Set x/y/z as the only fields
124  pointcloud_.fields[0].name = "x";
125  pointcloud_.fields[1].name = "y";
126  pointcloud_.fields[2].name = "z";
127 
128  int offset = 0;
129  // All offsets are *4, as all field data types are float32
130  for (size_t d = 0; d < pointcloud_.fields.size(); ++d, offset += 4)
131  {
132  pointcloud_.fields[d].count = 1;
133  pointcloud_.fields[d].offset = offset;
134  pointcloud_.fields[d].datatype = sensor_msgs::PointField::FLOAT32;
135  }
136 
137  pointcloud_.point_step = offset;
138  pointcloud_.row_step = pointcloud_.point_step * pointcloud_.width;
139 
140  pointcloud_.data.resize(3 * pointcloud_.point_step);
141  pointcloud_.is_bigendian = false;
142  pointcloud_.is_dense = true;
143 
144  // Bumper/cliff "points" fix coordinates (the others depend on sensor activation/deactivation)
145 
146  // y: always 0 for central bumper
147  memcpy(&pointcloud_.data[1 * pointcloud_.point_step + pointcloud_.fields[1].offset], &ZERO, sizeof(float));
148 
149  // z: constant elevation from base frame
150  memcpy(&pointcloud_.data[0 * pointcloud_.point_step + pointcloud_.fields[2].offset], &pc_height_, sizeof(float));
151  memcpy(&pointcloud_.data[1 * pointcloud_.point_step + pointcloud_.fields[2].offset], &pc_height_, sizeof(float));
152  memcpy(&pointcloud_.data[2 * pointcloud_.point_step + pointcloud_.fields[2].offset], &pc_height_, sizeof(float));
153 
154  pointcloud_pub_ = nh.advertise <sensor_msgs::PointCloud2> ("pointcloud", 10);
155  core_sensor_sub_ = nh.subscribe("core_sensors", 10, &SensorPcNodelet::coreSensorCB, this);
156  ROS_INFO("init params: cliff_enable:%d ult_enable:%d psd_enable:%d.",cliff_enable_, ult_enable_, psd_enable_);
157 
158  ROS_INFO("Ult/psd/cliff pointcloud configured at distance %f and height %f from base frame", pc_radius_, pc_height_);
159 }
160 
161 } // namespace roch_sensorpc
162 
163 int main(int argc, char** argv){
164  ros::init(argc,argv,"roch_sensorpc_nodelet");
165  ros::NodeHandle nh, private_nh("~");
166  roch_sensorpc::SensorPcNodelet sensorpc(nh,private_nh);
167 
168  ros::spin();
169 
170  return 0;
171 }
d
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
Bumper/cliff to pointcloud nodelet class declaration.
int main(int argc, char **argv)
ROSCPP_DECL void spin(Spinner &spinner)
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
sensor_msgs::PointCloud2 pointcloud_
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void coreSensorCB(const roch_msgs::SensorState::ConstPtr &msg)
Core sensors state structure callback.
uint32_t getNumSubscribers() const
#define ROS_INFO_STREAM(args)
SensorPcNodelet class declaration.


roch_sensorpc
Author(s): Chen , Jorge Santos Simon
autogenerated on Mon Jun 10 2019 14:41:26