-
Notifications
You must be signed in to change notification settings - Fork 314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adjust Global Frame in odometry pipeline #331
Conversation
Short notice: We already discussed this on the ROS side in #241, but the PR got closed. The main issue was that the map was cleared instead of being transformed as done here. Actually, since we no longer keep track of the trajectory, this functionality is now easier to implement and also feels more natural. |
I also did something similar, but mainly for resetting the poses. I need to think about this one in particular, as calling that added method "spiritually" breaks the odometry assumption.... which is also not that hard given we already really on a local representation of the environment. Let's say I'm using this odometry source to path plan around a local map, if suddenly I get a pose from whatever source. then this will make the state of the robot jump immediately, even when the pose is being corrected to a global map. I'm not saying we shouldn't add this, as it doesn't hurt just leaving it there. And since the only consumer of this pipeline is ROS, this won't break anything. But I'm trying to think if this is worth adding here from a conceptual point of view. What's your view 🧘 ? |
Adding REP-105 as reference, which is what most people is using to stick to as a common referennce odom The coordinate frame called odom is a world-fixed frame. The pose of a mobile platform in the odom frame can drift over time, without any bounds. This drift makes the odom frame useless as a long-term global reference. However, the pose of a robot in the odom frame is guaranteed to be continuous, meaning that the pose of a mobile platform in the odom frame always evolves in a smooth way, without discrete jumps. In a typical setup the odom frame is computed based on an odometry source, such as wheel odometry, visual odometry or an inertial measurement unit. The odom frame is useful as an accurate, short-term local reference, but drift makes it a poor frame for long-term reference. map In a typical setup, a localization component constantly re-computes the robot pose in the map frame based on sensor observations, therefore eliminating drift, but causing discrete jumps when new sensor information arrives. The map frame is useful as a long-term global reference, but discrete jumps in position estimators make it a poor reference frame for local sensing and acting. |
I see your point, and from a ROS-centric perspective, this is right as, typically, the A better solution philosophically will be to make the what do you think? @nachovizzo @benemer |
attributes doesn't break
I got a proposal code now, check also the commit message |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see your point @nachovizzo. The new solution is a good compromise then, we at least give the user access to the members such that they can implement their own AdjustGlobalFrame, ResetOdometry, SetPose, or WhatEver :)
Great solution. This is exactly what I had in mind: providing const and non-const references. If in a downstream application, the user decides to mess up with the internal map representation, it would be explicit in the code and make more sense to me. Another example I was thinking to support this idea was the example of having a wheel odometry node that converts the encoder readings from the wheels of a robot in odometry messages. It would be strange to provide an API entry point to inject a reading from outside this context. But if I want to write a wheel odometry manager and do crazy stuff with it would be nice to have the opportunity. From the const point of view, it would be better not allow to modify the internal map representation, but this would force copying data, something that was already happening in the original proposal: void KissICP::adjustGlobalFrame(const Sophus::SE3d &global_frame_correction) {
last_pose_ = global_frame_correction * last_pose_;
KissICP::Vector3dVector map_points = local_map_.Pointcloud();
local_map_.Clear();
std::transform(map_points.cbegin(), map_points.cend(), map_points.begin(),
[&](const auto &p) { return global_frame_correction * p; });
local_map_.AddPoints(map_points);
} This might be the weak point of this nonconst ref API. but I believe it is worth taking the risk of this "unsafe" API to simplify consumption of the pipeline |
Me and @benemer added this change so that it is possible to adjust the global reference frame of KISS. This can be useful if one needs to adjust the pose estimate based on a new global pose measurement (coming from GPS, April tag localization system, or any indoor global localization system out there). Notice that this change only affects the CPP API, as a user can already do this manually in Python. For the ROS "API", this highly depends on the global measurement used, which we can probably also leave to the users in their custom nodes.