Corentin Chauvin-Hameau – 2019-2020
Coverage Path Planning for an underwater robot surveying a marine farm
camera_nodelet.hpp
Go to the documentation of this file.
1 /**
2  * @file
3  *
4  * \brief Declaration of a nodelet simulating a camera
5  * \author Corentin Chauvin-Hameau
6  * \date 2019
7  */
8 
9 #ifndef CAMERA_HPP
10 #define CAMERA_HPP
11 
12 #include "mf_sensors_simulator/CameraOutput.h"
13 #include "mf_sensors_simulator/MultiPoses.h"
15 #include "mf_farm_simulator/Algae.h"
16 #include "reactphysics3d.h"
17 #include <tf2_ros/transform_listener.h>
18 #include <tf2/LinearMath/Vector3.h>
19 #include <tf2/LinearMath/Transform.h>
20 #include <geometry_msgs/TransformStamped.h>
21 #include <nodelet/nodelet.h>
22 #include <ros/ros.h>
23 #include <csignal>
24 #include <string>
25 #include <mutex>
26 #include <vector>
27 
28 
29 namespace mfcpp {
30 
31 typedef std::unique_ptr<rp3d::BoxShape> box_shape_ptr;
32 
33 
34 /**
35  * \brief Nodelet for a simulated camera
36  *
37  * For each pixel, the simulated sensor casts a ray. If the ray touches an alga,
38  * the sensor will return the hit position, and the corresponding value of
39  * the alga disease heatmap.
40  *
41  * To improve performance, two collision worlds are created:
42  * - a big collision world containing all the algae and the field of view (FOV)
43  * of the camera.
44  * - a small one only for raycasting.
45  *
46  * A first step is then to test overlap between the camera FOV and the algae, the
47  * overlapping algae populates the small collision world. Therefore, raycasting
48  * is performed on a smaller amount of algae.
49  */
50 class CameraNodelet: public nodelet::Nodelet {
51  public:
52  CameraNodelet();
54 
55  /**
56  * \brief Function called at beginning of nodelet execution
57  */
58  virtual void onInit();
59 
60  private:
61  /**
62  * \brief Callback class for raycasting
63  */
64  class RaycastCallback: public rp3d::RaycastCallback
65  {
66  public:
68  virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& info);
69 
70  bool alga_hit_; ///< Whether an alga has been hit
71  tf2::Vector3 hit_pt_; ///< Hit point
72  int alga_idx_; ///< Index of the hit alga in the ray_bodies_ vector
73  private:
74  CameraNodelet *parent_; ///< Parent CameraNodelet instance
75  };
76 
77  /**
78  * \brief Callback class for overlap detection
79  */
80  class OverlapCallback: public rp3d::OverlapCallback
81  {
82  public:
84  virtual void notifyOverlap(rp3d::CollisionBody *body);
85 
86  private:
87  /// Parent CameraNodelet instance
89  };
90 
91 
92  // Static members
93  // Note: the timers need to be static since stopped by the SIGINT callback
94  static sig_atomic_t volatile b_sigint_; ///< Whether SIGINT signal has been received
95  static ros::Timer main_timer_; ///< Timer callback for the main function
96 
97  // Private members
98  ros::NodeHandle nh_; ///< Node handler (for topics and services)
99  ros::NodeHandle private_nh_; ///< Private node handler (for parameters)
100  ros::Subscriber algae_sub_; ///< Subscriber for the algae of the farm
101  ros::ServiceServer ray_multi_serv_; ///< Service for raycasting from several camera poses
102  ros::Publisher out_pub_; ///< Publisher for the camera output
103  ros::Publisher rviz_pub_; ///< Publisher for Rviz markers
104  tf2_ros::Buffer tf_buffer_;
105  tf2_ros::TransformListener tf_listener_;
106 
107  mf_farm_simulator::AlgaeConstPtr last_algae_msg_; ///< Last algae message
108  bool algae_msg_received_; ///< Whether an algae message has been received
109  geometry_msgs::TransformStamped fixed_camera_tf_; ///< Transform from fixed frame to camera
110  geometry_msgs::TransformStamped camera_fixed_tf_; ///< Transform from camera to fixed frame
111  geometry_msgs::TransformStamped camera_robot_tf_; ///< Transform from camera to robot frame
112  geometry_msgs::TransformStamped robot_camera_tf_; ///< Transform from robot to camera frame
113  std::vector<std::vector<std::vector<float>>> heatmaps_; ///< Disease heatmatps for all the algae
114  std::vector<int> corr_algae_; ///< Correspondance between the algae used for raytracing and all the others
115  std::mutex coll_mutex_; ///< Mutex to control access to collision variables
116 
117  /// \name Collision members
118  ///@{
119  bool world_init_; ///< Whether the collision world has been initialised
120  rp3d::CollisionWorld coll_world_; ///< World with all algae and camera FOV
121  rp3d::CollisionWorld ray_world_; ///< World with algae colliding with FOV
122  rp3d::WorldSettings world_settings_; ///< Collision world settings
123  std::vector<rp3d::CollisionBody*> algae_bodies_; ///< Collision bodies of the algae
124  std::vector<rp3d::CollisionBody*> ray_bodies_; ///< Collision bodies for raycasting
125  rp3d::CollisionBody* fov_body_; ///< Collision body of the camera FOV
126  std::vector<box_shape_ptr> algae_shapes_; ///< Collision shapes of the algae bodies
127  std::vector<box_shape_ptr> ray_shapes_; ///< Collision shapes of algae for raycasting
128  box_shape_ptr fov_shape_; ///< Collision shapes of the FOV body
129 
130  RaycastCallback raycast_cb_; ///< Callback instance for raycasting
131  OverlapCallback overlap_cb_; ///< Callback instance for overlap detection
132  ///@}
133 
134 
135  /// \name ROS parameters
136  ///@{
137  float camera_freq_; ///< Frequency of the sensor
138  std::string fixed_frame_; ///< Frame in which the pose is expressed
139  std::string robot_frame_; ///< Frame of the robot
140  std::string camera_frame_; ///< Frame of the camera
141  std::vector<float> fov_color_; ///< Color of the camera field of view Rviz marker
142 
143  float focal_length_; ///< Focal length of the camera
144  float sensor_width_; ///< Width of the camera sensor
145  float sensor_height_; ///< Height of the camera sensor
146  float fov_distance_; ///< Maximum distance detected by the camera
147  int n_pxl_height_; ///< Nbr of pixels along sensor height
148  int n_pxl_width_; ///< Nbr of pixels along sensor width
149 
150  bool noise_meas_; ///< Whether to noise measurements on disease heatmap
151  float noise_std_; ///< Maximum standard deviation of the measurement noise
152  float noise_decay_; ///< Spatial decay rate for measurement noise standard deviation
153  ///@}
154 
155 
156  /**
157  * \brief Main callback which is called by a timer
158  *
159  * \param timer_event Timer event information
160  */
161  void main_cb(const ros::TimerEvent &timer_event);
162 
163  /**
164  * \brief SINGINT (Ctrl+C) callback to stop the nodelet properly
165  */
166  static void sigint_handler(int s);
167 
168  /**
169  * \brief Callback for the algae of the farm
170  *
171  * \param msg Pointer to the algae
172  */
173  void algae_cb(const mf_farm_simulator::AlgaeConstPtr msg);
174 
175  /**
176  * \brief Initialise the collision world
177  */
178  void init_coll_world();
179 
180  /**
181  * \brief Updates algae in the collision world
182  */
183  void update_algae();
184 
185  /**
186  * \brief Gets tf transforms
187  *
188  * \return Whether a transform has been received
189  */
190  bool get_tf();
191 
192  /**
193  * \brief Fill a collision body for multi-pose FOV overlap
194  *
195  * The collision body is the smallest AABB containing each FOV of each
196  * pose. The corresponding collision shape is also filled.
197  *
198  * \param [in] poses Vector of poses
199  * \param [out] body Body to fill
200  * \param [out] shape Collision shape of the body
201  * \param [in] stamp Time at which to retrieve ROS transforms
202  * return Whether the call was successful
203  */
204  bool multi_fov_body(
205  const std::vector<geometry_msgs::Pose> &poses,
206  rp3d::CollisionBody* body,
207  std::unique_ptr<rp3d::BoxShape> &shape,
208  ros::Time stamp = ros::Time(0)
209  );
210 
211  /**
212  * \brief Service callback for raycasting from several camera poses
213  *
214  * This service raycast one line for each corner of the camera screen. It
215  * only returns the hit points position, not the algae disease values.
216  */
217  bool ray_multi_cb(mf_sensors_simulator::MultiPoses::Request &req,
218  mf_sensors_simulator::MultiPoses::Response &res);
219 
220  /**
221  * \brief Publishes a Rviz marker for the camera field of view
222  */
223  void publish_rviz_fov();
224 
225  /**
226  * \brief Updates pose of field of view body
227  */
228  void update_fov_pose();
229 
230  /**
231  * \brief Selects algae that are in field of view of the camera
232  *
233  * The function will update `CameraNodelet::corr_algae_`, `CameraNodelet::ray_world_`,
234  * `CameraNodelet::ray_bodies_` and `CameraNodelet::ray_shapes_`.
235  *
236  * \param body Collision body to check overlap with algae
237  */
238  void overlap_fov(rp3d::CollisionBody* body);
239 
240  /**
241  * \brief Gets position, dimension and axes of the algae for raycasting
242  *
243  * \param [out] w_algae Width of the algae
244  * \param [out] h_algae Height of the algae
245  * \param [out] inc_y3 Increment along y3 algae axis
246  * \param [out] inc_z3 Increment along z3 algae axis
247  * \param [out] tf_algae Transforms of algae local frames
248  */
249  void get_ray_algae_carac(
250  std::vector<float> &w_algae, std::vector<float> &h_algae,
251  std::vector<float> &inc_y3, std::vector<float> &inc_z3,
252  std::vector<geometry_msgs::TransformStamped> &tf_algae
253  );
254 
255  /**
256  * \brief Gets an aim point from pixel coordinates for raycasting
257  *
258  * The raycast will be performed between the camera origin and this aim
259  * point. The norm of the aim point is the field of view distance.
260  *
261  * \param pxl_h Pixel coordinate in height axis
262  * \param pxl_w Pixel coordinate in width axis
263  * \param n_pxl_h Custom total number of pixels of the camera in height (defaulted to global value)
264  * \param n_pxl_w Custom total number of pixels of the camera in width (defaulted to global value)
265  * \return The corresponding aim point
266  */
267  tf2::Vector3 get_aim_pt(int pxl_h, int pxl_w, int n_pixel_h = -1, int n_pixel_w = -1);
268 
269  /**
270  * \brief Converts a tf2 vector to a rp3d vector
271  *
272  * \param vect Vector to convert
273  */
274  inline rp3d::Vector3 tf2_to_rp3d(const tf2::Vector3 vect);
275 
276  /**
277  * \brief Converts a pose to a transform
278  *
279  * \warning This doesn't take into account frame ids and doesn't fill header
280  *
281  * \param pose Pose to convert
282  * \return Converted transform
283  */
284  inline geometry_msgs::TransformStamped pose_to_tf(const geometry_msgs::Pose &pose);
285 
286  /**
287  * \brief Inverse a transform
288  *
289  * \warning Doesn't fill the header
290  *
291  * \param transform Transform to inverse
292  * \return Inversed transform
293  */
294  inline geometry_msgs::TransformStamped inverse_tf(
295  const geometry_msgs::TransformStamped &transform);
296 
297  /**
298  * \brief Combine transforms sequentially
299  *
300  * \param transforms List of transform to combine
301  * \return Product of all transforms
302  */
303  geometry_msgs::TransformStamped combine_transforms(
304  const std::vector<geometry_msgs::TransformStamped> &transforms);
305 
306  /**
307  * \brief Applies a transform to a vector
308  *
309  * \param [in] in_vector Vector to transform
310  * \param [in] transform Transform to apply
311  * return Transformed vector
312  */
313  tf2::Vector3 apply_transform(const tf2::Vector3 &in_vector,
314  const geometry_msgs::TransformStamped &transform);
315 
316  /**
317  * \brief Casts a ray on algae and gets hit point
318  *
319  * \param [in] aim_pt Point towards which casting the ray (in camera frame)
320  * \param [out] hit_pt Hit point (in fixed frame)
321  * \param [out] alga_idx Index of the hit alga in the ray_bodies_ vector
322  * \param [in] origin Origin of the ray (in camera frame)
323  * \param [in] fixed_camera_tf Transform from fixed to camera frames
324  * \return Whether an alga has been hit
325  */
326  bool raycast_alga(
327  const tf2::Vector3 &aim_pt,
328  tf2::Vector3 &hit_pt,
329  int &alga_idx,
330  const geometry_msgs::TransformStamped &fixed_camera_tf,
331  const tf2::Vector3 &origin = tf2::Vector3(0, 0, 0)
332  );
333 
334  /**
335  * \brief Casts a ray on algae and gets hit distance
336  *
337  * \param [in] aim_pt Point towards which casting the ray (in camera frame)
338  * \param [out] distance Distance to the hit alga
339  * \param [in] origin Origin of the ray (in camera frame)
340  * \param [in] fixed_camera_tf Transform from fixed to camera frames
341  * \return Whether an alga has been hit
342  */
343  bool raycast_alga(
344  const tf2::Vector3 &aim_pt,
345  float &distance,
346  const geometry_msgs::TransformStamped &fixed_camera_tf,
347  const tf2::Vector3 &origin = tf2::Vector3(0, 0, 0)
348  );
349 
350  /*
351  * \brief Raycast for each pixel of a camera for a specified viewpoint
352  *
353  * This method is trying to minimise the number of casted rays with some
354  * assumption. It starts by casting a ray for each corner of the camera
355  * screen. If the four rays hit something, the remaining pixels hit positions
356  * are interpolated in between. Otherwise, it casts a ray for each pixel.
357  *
358  * Therefore this method assumes that the four corners lie on a plane, which
359  * will be the case for an algae wall, but not when dealing with lots of
360  * algae.
361  *
362  * \note The code refers to two different frames: the viewpoint frame which
363  * is a virtual frame ; and the global camera frame which is the frame
364  * of the actual robot camera.
365  *
366  * \note It will transform the viewpoint in global camera frame. So it
367  * assumes `CameraNodelet::camera_robot_tf_` is up to date.
368  *
369  * \param [in] vp_pose Pose of the viewpoint in camera frame
370  * \param [in] n_pxl_h Number of pixels of the camera in height direction
371  * \param [in] n_pxl_w Number of pixels of the camera in width direction
372  * \param [out] pxl_output Hit points for all pixels
373  * \param [in] stamp Pose at which to fetch the ROS transforms
374  */
375  bool raycast_wall(
376  const geometry_msgs::Pose &vp_pose,
377  int n_pxl_h, int n_pxl_w,
378  mf_sensors_simulator::CameraOutput &pxl_output,
379  ros::Time stamp = ros::Time(0)
380  );
381 
382  /**
383  * \brief Interpolates a 3D quadrilateral lying on a plane
384  *
385  * It uses bilinear mapping to transform points in [-1, 1]x[-1, 1] to 3D
386  * points inside a quadrilateral defined by its four corners.
387  *
388  * For \f$ (u, v) \in [-1, 1]^2 \f$, the mapping to corresponding
389  * \f$ (x, y, z) \f$ coordinates is as follow:
390  * - \f$ x(u, v) = \alpha_0 + \alpha_1 u + \alpha_2 v + \alpha_3 u v \f$
391  * - \f$ y(u, v) = \beta_0 + \beta_1 u + \beta_2 v + \beta_3 u v \f$
392  * - \f$ z(u, v) = \gamma_0 + \gamma_1 u + \gamma_2 v + \gamma_3 u v \f$
393  *
394  * Where \f$ \alpha \f$, \f$ \beta \f$ and \f$ \gamma \f$ are determined
395  * thanks to the corner points. For more information, you can refer to:
396  * _The Finite Element Method: Linear Static and Dynamic Finite Element
397  * Analysis_ by Thomas J. R. Hughes (chapter 3.2).
398  *
399  * \note - The four corners are not added.
400  *
401  * \note - Points will be emplaced back to the x, y, and z lists, so it
402  * assumes that their size is already reserved before.
403  *
404  * \param [in] p1 Top left corner of the quadrilateral
405  * \param [in] p2 Bottom left corner of the quadrilateral
406  * \param [in] p3 Bottom right corner of the quadrilateral
407  * \param [in] p4 Top right corner of the quadrilateral
408  * \param [in] n_h Number of points to interpolate in the height direction
409  * \param [in] n_w Number of points to interpolate in the width direction
410  * \param [out] x_list X coordinates of the interpolated points
411  * \param [out] y_list Y coordinates of the interpolated points
412  * \param [out] z_list Z coordinates of the interpolated points
413  */
414  void interpolate_quadri(
415  const tf2::Vector3 &p1, const tf2::Vector3 &p2, const tf2::Vector3 &p3, const tf2::Vector3 &p4,
416  int n_h, int n_w,
417  std::vector<float> &x_list, std::vector<float> &y_list, std::vector<float> &z_list
418  );
419 
420  /**
421  * \brief Prepares the ROS output messages
422  *
423  * \param [out] out_msgs Camera output message
424  * \param [out] ray_marker Rviz marker for displaying the rays
425  * \param [out] pts_marker Rviz marker for displaying the hit points
426  */
427  void prepare_out_msgs(
428  mf_sensors_simulator::CameraOutput &out_msg,
429  visualization_msgs::Marker &ray_marker,
430  visualization_msgs::Marker &pts_marker
431  );
432 
433  /**
434  * \brief Add a point to a point marker
435  *
436  * \param [out] marker Marker to fill
437  * \param [in] pt Point to add to the marker
438  * \param [in] color_r Red channel of the point color
439  * \param [in] color_g Green channel of the point color
440  * \param [in] color_b Blue channel of the point color
441  */
442  void add_pt_to_marker(visualization_msgs::Marker &marker,
443  const tf2::Vector3 &pt, float color_r, float color_g, float color_b);
444 
445  /**
446  * \brief Add a point to a point marker
447  *
448  * \param [out] marker Marker to fill
449  * \param [in] pt1 First point to add to the marker
450  * \param [in] pt2 Second point to add to the marker
451  */
452  void add_line_to_marker(visualization_msgs::Marker &marker,
453  const tf2::Vector3 &pt1, const tf2::Vector3 &pt2);
454 
455  /**
456  * \brief Publishes camera output
457  */
458  void publish_output();
459 
460 };
461 
462 
463 inline rp3d::Vector3 CameraNodelet::tf2_to_rp3d(const tf2::Vector3 vect)
464 {
465  return rp3d::Vector3(vect.getX(), vect.getY(), vect.getZ());
466 }
467 
468 
469 inline geometry_msgs::TransformStamped CameraNodelet::pose_to_tf(
470  const geometry_msgs::Pose &pose)
471 {
472  geometry_msgs::TransformStamped transf;
473  transf.transform.translation.x = pose.position.x;
474  transf.transform.translation.y = pose.position.y;
475  transf.transform.translation.z = pose.position.z;
476  transf.transform.rotation.x = pose.orientation.x;
477  transf.transform.rotation.y = pose.orientation.y;
478  transf.transform.rotation.z = pose.orientation.z;
479  transf.transform.rotation.w = pose.orientation.w;
480 
481  return transf;
482 }
483 
484 
485 inline geometry_msgs::TransformStamped CameraNodelet::inverse_tf(
486  const geometry_msgs::TransformStamped &transform)
487 {
488  tf2::Vector3 trans(transform.transform.translation.x,
489  transform.transform.translation.y,
490  transform.transform.translation.z);
491  tf2::Quaternion orient(transform.transform.rotation.x,
492  transform.transform.rotation.y,
493  transform.transform.rotation.z,
494  transform.transform.rotation.w);
495 
496  tf2::Transform inverse = tf2::Transform(orient, trans).inverse();
497  trans = inverse.getOrigin();
498  orient = inverse.getRotation();
499 
500  geometry_msgs::TransformStamped ret;
501  ret.transform.translation.x = trans.getX();
502  ret.transform.translation.y = trans.getY();
503  ret.transform.translation.z = trans.getZ();
504  ret.transform.rotation.x = orient.getX();
505  ret.transform.rotation.y = orient.getY();
506  ret.transform.rotation.z = orient.getZ();
507  ret.transform.rotation.w = orient.getW();
508 
509  return ret;
510 
511 }
512 
513 
514 } // namespace mfcpp
515 
516 #endif
void get_ray_algae_carac(std::vector< float > &w_algae, std::vector< float > &h_algae, std::vector< float > &inc_y3, std::vector< float > &inc_z3, std::vector< geometry_msgs::TransformStamped > &tf_algae)
Gets position, dimension and axes of the algae for raycasting.
Definition: collision.cpp:174
float noise_std_
Maximum standard deviation of the measurement noise.
Definition: common.hpp:23
std::vector< int > corr_algae_
Correspondance between the algae used for raytracing and all the others.
bool world_init_
Whether the collision world has been initialised.
bool algae_msg_received_
Whether an algae message has been received.
float focal_length_
Focal length of the camera.
void publish_output()
Publishes camera output.
Definition: output.cpp:165
void algae_cb(const mf_farm_simulator::AlgaeConstPtr msg)
Callback for the algae of the farm.
virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo &info)
Definition: collision.cpp:59
int n_pxl_width_
Nbr of pixels along sensor width.
static ros::Timer main_timer_
Timer callback for the main function.
ros::NodeHandle nh_
Node handler (for topics and services)
rp3d::CollisionWorld ray_world_
World with algae colliding with FOV.
void overlap_fov(rp3d::CollisionBody *body)
Selects algae that are in field of view of the camera.
Definition: collision.cpp:160
rp3d::CollisionWorld coll_world_
World with all algae and camera FOV.
float camera_freq_
Frequency of the sensor.
std::vector< std::vector< std::vector< float > > > heatmaps_
Disease heatmatps for all the algae.
tf2::Vector3 apply_transform(const tf2::Vector3 &in_vector, const geometry_msgs::TransformStamped &transform)
Applies a transform to a vector.
Definition: collision.cpp:257
box_shape_ptr fov_shape_
Collision shapes of the FOV body.
virtual void onInit()
Function called at beginning of nodelet execution.
Declaration of common Rviz display functions.
geometry_msgs::TransformStamped fixed_camera_tf_
Transform from fixed frame to camera.
ros::NodeHandle private_nh_
Private node handler (for parameters)
static sig_atomic_t volatile b_sigint_
Whether SIGINT signal has been received.
std::vector< box_shape_ptr > ray_shapes_
Collision shapes of algae for raycasting.
CameraNodelet * parent_
Parent CameraNodelet instance.
bool raycast_wall(const geometry_msgs::Pose &vp_pose, int n_pxl_h, int n_pxl_w, mf_sensors_simulator::CameraOutput &pxl_output, ros::Time stamp=ros::Time(0))
Definition: collision.cpp:321
geometry_msgs::TransformStamped pose_to_tf(const geometry_msgs::Pose &pose)
Converts a pose to a transform.
void prepare_out_msgs(mf_sensors_simulator::CameraOutput &out_msg, visualization_msgs::Marker &ray_marker, visualization_msgs::Marker &pts_marker)
Prepares the ROS output messages.
Definition: output.cpp:85
tf2_ros::Buffer tf_buffer_
std::vector< float > fov_color_
Color of the camera field of view Rviz marker.
std::unique_ptr< rp3d::BoxShape > box_shape_ptr
void update_algae()
Updates algae in the collision world.
void init_coll_world()
Initialise the collision world.
float distance(const geometry_msgs::Point &p1, const geometry_msgs::Point &p2)
Computes the the euclidean distance between two positions.
Definition: common.hpp:69
void main_cb(const ros::TimerEvent &timer_event)
Main callback which is called by a timer.
float fov_distance_
Maximum distance detected by the camera.
rp3d::Vector3 tf2_to_rp3d(const tf2::Vector3 vect)
Converts a tf2 vector to a rp3d vector.
void add_pt_to_marker(visualization_msgs::Marker &marker, const tf2::Vector3 &pt, float color_r, float color_g, float color_b)
Add a point to a point marker.
Definition: output.cpp:132
std::string robot_frame_
Frame of the robot.
geometry_msgs::TransformStamped inverse_tf(const geometry_msgs::TransformStamped &transform)
Inverse a transform.
void interpolate_quadri(const tf2::Vector3 &p1, const tf2::Vector3 &p2, const tf2::Vector3 &p3, const tf2::Vector3 &p4, int n_h, int n_w, std::vector< float > &x_list, std::vector< float > &y_list, std::vector< float > &z_list)
Interpolates a 3D quadrilateral lying on a plane.
Definition: collision.cpp:433
static void sigint_handler(int s)
SINGINT (Ctrl+C) callback to stop the nodelet properly.
float sensor_height_
Height of the camera sensor.
void add_line_to_marker(visualization_msgs::Marker &marker, const tf2::Vector3 &pt1, const tf2::Vector3 &pt2)
Add a point to a point marker.
Definition: output.cpp:150
rp3d::WorldSettings world_settings_
Collision world settings.
mf_farm_simulator::AlgaeConstPtr last_algae_msg_
Last algae message.
bool raycast_alga(const tf2::Vector3 &aim_pt, tf2::Vector3 &hit_pt, int &alga_idx, const geometry_msgs::TransformStamped &fixed_camera_tf, const tf2::Vector3 &origin=tf2::Vector3(0, 0, 0))
Casts a ray on algae and gets hit point.
Definition: collision.cpp:271
Callback class for raycasting.
geometry_msgs::TransformStamped robot_camera_tf_
Transform from robot to camera frame.
std::string fixed_frame_
Frame in which the pose is expressed.
geometry_msgs::TransformStamped camera_robot_tf_
Transform from camera to robot frame.
std::mutex coll_mutex_
Mutex to control access to collision variables.
Callback class for overlap detection.
RaycastCallback(CameraNodelet *parent)
Definition: collision.cpp:28
ros::Publisher rviz_pub_
Publisher for Rviz markers.
bool get_tf()
Gets tf transforms.
ros::Publisher out_pub_
Publisher for the camera output.
void update_fov_pose()
Updates pose of field of view body.
Definition: collision.cpp:145
bool noise_meas_
Whether to noise measurements on disease heatmap.
std::vector< rp3d::CollisionBody * > ray_bodies_
Collision bodies for raycasting.
geometry_msgs::TransformStamped combine_transforms(const std::vector< geometry_msgs::TransformStamped > &transforms)
Combine transforms sequentially.
Definition: collision.cpp:223
ros::ServiceServer ray_multi_serv_
Service for raycasting from several camera poses.
bool ray_multi_cb(mf_sensors_simulator::MultiPoses::Request &req, mf_sensors_simulator::MultiPoses::Response &res)
Service callback for raycasting from several camera poses.
RaycastCallback raycast_cb_
Callback instance for raycasting.
ros::Subscriber algae_sub_
Subscriber for the algae of the farm.
OverlapCallback overlap_cb_
tf2_ros::TransformListener tf_listener_
int alga_idx_
Index of the hit alga in the ray_bodies_ vector.
std::string camera_frame_
Frame of the camera.
void publish_rviz_fov()
Publishes a Rviz marker for the camera field of view.
Definition: output.cpp:24
std::vector< rp3d::CollisionBody * > algae_bodies_
Collision bodies of the algae.
int n_pxl_height_
Nbr of pixels along sensor height.
tf2::Vector3 get_aim_pt(int pxl_h, int pxl_w, int n_pixel_h=-1, int n_pixel_w=-1)
Gets an aim point from pixel coordinates for raycasting.
Definition: collision.cpp:206
geometry_msgs::TransformStamped camera_fixed_tf_
Transform from camera to fixed frame.
bool alga_hit_
Whether an alga has been hit.
float sensor_width_
Width of the camera sensor.
CameraNodelet * parent_
Parent CameraNodelet instance.
Nodelet for a simulated camera.
std::vector< box_shape_ptr > algae_shapes_
Collision shapes of the algae bodies.
bool multi_fov_body(const std::vector< geometry_msgs::Pose > &poses, rp3d::CollisionBody *body, std::unique_ptr< rp3d::BoxShape > &shape, ros::Time stamp=ros::Time(0))
Fill a collision body for multi-pose FOV overlap.
Definition: collision.cpp:76
rp3d::CollisionBody * fov_body_
Collision body of the camera FOV.