25 #include <boost/thread/thread.hpp> 26 #include <boost/bind.hpp> 30 #include <gazebo/sensors/Sensor.hh> 32 #include <gazebo/sensors/SensorTypes.hh> 41 GZ_REGISTER_SENSOR_PLUGIN(GazeboRosDepthCamera)
47 this->point_cloud_connect_count_ = 0;
48 this->depth_image_connect_count_ = 0;
49 this->depth_info_connect_count_ = 0;
50 this->last_depth_image_camera_info_update_time_ = common::Time(0);
63 DepthCameraPlugin::Load(_parent, _sdf);
68 ROS_FATAL_STREAM_NAMED(
"depth_camera",
"A ROS node for Gazebo has not been initialized, unable to load plugin. " 69 <<
"Load the Gazebo system plugin 'libgazebo_ros_api_plugin.so' in the gazebo_ros package)");
75 this->
width_ = this->width;
77 this->
depth_ = this->depth;
79 this->
camera_ = this->depthCamera;
82 if (!_sdf->HasElement(
"imageTopicName"))
84 if (!_sdf->HasElement(
"cameraInfoTopicName"))
88 if (!_sdf->HasElement(
"pointCloudTopicName"))
94 if (!_sdf->HasElement(
"depthImageTopicName"))
99 if (!_sdf->HasElement(
"depthImageCameraInfoTopicName"))
104 if (!_sdf->HasElement(
"pointCloudCutoff"))
116 ros::AdvertiseOptions::create<sensor_msgs::PointCloud2 >(
124 ros::AdvertiseOptions::create< sensor_msgs::Image >(
132 ros::AdvertiseOptions::create<sensor_msgs::CameraInfo>(
147 this->parentSensor->SetActive(
true);
156 this->parentSensor->SetActive(
false);
164 this->parentSensor->SetActive(
true);
189 unsigned int _width,
unsigned int _height,
unsigned int _depth,
190 const std::string &_format)
195 # if GAZEBO_MAJOR_VERSION >= 7 201 if (this->parentSensor->IsActive())
207 this->parentSensor->SetActive(
false);
223 this->parentSensor->SetActive(
true);
230 unsigned int _width,
unsigned int _height,
unsigned int _depth,
231 const std::string &_format)
236 # if GAZEBO_MAJOR_VERSION >= 7 242 if (!this->parentSensor->IsActive())
246 this->parentSensor->SetActive(
true);
262 pcd_modifier.
resize(_width*_height);
271 for (
unsigned int i = 0; i < _width; i++)
273 for (
unsigned int j = 0; j < _height; j++, ++iter_x, ++iter_y, ++iter_z, ++iter_rgb)
275 unsigned int index = (j * _width) + i;
276 *iter_x = _pcd[4 * index];
277 *iter_y = _pcd[4 * index + 1];
278 *iter_z = _pcd[4 * index + 2];
279 *iter_rgb = _pcd[4 * index + 3];
280 if (i == _width /2 && j == _height / 2)
282 uint32_t rgb = *
reinterpret_cast<int*
>(&(*iter_rgb));
283 uint8_t r = (rgb >> 16) & 0x0000ff;
284 uint8_t g = (rgb >> 8) & 0x0000ff;
285 uint8_t b = (rgb) & 0x0000ff;
286 std::cerr << (int)r <<
" " << (
int)g <<
" " << (int)b <<
"\n";
292 this->
lock_.unlock();
300 unsigned int _width,
unsigned int _height,
unsigned int _depth,
301 const std::string &_format)
307 # if GAZEBO_MAJOR_VERSION >= 7 313 if (!this->parentSensor->IsActive())
317 this->parentSensor->SetActive(
true);
352 this->
lock_.unlock();
374 this->
lock_.unlock();
380 sensor_msgs::PointCloud2 &point_cloud_msg,
381 uint32_t rows_arg, uint32_t cols_arg,
382 uint32_t step_arg,
void* data_arg)
386 pcd_modifier.
resize(rows_arg*cols_arg);
393 point_cloud_msg.is_dense =
true;
395 float* toCopyFrom = (
float*)data_arg;
398 double hfov = this->parentSensor->DepthCamera()->HFOV().Radian();
399 double fl = ((double)this->width) / (2.0 *tan(hfov/2.0));
402 for (uint32_t j=0; j<rows_arg; j++)
405 if (rows_arg>1) pAngle = atan2( (
double)j - 0.5*(
double)(rows_arg-1), fl);
408 for (uint32_t i=0; i<cols_arg; i++, ++iter_x, ++iter_y, ++iter_z, ++iter_rgb)
411 if (cols_arg>1) yAngle = atan2( (
double)i - 0.5*(
double)(cols_arg-1), fl);
414 double depth = toCopyFrom[index++];
420 *iter_x = depth * tan(yAngle);
421 *iter_y = depth * tan(pAngle);
428 *iter_x = *iter_y = *iter_z = std::numeric_limits<float>::quiet_NaN ();
429 point_cloud_msg.is_dense =
false;
433 uint8_t* image_src = (uint8_t*)(&(this->
image_msg_.data[0]));
434 if (this->
image_msg_.data.size() == rows_arg*cols_arg*3)
437 iter_rgb[0] = image_src[i*3+j*cols_arg*3+0];
438 iter_rgb[1] = image_src[i*3+j*cols_arg*3+1];
439 iter_rgb[2] = image_src[i*3+j*cols_arg*3+2];
441 else if (this->
image_msg_.data.size() == rows_arg*cols_arg)
444 iter_rgb[0] = image_src[i+j*cols_arg];
445 iter_rgb[1] = image_src[i+j*cols_arg];
446 iter_rgb[2] = image_src[i+j*cols_arg];
463 sensor_msgs::Image& image_msg,
464 uint32_t rows_arg, uint32_t cols_arg,
465 uint32_t step_arg,
void* data_arg)
468 image_msg.height = rows_arg;
469 image_msg.width = cols_arg;
470 image_msg.step =
sizeof(float) * cols_arg;
471 image_msg.data.resize(rows_arg * cols_arg *
sizeof(
float));
472 image_msg.is_bigendian = 0;
474 const float bad_point = std::numeric_limits<float>::quiet_NaN();
476 float* dest = (
float*)(&(image_msg.data[0]));
477 float* toCopyFrom = (
float*)data_arg;
481 for (uint32_t j = 0; j < rows_arg; j++)
483 for (uint32_t i = 0; i < cols_arg; i++)
485 float depth = toCopyFrom[index++];
489 dest[i + j * cols_arg] = depth;
493 dest[i + j * cols_arg] = bad_point;
502 ROS_DEBUG_NAMED(
"depth_camera",
"publishing default camera info, then depth camera info");
507 # if GAZEBO_MAJOR_VERSION >= 7 508 common::Time sensor_update_time = this->
parentSensor_->LastMeasurementTime();
510 common::Time sensor_update_time = this->
parentSensor_->GetLastMeasurementTime();
double point_cloud_cutoff_
void PointCloudDisconnect()
~GazeboRosDepthCamera()
Destructor.
virtual void Load(sensors::SensorPtr _parent, sdf::ElementPtr _sdf)
Load the plugin.
std::string image_topic_name_
ROS image topic name.
boost::mutex lock_
A mutex to lock access to fields that are used in ROS message callbacks.
virtual void PublishCameraInfo()
common::Time sensor_update_time_
std::string depth_image_topic_name_
image where each pixel contains the depth information
void DepthImageDisconnect()
ROSCPP_DECL bool isInitialized()
std::string point_cloud_topic_name_
ROS image topic name.
void Load(sensors::SensorPtr _parent, sdf::ElementPtr _sdf, const std::string &_camera_name_suffix="")
Load the plugin.
common::Time last_depth_image_camera_info_update_time_
common::Time depth_sensor_update_time_
ros::CallbackQueue camera_queue_
boost::shared_ptr< int > image_connect_count_
Keep track of number of image connections.
sensor_msgs::Image image_msg_
ROS image message.
#define ROS_DEBUG_NAMED(name,...)
void publish(const boost::shared_ptr< M > &message) const
event::ConnectionPtr OnLoad(const boost::function< void()> &)
#define ROS_FATAL_STREAM_NAMED(name, args)
const std::string TYPE_32FC1
bool initialized_
True if camera util is initialized.
int depth_info_connect_count_
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
std::string frame_name_
ROS frame transform name to use in the image message header. This should typically match the link nam...
bool FillDepthImageHelper(sensor_msgs::Image &image_msg, uint32_t rows_arg, uint32_t cols_arg, uint32_t step_arg, void *data_arg)
std::string camera_info_topic_name_
sensor_msgs::PointCloud2 point_cloud_msg_
PointCloud2 point cloud message.
ros::Publisher point_cloud_pub_
A pointer to the ROS node. A node will be instantiated if it does not exist.
void PutCameraData(const unsigned char *_src)
Put camera data to the ROS topic.
rendering::CameraPtr camera_
int point_cloud_connect_count_
Keep track of number of connctions for point clouds.
virtual void OnNewDepthFrame(const float *_image, unsigned int _width, unsigned int _height, unsigned int _depth, const std::string &_format)
Update the controller.
ros::NodeHandle * rosnode_
A pointer to the ROS node. A node will be instantiated if it does not exist.
void FillPointdCloud(const float *_src)
Put camera data to the ROS topic.
int depth_image_connect_count_
Keep track of number of connctions for point clouds.
void FillDepthImage(const float *_src)
push depth image data into ros topic
event::ConnectionPtr load_connection_
ros::Publisher depth_image_camera_info_pub_
ros::Publisher depth_image_pub_
virtual void Advertise()
Advertise point cloud and depth image.
std::string depth_image_camera_info_topic_name_
void DepthInfoDisconnect()
sensor_msgs::Image depth_image_msg_
sensors::SensorPtr parentSensor_
void setPointCloud2FieldsByString(int n_fields,...)
virtual void OnNewRGBPointCloud(const float *_pcd, unsigned int _width, unsigned int _height, unsigned int _depth, const std::string &_format)
Update the controller.
boost::shared_ptr< void > VoidPtr
virtual void OnNewImageFrame(const unsigned char *_image, unsigned int _width, unsigned int _height, unsigned int _depth, const std::string &_format)
Update the controller.
bool FillPointCloudHelper(sensor_msgs::PointCloud2 &point_cloud_msg, uint32_t rows_arg, uint32_t cols_arg, uint32_t step_arg, void *data_arg)