16 #ifndef NAV2_LOOPBACK_SIM__LOOPBACK_SIMULATOR_HPP_
17 #define NAV2_LOOPBACK_SIM__LOOPBACK_SIMULATOR_HPP_
28 #include "nav2_ros_common/lifecycle_node.hpp"
29 #include "nav2_ros_common/service_client.hpp"
30 #include "nav2_util/twist_subscriber.hpp"
31 #include "nav2_loopback_sim/clock_publisher.hpp"
32 #include "rcl_interfaces/msg/set_parameters_result.hpp"
33 #include "geometry_msgs/msg/pose.hpp"
34 #include "geometry_msgs/msg/pose_with_covariance_stamped.hpp"
35 #include "geometry_msgs/msg/quaternion.hpp"
36 #include "geometry_msgs/msg/transform_stamped.hpp"
37 #include "geometry_msgs/msg/twist.hpp"
38 #include "geometry_msgs/msg/twist_stamped.hpp"
39 #include "geometry_msgs/msg/vector3.hpp"
40 #include "nav_msgs/msg/occupancy_grid.hpp"
41 #include "nav_msgs/msg/odometry.hpp"
42 #include "nav_msgs/srv/get_map.hpp"
43 #include "sensor_msgs/msg/laser_scan.hpp"
44 #include "nav2_ros_common/tf2_factories.hpp"
45 #include "tf2/LinearMath/Transform.hpp"
46 #include "tf2/LinearMath/Quaternion.hpp"
47 #include "tf2/LinearMath/Matrix3x3.hpp"
49 namespace nav2_loopback_sim
66 explicit LoopbackSimulator(
const rclcpp::NodeOptions & options = rclcpp::NodeOptions());
73 nav2::CallbackReturn
on_configure(
const rclcpp_lifecycle::State & state)
override;
77 nav2::CallbackReturn
on_activate(
const rclcpp_lifecycle::State & state)
override;
81 nav2::CallbackReturn
on_deactivate(
const rclcpp_lifecycle::State & state)
override;
85 nav2::CallbackReturn
on_cleanup(
const rclcpp_lifecycle::State & state)
override;
89 nav2::CallbackReturn
on_shutdown(
const rclcpp_lifecycle::State & state)
override;
94 void cmdVelCallback(
const geometry_msgs::msg::Twist::ConstSharedPtr & msg);
103 const geometry_msgs::msg::PoseWithCovarianceStamped::ConstSharedPtr & msg);
126 const std::vector<rclcpp::Parameter> & parameters);
145 geometry_msgs::msg::TransformStamped & map_to_odom,
146 geometry_msgs::msg::TransformStamped & odom_to_base_link);
150 void publishOdometry(
const geometry_msgs::msg::TransformStamped & odom_to_base_link);
160 void getLaserScan(
int num_samples, sensor_msgs::msg::LaserScan & scan_msg);
169 const geometry_msgs::msg::Quaternion & quaternion,
double yaw_to_add);
173 std::string base_frame_id_;
174 std::string map_frame_id_;
175 std::string odom_frame_id_;
176 std::string scan_frame_id_;
177 double odom_publish_dur_;
178 double scan_publish_dur_;
179 bool publish_map_odom_tf_;
180 double scan_range_min_;
181 double scan_range_max_;
182 double scan_angle_min_;
183 double scan_angle_max_;
184 double scan_angle_increment_;
186 double scan_noise_std_;
189 double speed_factor_;
192 std::optional<geometry_msgs::msg::Twist> curr_cmd_vel_;
193 rclcpp::Time curr_cmd_vel_time_;
194 bool has_initial_pose_{
false};
195 geometry_msgs::msg::Pose initial_pose_;
196 bool has_map_{
false};
197 nav_msgs::msg::OccupancyGrid map_;
198 bool has_base_to_laser_{
false};
199 tf2::Transform tf_base_to_laser_;
200 std::mt19937 rng_{std::random_device{}()};
201 geometry_msgs::msg::TransformStamped t_map_to_odom_;
202 geometry_msgs::msg::TransformStamped t_odom_to_base_link_;
205 nav2::TransformBroadcaster::SharedPtr tf_broadcaster_;
206 nav2::TransformBuffer::SharedPtr tf_buffer_;
207 nav2::TransformListener::SharedPtr tf_listener_;
209 nav2::Subscription<geometry_msgs::msg::PoseWithCovarianceStamped>::SharedPtr
211 std::unique_ptr<nav2_util::TwistSubscriber> cmd_vel_sub_;
213 nav2::Publisher<nav_msgs::msg::Odometry>::SharedPtr odom_pub_;
214 nav2::Publisher<sensor_msgs::msg::LaserScan>::SharedPtr scan_pub_;
216 nav2::ServiceClient<nav_msgs::srv::GetMap>::SharedPtr map_client_;
218 rclcpp::TimerBase::SharedPtr setup_timer_;
219 rclcpp::TimerBase::SharedPtr timer_;
220 rclcpp::TimerBase::SharedPtr odom_timer_;
221 rclcpp::TimerBase::SharedPtr scan_timer_;
223 std::unique_ptr<ClockPublisher> clock_publisher_;
224 rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr param_validator_;
225 rclcpp::node_interfaces::PostSetParametersCallbackHandle::SharedPtr param_updater_;
A lifecycle node wrapper to enable common Nav2 needs such as manipulating parameters.
A loopback simulator that replaces a physics simulator to create a frictionless, inertialess,...
void odomTimerCallback()
Periodic odometry publishing callback.
void cmdVelCallback(const geometry_msgs::msg::Twist::ConstSharedPtr &msg)
Callback for incoming cmd_vel (unstamped Twist)
rcl_interfaces::msg::SetParametersResult validateParameterUpdatesCallback(const std::vector< rclcpp::Parameter > ¶meters)
Validate dynamic parameter changes (pre-set callback)
std::tuple< double, double, double > getLaserPose()
Compute the laser pose in the map frame.
void publishTransforms(geometry_msgs::msg::TransformStamped &map_to_odom, geometry_msgs::msg::TransformStamped &odom_to_base_link)
Publish map->odom and odom->base_link transforms.
void publishOdometry(const geometry_msgs::msg::TransformStamped &odom_to_base_link)
Publish nav_msgs::Odometry from the current odom->base transform.
static geometry_msgs::msg::Quaternion addYawToQuat(const geometry_msgs::msg::Quaternion &quaternion, double yaw_to_add)
Add a yaw rotation to a quaternion.
void getMap()
Request the map from the map server.
void cmdVelStampedCallback(const geometry_msgs::msg::TwistStamped::ConstSharedPtr &msg)
Callback for incoming cmd_vel (stamped TwistStamped)
void updateParametersCallback(const std::vector< rclcpp::Parameter > ¶meters)
Apply validated dynamic parameter changes (post-set callback)
nav2::CallbackReturn on_configure(const rclcpp_lifecycle::State &state) override
Configure the node: declare parameters, create pubs/subs/timers.
void timerCallback()
Main update callback: integrates cmd_vel and publishes TF.
void initialPoseCallback(const geometry_msgs::msg::PoseWithCovarianceStamped::ConstSharedPtr &msg)
Callback for incoming initial pose.
nav2::CallbackReturn on_cleanup(const rclcpp_lifecycle::State &state) override
Cleanup the node: release all resources.
void publishLaserScan()
Publish a simulated laser scan from the map.
nav2::CallbackReturn on_deactivate(const rclcpp_lifecycle::State &state) override
Deactivate the node: stop timers, reset cmd_vel.
void getLaserScan(int num_samples, sensor_msgs::msg::LaserScan &scan_msg)
Raycast the map to fill a LaserScan message.
void setupTimerCallback()
Periodic setup callback: publishes identity TFs and fetches map.
LoopbackSimulator(const rclcpp::NodeOptions &options=rclcpp::NodeOptions())
Construct a LoopbackSimulator node.
nav2::CallbackReturn on_activate(const rclcpp_lifecycle::State &state) override
Activate the node: start publishing.
void getBaseToLaserTf()
Look up the static transform from base to laser frame.
nav2::CallbackReturn on_shutdown(const rclcpp_lifecycle::State &state) override
Shutdown the node.