Skip to content

Commit b242113

Browse files
authored
Merge pull request #40 from fmrico/set_robot_frame
Use TFInfo to unify TF specifications
2 parents 215314a + 853b254 commit b242113

46 files changed

Lines changed: 350 additions & 230 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

common/easynav_simple_common/src/easynav_simple_common/SimpleMap.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,8 @@ SimpleMap::downsample_factor(int factor) const
296296
}
297297
}
298298

299-
new_map->at(x, y) = (occupied_count > (factor * factor / 2));
299+
// Mark cell as occupied if any source cell in the block is occupied
300+
new_map->at(x, y) = (occupied_count > 0);
300301
}
301302
}
302303

common/easynav_simple_common/tests/simple_maps_tests.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ TEST_F(SimpleMapTest, DownsampleIntegerFactor)
172172
EXPECT_TRUE(downsampled->at(0, 0));
173173
EXPECT_FALSE(downsampled->at(1, 0));
174174
EXPECT_FALSE(downsampled->at(0, 1));
175-
EXPECT_FALSE(downsampled->at(1, 1));
175+
EXPECT_TRUE(downsampled->at(1, 1));
176176
}
177177

178178
/// \brief Downsampling to new resolution
@@ -195,9 +195,9 @@ TEST_F(SimpleMapTest, DownsampleToResolution)
195195
EXPECT_DOUBLE_EQ(downsampled->origin_x(), -1.0);
196196
EXPECT_DOUBLE_EQ(downsampled->origin_y(), -1.0);
197197

198-
EXPECT_FALSE(downsampled->at(0, 0));
199-
EXPECT_FALSE(downsampled->at(1, 1));
200-
EXPECT_FALSE(downsampled->at(2, 2));
198+
EXPECT_TRUE(downsampled->at(0, 0));
199+
EXPECT_TRUE(downsampled->at(1, 1));
200+
EXPECT_TRUE(downsampled->at(2, 2));
201201
}
202202

203203
/// \brief Downsample that results in cropped edges

controllers/easynav_mpc_controller/src/easynav_mpc_controller/MPCController.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include "easynav_mpc_controller/MPCController.hpp"
2424
#include "easynav_system/GoalManager.hpp"
2525

26+
#include "easynav_common/RTTFBuffer.hpp"
27+
2628
namespace easynav
2729
{
2830

@@ -201,9 +203,11 @@ MPCController::update_rt(NavState & nav_state)
201203
const auto & last_pose = path.poses[local_horizon].pose.position;
202204

203205
const auto & perceptions = nav_state.get<PointPerceptions>("points");
206+
const auto & tf_info = RTTFBuffer::getInstance()->get_tf_info();
207+
204208
const auto & filtered = PointPerceptionsOpsView(perceptions)
205209
.filter({-2.0, -0.35, -1.0}, {0.0, 0.35, 1.0})
206-
.fuse("map")
210+
.fuse(tf_info.map_frame)
207211
.filter({NAN, NAN, 0.1}, {NAN, NAN, NAN})
208212
.collapse({NAN, NAN, 0.1})
209213
.downsample(0.1)

controllers/easynav_mppi_controller/src/easynav_mppi_controller/MPPIController.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
#include "easynav_mppi_controller/MPPIController.hpp"
2626
#include "easynav_common/types/PointPerception.hpp"
27+
#include "easynav_common/RTTFBuffer.hpp"
28+
2729
#include "easynav_system/GoalManager.hpp"
2830

2931
#include "nav_msgs/msg/odometry.hpp"
@@ -78,14 +80,15 @@ void MPPIController::publish_mppi_markers(
7880
const std::vector<std::vector<std::pair<double, double>>> & all_trajs,
7981
const std::vector<std::pair<double, double>> & best_traj)
8082
{
83+
const auto & tf_info = RTTFBuffer::getInstance()->get_tf_info();
8184
visualization_msgs::msg::MarkerArray candidates;
8285
visualization_msgs::msg::MarkerArray optimal;
8386
int id = 0;
8487

8588
// Candidates in blue
8689
for (const auto & traj : all_trajs) {
8790
visualization_msgs::msg::Marker marker;
88-
marker.header.frame_id = "map";
91+
marker.header.frame_id = tf_info.map_frame;
8992
marker.header.stamp = rclcpp::Clock().now();
9093
marker.ns = "mppi_candidates";
9194
marker.id = id++;
@@ -110,7 +113,7 @@ void MPPIController::publish_mppi_markers(
110113

111114
// Best trajectory in red
112115
visualization_msgs::msg::Marker best_marker;
113-
best_marker.header.frame_id = "map";
116+
best_marker.header.frame_id = tf_info.map_frame;
114117
best_marker.header.stamp = rclcpp::Clock().now();
115118
best_marker.ns = "mppi_optimal_path";
116119
best_marker.id = id++;
@@ -188,10 +191,10 @@ MPPIController::update_rt(NavState & nav_state)
188191

189192
const auto & pose = nav_state.get<nav_msgs::msg::Odometry>("robot_pose").pose.pose;
190193
const auto & perceptions = nav_state.get<PointPerceptions>("points");
191-
194+
const auto & tf_info = RTTFBuffer::getInstance()->get_tf_info();
192195
const auto & filtered = PointPerceptionsOpsView(perceptions)
193196
.filter({-1.0, -1.0, -1.0}, {1.0, 1.0, 1.0})
194-
.fuse("map")
197+
.fuse(tf_info.map_frame)
195198
.filter({NAN, NAN, 0.1}, {NAN, NAN, NAN})
196199
.collapse({NAN, NAN, 0.1})
197200
.downsample(0.1)

controllers/easynav_serest_controller/src/easynav_serest_controller/SerestController.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
3030

3131
#include "easynav_common/types/PointPerception.hpp"
32+
#include "easynav_common/RTTFBuffer.hpp"
3233

3334
#include "easynav_serest_controller/SerestController.hpp"
3435
#include "pluginlib/class_list_macros.hpp"
@@ -304,9 +305,11 @@ SerestController::closest_obstacle_distance(
304305
if (!nav_state.has("points")) {return std::numeric_limits<double>::infinity();}
305306

306307
const auto & perceptions = nav_state.get<PointPerceptions>("points");
308+
const auto & tf_info = RTTFBuffer::getInstance()->get_tf_info();
309+
307310
auto fused = PointPerceptionsOpsView(perceptions)
308311
.downsample(0.3)
309-
.fuse(get_tf_prefix() + "base_link")
312+
.fuse(tf_info.robot_frame)
310313
.filter({-dist_search_radius_, -dist_search_radius_, NAN},
311314
{dist_search_radius_, dist_search_radius_, 2.0})
312315
.collapse({NAN, NAN, 0.1})
@@ -367,8 +370,10 @@ SerestController::fetch_required_inputs(
367370
nav_msgs::msg::Path & path,
368371
nav_msgs::msg::Odometry & odom)
369372
{
373+
const auto & tf_info = RTTFBuffer::getInstance()->get_tf_info();
374+
370375
if (!nav_state.has("path") || !nav_state.has("robot_pose") || !nav_state.has("map.dynamic")) {
371-
publish_stop(nav_state, "base_link");
376+
publish_stop(nav_state, tf_info.robot_frame);
372377
return false;
373378
}
374379

controllers/easynav_simple_controller/tests/simple_controller_tests.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,12 @@ TEST_F(AMCLLocalizerTest, SavemapServiceWorks)
144144
{
145145
auto node = std::make_shared<rclcpp_lifecycle::LifecycleNode>("test_savemap_node");
146146
auto manager = std::make_shared<easynav::SimpleController>();
147+
easynav::TFInfo tf_info;
148+
tf_info.map_frame = "world_map";
149+
tf_info.odom_frame = "world_odom";
150+
tf_info.robot_frame = "world_base";
151+
easynav::RTTFBuffer::getInstance()->set_tf_info(tf_info);
152+
147153
manager->initialize(node, "test_savemap");
148154

149155
auto static_map = std::make_shared<easynav::SimpleMap>();

controllers/easynav_vff_controller/src/easynav_vff_controller/VffController.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,11 @@ std::expected<void, std::string> VffController::on_initialize()
6262
node->get_parameter<double>(plugin_name + ".max_speed", max_speed_);
6363
node->get_parameter<double>(plugin_name + ".max_angular_speed", max_angular_speed_);
6464

65+
const auto & tf_info = RTTFBuffer::getInstance()->get_tf_info();
66+
6567
// Initialize the odometry message
6668
cmd_vel_.header.stamp = node->now();
67-
cmd_vel_.header.frame_id = get_tf_prefix() + "base_link";
69+
cmd_vel_.header.frame_id = tf_info.robot_frame;
6870
cmd_vel_.twist.linear.x = 0.0;
6971
cmd_vel_.twist.linear.y = 0.0;
7072
cmd_vel_.twist.linear.z = 0.0;
@@ -213,9 +215,10 @@ void VffController::update_rt(NavState & nav_state)
213215
if (!nav_state.has("robot_pose")) {return;}
214216

215217
const auto & all_goals = nav_state.get<nav_msgs::msg::Goals>("goals");
218+
const auto & tf_info = RTTFBuffer::getInstance()->get_tf_info();
216219

217220
if (all_goals.goals.empty()) {
218-
cmd_vel_.header.frame_id = get_tf_prefix() + "map";
221+
cmd_vel_.header.frame_id = tf_info.map_frame;
219222
cmd_vel_.header.stamp = get_node()->now();
220223
cmd_vel_.twist.linear.x = 0.0;
221224
cmd_vel_.twist.angular.z = 0.0;
@@ -259,17 +262,18 @@ void VffController::update_rt(NavState & nav_state)
259262

260263
const auto & perceptions = nav_state.get<PointPerceptions>("points");
261264

265+
const auto & tf_info = RTTFBuffer::getInstance()->get_tf_info();
262266
auto fused =
263267
PointPerceptionsOpsView(perceptions)
264268
.filter({-10.0, -10.0, -10.0}, {10.0, 10.0, 10.0})
265-
.fuse(get_tf_prefix() + "base_link")
269+
.fuse(tf_info.robot_frame)
266270
.filter({obstacle_detection_x_min_, obstacle_detection_y_min_, obstacle_detection_z_min_},
267271
{obstacle_detection_x_max_, obstacle_detection_y_max_,
268272
obstacle_detection_z_max_})
269273
.as_points();
270274

271275
// Get VFF vectors
272-
const VFFVectors & vff = get_vff(angle_error, fused, get_tf_prefix() + "base_link");
276+
const VFFVectors & vff = get_vff(angle_error, fused, tf_info.robot_frame);
273277

274278
// Use result vector to calculate output speed
275279
const auto & v = vff.result;

localizers/easynav_costmap_localizer/include/easynav_costmap_localizer/AMCLLocalizer.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,9 @@ class AMCLLocalizer : public LocalizerMethodBase
222222
/// Time interval (in seconds) after which the particles should be reseeded.
223223
double reseed_time_;
224224

225+
/// Timestamp of the last input message (odometry or initial pose).
226+
rclcpp::Time last_input_time_;
227+
225228
/// Timestamp of the last reseed event.
226229
rclcpp::Time last_reseed_;
227230
};

localizers/easynav_costmap_localizer/src/easynav_costmap_localizer/AMCLLocalizer.cpp

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ AMCLLocalizer::odom_callback(nav_msgs::msg::Odometry::UniquePtr msg)
322322
if (compute_odom_from_tf_) {return;}
323323

324324
tf2::fromMsg(msg->pose.pose, odom_);
325+
last_input_time_ = msg->header.stamp;
325326

326327
if (!initialized_odom_) {
327328
last_odom_ = odom_;
@@ -338,9 +339,9 @@ AMCLLocalizer::init_pose_callback(
338339
}
339340

340341
auto logger = get_node()->get_logger();
341-
342+
const auto & tf_info = RTTFBuffer::getInstance()->get_tf_info();
342343
// Check expected frame
343-
const std::string expected_frame = get_tf_prefix() + std::string("map");
344+
const std::string expected_frame = tf_info.map_frame;
344345
if (!msg->header.frame_id.empty() && msg->header.frame_id != expected_frame) {
345346
RCLCPP_WARN(
346347
logger,
@@ -485,10 +486,13 @@ AMCLLocalizer::init_pose_callback(
485486
void
486487
AMCLLocalizer::update_odom_from_tf()
487488
{
489+
const auto & tf_info = RTTFBuffer::getInstance()->get_tf_info();
490+
488491
geometry_msgs::msg::TransformStamped tf_msg;
489492
try {
490493
tf_msg = RTTFBuffer::getInstance()->lookupTransform(
491-
"odom", "base_footprint", tf2::TimePointZero, tf2::durationFromSec(0.0));
494+
tf_info.odom_frame, tf_info.robot_frame, tf2::TimePointZero,
495+
tf2::durationFromSec(0.0));
492496
} catch (const tf2::TransformException & ex) {
493497
RCLCPP_WARN(get_node()->get_logger(), "AMCLLocalizer::update: TF failed: %s", ex.what());
494498
return;
@@ -499,8 +503,11 @@ AMCLLocalizer::update_odom_from_tf()
499503

500504
last_odom_ = odom_;
501505
odom_ = tf_odom;
506+
last_input_time_ = tf_msg.header.stamp;
502507

503508
initialized_odom_ = true;
509+
510+
504511
}
505512

506513
void
@@ -578,9 +585,10 @@ AMCLLocalizer::correct(NavState & nav_state)
578585

579586
const auto & map_static = nav_state.get<Costmap2D>("map.static");
580587

588+
const auto & tf_info = RTTFBuffer::getInstance()->get_tf_info();
581589
const auto & filtered = PointPerceptionsOpsView(perceptions)
582590
.downsample(map_static.getResolution())
583-
.fuse(get_tf_prefix() + "base_footprint")
591+
.fuse(tf_info.robot_frame)
584592
.filter({NAN, NAN, 0.1}, {NAN, NAN, NAN})
585593
.collapse({NAN, NAN, 0.1})
586594
.downsample(map_static.getResolution())
@@ -716,9 +724,10 @@ void
716724
AMCLLocalizer::publishTF(const tf2::Transform & map2bf)
717725
{
718726
geometry_msgs::msg::TransformStamped tf_msg;
719-
tf_msg.header.stamp = get_node()->now();
720-
tf_msg.header.frame_id = get_tf_prefix() + "map";
721-
tf_msg.child_frame_id = get_tf_prefix() + "odom";
727+
tf_msg.header.stamp = last_input_time_;
728+
const auto & tf_info = RTTFBuffer::getInstance()->get_tf_info();
729+
tf_msg.header.frame_id = tf_info.map_frame;
730+
tf_msg.child_frame_id = tf_info.odom_frame;
722731
tf_msg.transform = tf2::toMsg(map2bf);
723732

724733
RTTFBuffer::getInstance()->setTransform(tf_msg, "easynav", false);
@@ -728,10 +737,11 @@ AMCLLocalizer::publishTF(const tf2::Transform & map2bf)
728737
void
729738
AMCLLocalizer::publishParticles()
730739
{
731-
geometry_msgs::msg::PoseArray array_msg;
732-
array_msg.header.stamp = get_node()->now();
733-
array_msg.header.frame_id = get_tf_prefix() + "map";
740+
const auto & tf_info = RTTFBuffer::getInstance()->get_tf_info();
734741

742+
geometry_msgs::msg::PoseArray array_msg;
743+
array_msg.header.stamp = last_input_time_;
744+
array_msg.header.frame_id = tf_info.map_frame;
735745
array_msg.poses.reserve(particles_.size());
736746
for (const auto & p : particles_) {
737747
geometry_msgs::msg::Pose pose_msg;
@@ -789,9 +799,10 @@ AMCLLocalizer::publishEstimatedPose(const tf2::Transform & est_pose)
789799
tf2::Matrix3x3 cov = computeCovariance(particles_, 0, N_top, mean);
790800
double yaw_variance = computeYawVariance(particles_, 0, N_top);
791801

802+
const auto & tf_info = RTTFBuffer::getInstance()->get_tf_info();
792803
geometry_msgs::msg::PoseWithCovarianceStamped msg;
793-
msg.header.stamp = get_node()->now();
794-
msg.header.frame_id = get_tf_prefix() + "map";
804+
msg.header.stamp = last_input_time_;
805+
msg.header.frame_id = tf_info.map_frame;
795806

796807
msg.pose.pose.position.x = mean.x();
797808
msg.pose.pose.position.y = mean.y();
@@ -813,9 +824,10 @@ AMCLLocalizer::get_pose()
813824
{
814825
nav_msgs::msg::Odometry odom_msg;
815826

816-
odom_msg.header.stamp = get_node()->now();
817-
odom_msg.header.frame_id = get_tf_prefix() + "map";
818-
odom_msg.child_frame_id = get_tf_prefix() + "base_footprint";
827+
odom_msg.header.stamp = last_input_time_;
828+
const auto & tf_info = RTTFBuffer::getInstance()->get_tf_info();
829+
odom_msg.header.frame_id = tf_info.map_frame;
830+
odom_msg.child_frame_id = tf_info.robot_frame;
819831

820832
tf2::Transform est_pose = getEstimatedPose();
821833

localizers/easynav_fusion_localizer/include/easynav_fusion_localizer/FusionLocalizer.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,6 @@ class FusionLocalizer : public easynav::LocalizerMethodBase
5555
int n_imu_sensors_{0};
5656
int n_gps_sensors_{0};
5757

58-
std::string base_link_frame_id_;
59-
std::string odom_frame_id_;
60-
std::string world_frame_id_;
61-
6258
geometry_msgs::msg::PoseWithCovarianceStamped
6359
navsatfix_to_pose(const sensor_msgs::msg::NavSatFix & navsat_msg);
6460

0 commit comments

Comments
 (0)