config and lib directories are only needed if you use parameters, or make a custom library.
Composition
Write your nodes as components! This means in your my_node.cpp file, you will just have your node class, and no main function. See this tutorial for more information.
You will have a node composition file (or multiple?), that should use executors to instantiate each node. See this page on executors.
We haven't really figured out what the best thing is to do for multiple nodes.
Do we have one main function per node, or one per package?
One executor per node, or per package?
Probably going to go with a single main function per package and figure out executors as we go.
Example node_composition.cpp
Custom Interfaces
If you create custom interfaces (messages, services, actions), you should create a separate package for them. This is due to CMake dependency issues with building messages in the same packages that uses them. There are suggested work arounds online, I havenn't been able to get any to work.
For example, if your package is called my_package, you will create another package called my_package_interfaces and use msg, srv, and action directories for your interfaces.
Parameter Files
Example
Launch Files
Rules
You must set a log level launch argument - see example. This allows us to control the log level from the launch file, and the terminal.
If using parameters, you must pass them to your node from your launch file.
Basic Example
Nodes
Each node is a class. Use header files.
Setup subscribers and publishers in class constructor
Write nodes as components
If you have a lot of complex functions - move them to a library
Throttle log messages that are very frequent, or set to DEBUG.
How to get parameters to your node
See lidar_prop_detector_component.cpp for an example. //TODO ADD LINK TO FILE
We need to inherit from rclcpp and make our own node class and add these functions in, but for now you can do the following.
Add to your node's header file:
Create member variables for each parameter starting with p_.
LidarPropDetector::getParam<double>("max_lidar_dist", p_max_lidar_dist_, 0.0, "Maximum accepted range of lidar readings in m");
LidarPropDetector::getParam<double>("min_lidar_dist", p_min_lidar_dist_, 0.0, "Minimum accepted range of lidar readings in m");
LidarPropDetector::getParam<int>("min_points_in_segment", p_min_points_in_segment_, 0, "Minimum accepted points in a laser_segment");
LidarPropDetector::getParam<double>("max_radius_diff", p_max_radius_diff_, 0.0, "Maximum difference between measured and expected prop radii to consider a laser_segment a prop, in m");
LidarPropDetector::getParam<double>("lidar_fov", p_lidar_fov_, 0.0, "Lidar fov in degrees");