My Project 1.0
Holistic Fusion: A Generic Framework for Multimodal Sensor Fusion
Loading...
Searching...
No Matches
Position3Estimator.cpp
Go to the documentation of this file.
1/*
2Copyright 2024 by Julian Nubert & Timon Mathis, Robotic Systems Lab & Autonomous Systems Lab, ETH Zurich.
3All rights reserved.
4This file is released under the "BSD-3-Clause License".
5Please see the LICENSE file that has been included as part of this package.
6 */
7
8// Implementation
10
11// C++
12#include <boost/filesystem.hpp>
13
14// Project
17
18// Workspace
22
23namespace position3_se {
24
25Position3Estimator::Position3Estimator(std::shared_ptr<ros::NodeHandle> privateNodePtr) : holistic_fusion::HolisticFusionRos(privateNodePtr) {
26 REGULAR_COUT << GREEN_START << " Position3Estimator-Constructor called." << COLOR_END << std::endl;
27
28 // Configurations ----------------------------
29 // Static Transforms
30 staticTransformsPtr_ = std::make_shared<Position3StaticTransforms>(
32
33 // GNSS Handler
34 gnssHandlerPtr_ = std::make_shared<holistic_fusion::GnssHandler>();
35
36 // Alignment Handler
37 trajectoryAlignmentHandler_ = std::make_shared<holistic_fusion::TrajectoryAlignmentHandler>();
38
39 // Setup
41}
42
43//---------------------------------------------------------------
45 REGULAR_COUT << GREEN_START << " Position3Estimator-Setup called." << COLOR_END << std::endl;
46
47 // Read parameters ----------------------------
49
50 // Super class
51 HolisticFusionRos::setup(staticTransformsPtr_);
52
53 // Publishers ----------------------------
55
56 // Subscribers ----------------------------
58
59 // Messages ----------------------------
61
62 // Services ----------------------------
64
65 // Static Transforms
66 staticTransformsPtr_->findTransformations();
67
68 // Wrap up ----------------------------
69 REGULAR_COUT << GREEN_START << " Set up successfully." << COLOR_END << std::endl;
70}
71
72//---------------------------------------------------------------
74 // Status
75 REGULAR_COUT << GREEN_START << " Initializing Publishers..." << COLOR_END << std::endl;
76
77 // Paths
79 pubMeasWorldPrismPositionPath_ = privateNode.advertise<nav_msgs::Path>("/holistic_fusion/measPosition_path_world_prism", ROS_QUEUE_SIZE);
80 }
82 pubMeasWorldGnssPositionPath_ = privateNode.advertise<nav_msgs::Path>("/holistic_fusion/measPosition_path_world_gnss", ROS_QUEUE_SIZE);
83 }
86 privateNode.advertise<nav_msgs::Path>("/holistic_fusion/measPosition_path_world_gnss_offline_pose", ROS_QUEUE_SIZE);
87 }
88}
89
91 // Prism Position
93 subPrismPosition_ = privateNode.subscribe<geometry_msgs::PointStamped>(
94 "/prism_position_topic", ROS_QUEUE_SIZE, &Position3Estimator::prismPositionCallback_, this, ros::TransportHints().tcpNoDelay());
95 }
96 // GNSS
98 subGnssPosition_ = privateNode.subscribe<sensor_msgs::NavSatFix>(
99 "/gnss_position_topic", ROS_QUEUE_SIZE, &Position3Estimator::gnssPositionCallback_, this, ros::TransportHints().tcpNoDelay());
100 }
101 // GNSS Offline Pose
104 privateNode.subscribe<nav_msgs::Odometry>("/gnss_offline_pose_topic", ROS_QUEUE_SIZE, &Position3Estimator::gnssOfflinePoseCallback_,
105 this, ros::TransportHints().tcpNoDelay());
106 }
107
108 // Log
109 std::cout << YELLOW_START << "FactorGraphFiltering" << COLOR_END << " Initialized Position subscriber (on position_topic)." << std::endl;
110}
111
112//---------------------------------------------------------------
114 // Status
115 REGULAR_COUT << GREEN_START << " Initializing Messages..." << COLOR_END << std::endl;
116
117 // Paths
118 measPosition_worldPrismPositionPathPtr_ = nav_msgs::PathPtr(new nav_msgs::Path);
119 measPosition_worldGnssPositionPathPtr_ = nav_msgs::PathPtr(new nav_msgs::Path);
120 measPosition_worldGnssOfflinePosePathPtr_ = nav_msgs::PathPtr(new nav_msgs::Path);
121}
122
123// --------------------------------------------------------------
125 // Trigger Prism Unary
128 privateNode.advertiseService("/atn_position3_fuser_node/togglePrismUnary", &Position3Estimator::srvTogglePrismUnaryCallback_, this);
129 }
130 // Trigger GNSS Unary
133 privateNode.advertiseService("/atn_position3_fuser_node/toggleGnssUnary", &Position3Estimator::srvToggleGnssUnaryCallback_, this);
134 }
135 // Trigger GNSS Offline Pose Unary
137 srvToggleGnssOfflinePoseUnary_ = privateNode.advertiseService("/atn_position3_fuser_node/toggleGnssOfflinePoseUnary",
139 }
140}
141
142// Overwritten service for offline optimization
143bool Position3Estimator::srvOfflineSmootherOptimizeCallback(holistic_fusion_ros_msgs::OfflineOptimizationTrigger::Request& req,
144 holistic_fusion_ros_msgs::OfflineOptimizationTrigger::Response& res) {
145 std::cout << "Position3Estimator: srvOfflineSmootherOptimizeCallback (derived class) called." << std::endl;
146 // Call parent class and create most of the files already
148
149 // File streams
150 std::map<std::string, std::ofstream> fileStreams;
151
152 // Write T_totalStation_totalStationOld_ to file ----------------------------
153 // Get time string by finding latest directory in optimizationResultLoggingPath
155 if (timeString.empty()) {
156 REGULAR_COUT << " Could not find latest directory in " << optimizationResultLoggingPath << std::endl;
157 return false;
158 } else {
159 REGULAR_COUT << " Found latest directory in " << optimizationResultLoggingPath << ": " << timeString << std::endl;
160 }
161 // Create file stream
162 std::string transformIdentifier = "R_6D_transform_" + totalStationReferenceFrame_ + "_to_" + totalStationReferenceFrame_ + "Old";
163 holistic_fusion::createPose3CsvFileStream(fileStreams, optimizationResultLoggingPath, transformIdentifier, timeString, false);
164 // Add to file
165 holistic_fusion::writePose3ToCsvFile(fileStreams, T_totalStation_totalStationOld_, transformIdentifier, ros::Time::now().toSec(), false);
166 REGULAR_COUT << " Wrote T_totalStation_totalStationOld to file." << std::endl;
167
168 // Depending on whether GNSS or Prism was used for initialization, write the corresponding T_W_R identity to file ------------------------
170 // Write T_totalStation_totalStationOld_ to file
171 std::string transformIdentifier = "R_6D_transform_" + staticTransformsPtr_->getWorldFrame() + "_to_" + gnssReferenceFrame_;
172 holistic_fusion::createPose3CsvFileStream(fileStreams, optimizationResultLoggingPath, transformIdentifier, timeString, false);
173 // Add to file
174 holistic_fusion::writePose3ToCsvFile(fileStreams, Eigen::Isometry3d::Identity(), transformIdentifier, ros::Time::now().toSec(), false);
175 REGULAR_COUT << " Wrote T_W_gnssReferenceFrame to file." << std::endl;
176 } else {
177 // Write T_totalStation_enu_ to file
178 std::string transformIdentifier = "R_6D_transform_" + staticTransformsPtr_->getWorldFrame() + "_to_" + totalStationReferenceFrame_;
179 holistic_fusion::createPose3CsvFileStream(fileStreams, optimizationResultLoggingPath, transformIdentifier, timeString, false);
180 // Add to file
181 holistic_fusion::writePose3ToCsvFile(fileStreams, T_totalStation_enu_, transformIdentifier, ros::Time::now().toSec(), false);
182 REGULAR_COUT << " Wrote T_W_totalStationReferenceFrame to file." << std::endl;
183 }
184
185 // Close all file streams
186 for (auto& pair : fileStreams) {
187 pair.second.close();
188 }
189 // Return
190 return success;
191}
192
193//---------------------------------------------------------------
194void Position3Estimator::prismPositionCallback_(const geometry_msgs::PointStamped::ConstPtr& leicaPositionPtr) {
195 // Counter
197
198 // Fixed Frame
199 std::string fixedFrame;
201 fixedFrame = staticTransformsPtr_->getWorldFrame();
202 } else {
203 fixedFrame = leicaPositionPtr->header.frame_id;
204 }
205
206 // Translate to Eigen
207 Eigen::Vector3d positionMeas = Eigen::Vector3d(leicaPositionPtr->point.x, leicaPositionPtr->point.y, leicaPositionPtr->point.z);
209
210 // Case: First call
212 REGULAR_COUT << " First prism position measurement received. Setting initial position to " << positionMeas.transpose() << std::endl;
213 // Set initial position
214 initialPrismPosition_ = positionMeas;
215 // Set Reference Frame
216 totalStationReferenceFrame_ = leicaPositionPtr->header.frame_id;
217 }
218
219 // Case: Not moved enough --> check if moved enough in meanwhile, only relevant if not initialized by GNSS
221 if ((positionMeas - initialPrismPosition_).norm() > PRISM_MOVED_ENOUGH_THRESHOLD) {
223 REGULAR_COUT << " Prism moved enough from initial position of " << initialPrismPosition_.transpose() << " to "
224 << positionMeas.transpose() << std::endl;
225 }
226 }
227
228 // Flag
229 bool addToGraphFlag = true;
230
231 // Case: Graph is not initialized by this callback, but instead by GNSS
233 trajectoryAlignmentHandler_->addR3Position(positionMeas, leicaPositionPtr->header.stamp.toSec());
234 // In radians
235 double yaw{0};
236 if (!(trajectoryAlignmentHandler_->alignTrajectories(yaw, T_totalStation_enu_))) {
237 if (prismPositionCallbackCounter_ % 10 == 0) {
238 REGULAR_COUT << " Graph was initialized by GNSS, hence trying to align. Trajectory alignment not ready. Waiting for more motion."
239 << std::endl;
240 }
241 addToGraphFlag = false;
242 } else {
244 // Only keep yaw of the orientation part of the transformation
245 REGULAR_COUT << GREEN_START << " Total Station to Old Total Station Transformation: " << COLOR_END
246 << T_totalStation_totalStationOld_.matrix() << std::endl;
248 REGULAR_COUT << GREEN_START << " Total Station to Old Total Station Transformation after removing roll and pitch: " << COLOR_END
249 << T_totalStation_totalStationOld_.matrix() << std::endl;
250 // Prepare for using this transformation in the graph
252 return; // Do not add unary measurement this round
253 }
254 }
255
256 // State Machine
258 // Try to initialize yaw and position if not done already
260 0.0, positionMeas, staticTransformsPtr_->getBaseLinkFrame(),
262 std::cout << "-------------------" << std::endl;
263 REGULAR_COUT << RED_START << " Prism callback is setting global yaw." << COLOR_END << std::endl;
264 std::cout << "-------------------" << std::endl;
265 REGULAR_COUT << " Set yaw and position successfully." << std::endl;
266 } else {
267 REGULAR_COUT << " Could not set yaw and position." << std::endl;
268 }
269 }
270 // Else if active
271 else if (usePrismPositionUnaryFlag_ && addToGraphFlag) {
272 const std::string& positionMeasFrame =
274 // Consider whether graph was initialized by GNSS or not ----------------------------
275 // if (initializedByGnssFlag_) {
276 // fixedFrame = leicaPositionPtr->header.frame_id;
277 // } else {
278 // fixedFrame = staticTransformsPtr_->getWorldFrame();
279 // }
280 // Potentially transform measurement to start ENU frame (if world origin was set to coincide with GNSS)
282 positionMeas = T_totalStation_totalStationOld_ * positionMeas;
283 }
284
285 // Already initialized --> add position measurement to graph ----------------------------
287 "LeicaPosition", int(prismPositionRate_), positionMeasFrame, positionMeasFrame + sensorFrameCorrectedNameId,
288 holistic_fusion::RobustNorm::None(), leicaPositionPtr->header.stamp.toSec(), POS_COVARIANCE_VIOLATION_THRESHOLD, positionMeas,
289 positionCovarianceXYZ, fixedFrame, staticTransformsPtr_->getWorldFrame(), initialSe3AlignmentNoise_, prismSe3AlignmentRandomWalk_);
290 this->addUnaryPosition3AbsoluteMeasurement(meas_W_t_W_P);
291 }
292 // Else if not active
293 else if ((prismPositionCallbackCounter_ % 10) == 0 && addToGraphFlag) {
294 REGULAR_COUT << " Prism unary measurement is turned off." << std::endl;
295 }
296
297 // Visualizations
298 // Fixed Frame
299 std::string msgFixedFrame = fixedFrame;
300 if (msgFixedFrame != staticTransformsPtr_->getWorldFrame()) {
301 msgFixedFrame += referenceFrameAlignedNameId;
302 }
303 // Add to Path
305 addToPathMsg(measPosition_worldPrismPositionPathPtr_, msgFixedFrame, leicaPositionPtr->header.stamp, positionMeas,
306 graphConfigPtr_->imuBufferLength_ * 4);
308 }
309}
310
311//---------------------------------------------------------------
312void Position3Estimator::gnssPositionCallback_(const sensor_msgs::NavSatFix::ConstPtr& gnssPositionPtr) {
313 throw std::runtime_error("Position3Estimator: outdated in terms of logic.");
314
315 // Counter
317
318 // Translate to Eigen
319 Eigen::Vector3d gnssCoord = Eigen::Vector3d(gnssPositionPtr->latitude, gnssPositionPtr->longitude, gnssPositionPtr->altitude);
320 Eigen::Vector3d estStdDevXYZ(sqrt(gnssPositionPtr->position_covariance[0]), sqrt(gnssPositionPtr->position_covariance[4]),
321 sqrt(gnssPositionPtr->position_covariance[8]));
322
323 // Initialize GNSS Handler
324 if (gnssPositionCallbackCounter_ < NUM_GNSS_CALLBACKS_UNTIL_START) { // Accumulate measurements
325 // Wait until measurements got accumulated
326 accumulatedGnssCoordinates_ += gnssCoord;
327 if ((gnssPositionCallbackCounter_ % 10) == 0) {
328 REGULAR_COUT << " NOT ENOUGH GNSS MESSAGES ARRIVED!" << std::endl;
329 }
330 return;
331 } else if (gnssPositionCallbackCounter_ == NUM_GNSS_CALLBACKS_UNTIL_START) { // Initialize GNSS Handler
333 REGULAR_COUT << " GNSS Handler initialized." << std::endl;
334 return;
335 }
336
337 // Convert to Cartesian Coordinates
338 Eigen::Vector3d W_t_W_Gnss;
339 gnssHandlerPtr_->convertNavSatToPosition(gnssCoord, W_t_W_Gnss);
340 // std::string fixedFrame = staticTransformsPtr_->getWorldFrame();
341 std::string fixedFrame = gnssPositionPtr->header.frame_id;
342
343 // Regular Operation
344 // Initialize if needed and no prism is used
346 // Try to initialize yaw and position if not done already
347 if (this->initYawAndPositionInWorld(0.0, W_t_W_Gnss, staticTransformsPtr_->getBaseLinkFrame(),
349 REGULAR_COUT << " GNSS set yaw and position successfully, as there is no prism." << std::endl;
350 } else {
351 REGULAR_COUT << " Could not set yaw and position." << std::endl;
352 }
353 }
354 // Else if inited or prism is used
356 const std::string& positionMeasFrame = dynamic_cast<Position3StaticTransforms*>(staticTransformsPtr_.get())->getGnssPositionMeasFrame();
357 // Already initialized --> add position measurement to graph
359 "GnssPosition", int(gnssPositionRate_), positionMeasFrame, positionMeasFrame + sensorFrameCorrectedNameId,
360 holistic_fusion::RobustNorm::None(), gnssPositionPtr->header.stamp.toSec(), POS_COVARIANCE_VIOLATION_THRESHOLD, W_t_W_Gnss, estStdDevXYZ,
362 this->addUnaryPosition3AbsoluteMeasurement(meas_W_t_W_P);
363 }
364 // Status
365 else if ((gnssPositionCallbackCounter_ % 10) == 0) {
366 REGULAR_COUT << " GNSS unary measurement is turned off or roll/pitch not yet inited." << std::endl;
367 }
368
369 // Adjust frame name
370 if (fixedFrame != staticTransformsPtr_->getWorldFrame()) {
371 fixedFrame += referenceFrameAlignedNameId;
372 }
373
374 // Visualizations
375 addToPathMsg(measPosition_worldGnssPositionPathPtr_, fixedFrame, gnssPositionPtr->header.stamp, W_t_W_Gnss,
376 graphConfigPtr_->imuBufferLength_ * 4);
377 // Publish Path
379}
380
381//---------------------------------------------------------------
382void Position3Estimator::gnssOfflinePoseCallback_(const nav_msgs::Odometry::ConstPtr& gnssOfflinePosePtr) {
383 // Counter
385
386 // Fixed Frame
387 std::string fixedFrame;
389 fixedFrame = staticTransformsPtr_->getWorldFrame();
390 } else {
391 fixedFrame = gnssOfflinePosePtr->header.frame_id;
392 }
393
394 // Case: First call
396 REGULAR_COUT << " First GNSS offline pose measurement received." << std::endl;
397 // Set Reference Frame
398 gnssReferenceFrame_ = gnssOfflinePosePtr->header.frame_id;
399 }
400
401 // Prepare Data
402 Eigen::Isometry3d T_ENU_Gk = Eigen::Isometry3d::Identity();
403 holistic_fusion::odomMsgToEigen(*gnssOfflinePosePtr, T_ENU_Gk.matrix());
404 double gnssUnaryTimeK = gnssOfflinePosePtr->header.stamp.toSec();
405
406 // If initialized by gnss --> make sure we can do the alignment with prism
408 trajectoryAlignmentHandler_->addSe3Position(T_ENU_Gk.translation(), gnssOfflinePosePtr->header.stamp.toSec());
409 }
410
411 // Get Uncertainty from message
412 auto estGnssOfflinePoseMeasUnaryNoiseList = gnssOfflinePosePtr->pose.covariance;
413 Eigen::Matrix<double, 6, 1> estGnssOfflinePoseMeasUnaryNoise;
414 estGnssOfflinePoseMeasUnaryNoise << sqrt(estGnssOfflinePoseMeasUnaryNoiseList[0]), sqrt(estGnssOfflinePoseMeasUnaryNoiseList[7]),
415 sqrt(estGnssOfflinePoseMeasUnaryNoiseList[14]), sqrt(estGnssOfflinePoseMeasUnaryNoiseList[21]),
416 sqrt(estGnssOfflinePoseMeasUnaryNoiseList[28]), sqrt(estGnssOfflinePoseMeasUnaryNoiseList[35]);
417
418 // Measurement
419 const std::string& gnssFrameName =
422 "Lidar_unary_6D", int(gnssOfflinePoseRate_), gnssFrameName, gnssFrameName + sensorFrameCorrectedNameId, holistic_fusion::RobustNorm::None(),
423 gnssUnaryTimeK, 1.0, T_ENU_Gk, gnssOfflinePoseMeasUnaryNoise_, fixedFrame, staticTransformsPtr_->getWorldFrame(),
425
426 // Wait until enough measurements have arrived
428 return;
429 }
430 // Initialize if needed and no prism is used
431 else if (!areYawAndPositionInited() && areRollAndPitchInited() && initializeUsingGnssFlag_) { // Initializing if no GNSS
432 std::cout << "-------------------" << std::endl;
433 REGULAR_COUT << RED_START << " GNSS offline odometry callback is setting global yaw." << COLOR_END << std::endl;
434 std::cout << "-------------------" << std::endl;
435 this->initYawAndPosition(unary6DMeasurement);
436 }
437 // Otherwise just add measurement
438 else if (areYawAndPositionInited()) { // Already initialized --> unary factor
439 // If prism has not moved enough, do not add GNSS measurements
440 bool addToOnlineSmootherFlag = true;
442 if ((gnssOfflinePoseCallbackCounter_ % 100) == 0) {
443 REGULAR_COUT << " PRISM HAS NOT MOVED ENOUGH YET! Not adding GNSS measurements to online graph." << std::endl;
444 }
445 addToOnlineSmootherFlag = false;
446 }
447 this->addUnaryPose3AbsoluteMeasurement(unary6DMeasurement, addToOnlineSmootherFlag);
448 }
449
450 // Visualization ----------------------------
451 // Add to path message
452 addToPathMsg(measPosition_worldGnssOfflinePosePathPtr_, fixedFrame, gnssOfflinePosePtr->header.stamp, T_ENU_Gk.translation(),
453 graphConfigPtr_->imuBufferLength_ * 4);
454
455 // Publish Path
457}
458
459//---------------------------------------------------------------
460bool Position3Estimator::srvTogglePrismUnaryCallback_(std_srvs::Trigger::Request& req, std_srvs::Trigger::Response& res) {
461 // Toggle Flag
463
464 // Response
465 res.success = true;
466 res.message = "Prism unary measurement toggled " + std::string(usePrismPositionUnaryFlag_ ? "on" : "off") + ".";
467
468 return true;
469}
470
471//---------------------------------------------------------------
472bool Position3Estimator::srvToggleGnssUnaryCallback_(std_srvs::Trigger::Request& req, std_srvs::Trigger::Response& res) {
473 // Toggle Flag
475
476 // Response
477 res.success = true;
478 res.message = "GNSS unary measurement toggled " + std::string(useGnssPositionUnaryFlag_ ? "on" : "off") + ".";
479
480 return true;
481}
482
483//---------------------------------------------------------------
484bool Position3Estimator::srvToggleGnssOfflinePoseUnaryCallback_(std_srvs::Trigger::Request& req, std_srvs::Trigger::Response& res) {
485 // Toggle Flag
487
488 // Response
489 res.success = true;
490 res.message = "GNSS offline pose unary measurement toggled " + std::string(useGnssOfflinePoseUnaryFlag_ ? "on" : "off") + ".";
491
492 return true;
493}
494
495} // namespace position3_se
#define NUM_GNSS_CALLBACKS_UNTIL_START
#define REGULAR_COUT
#define COLOR_END
#define GREEN_START
#define RED_START
#define ROS_QUEUE_SIZE
#define YELLOW_START
#define POS_COVARIANCE_VIOLATION_THRESHOLD
void addUnaryPosition3AbsoluteMeasurement(UnaryMeasurementXDAbsolute< Eigen::Vector3d, 3 > &R_t_R_S) override
void addUnaryPose3AbsoluteMeasurement(const UnaryMeasurementXDAbsolute< Eigen::Isometry3d, 6 > &R_T_R_S, const bool addToOnlineSmootherFlag=true) override
Unary Measurements / Absolute Measurements: In reference frame --> systematic drift.
virtual bool srvOfflineSmootherOptimizeCallback(holistic_fusion_ros_msgs::OfflineOptimizationTrigger::Request &req, holistic_fusion_ros_msgs::OfflineOptimizationTrigger::Response &res)
static void addToPathMsg(const nav_msgs::PathPtr &pathPtr, const std::string &frameName, const ros::Time &stamp, const Eigen::Vector3d &t, int maxBufferLength)
HolisticFusionRos(const std::shared_ptr< ros::NodeHandle > &privateNodePtr)
std::shared_ptr< GraphConfig > graphConfigPtr_
bool initYawAndPositionInWorld(const double yaw_W_frame1, const Eigen::Vector3d &W_t_W_frame2, const std::string &frame1, const std::string &frame2)
std::shared_ptr< StaticTransforms > staticTransformsPtr_
bool initYawAndPosition(const UnaryMeasurementXD< Eigen::Isometry3d, 6 > &unary6DMeasurement)
Class to represent x-dimensional absolute unary measurement in the graph.
Eigen::Isometry3d T_totalStation_totalStationOld_
Position3Estimator(std::shared_ptr< ros::NodeHandle > privateNodePtr)
nav_msgs::PathPtr measPosition_worldGnssPositionPathPtr_
bool srvOfflineSmootherOptimizeCallback(holistic_fusion_ros_msgs::OfflineOptimizationTrigger::Request &req, holistic_fusion_ros_msgs::OfflineOptimizationTrigger::Response &res) override
void initializeMessages(ros::NodeHandle &privateNode) override
ros::ServiceServer srvToggleGnssPositionUnary_
std::shared_ptr< holistic_fusion::GnssHandler > gnssHandlerPtr_
void initializeServices(ros::NodeHandle &privateNode) override
void gnssPositionCallback_(const sensor_msgs::NavSatFix::ConstPtr &gnssPositionPtr)
Eigen::Matrix< double, 6, 1 > gnssSe3AlignmentRandomWalk_
void initializePublishers(ros::NodeHandle &privateNode) override
void readParams(const ros::NodeHandle &privateNode) override
void gnssOfflinePoseCallback_(const nav_msgs::Odometry::ConstPtr &gnssOfflinePosePtr)
Eigen::Matrix< double, 6, 1 > gnssOfflinePoseMeasUnaryNoise_
void prismPositionCallback_(const geometry_msgs::PointStamped::ConstPtr &leicaPositionPtr)
Eigen::Matrix< double, 6, 1 > initialSe3AlignmentNoise_
ros::ServiceServer srvToggleGnssOfflinePoseUnary_
ros::ServiceServer srvTogglePrismPositionUnary_
std::shared_ptr< holistic_fusion::TrajectoryAlignmentHandler > trajectoryAlignmentHandler_
nav_msgs::PathPtr measPosition_worldGnssOfflinePosePathPtr_
Eigen::Matrix< double, 6, 1 > prismSe3AlignmentRandomWalk_
static constexpr bool constexprUseGnssPositionUnaryFlag_
static constexpr bool constexprUsePrismPositionUnaryFlag_
static constexpr double PRISM_MOVED_ENOUGH_THRESHOLD
nav_msgs::PathPtr measPosition_worldPrismPositionPathPtr_
bool srvToggleGnssOfflinePoseUnaryCallback_(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
void initializeSubscribers(ros::NodeHandle &privateNode) override
static constexpr bool constexprUseGnssOfflinePoseUnaryFlag_
bool srvToggleGnssUnaryCallback_(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
bool srvTogglePrismUnaryCallback_(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
void createPose3CsvFileStream(std::map< std::string, std::ofstream > &fileStreams, const std::string &savePath, const std::string &transformIdentifier, const std::string &timeString, const bool saveCovarianceFlag)
void odomMsgToEigen(const nav_msgs::Odometry &odomLidar, Eigen::Matrix4d &T)
std::string getLatestSubdirectory(const std::string &directoryPath)
void inPlaceRemoveRollPitch(Eigen::Isometry3d &T)
void writePose3ToCsvFile(std::map< std::string, std::ofstream > &fileStreams, const Eigen::Isometry3d pose, const std::string &transformIdentifier, const double timeStamp, const bool saveCovarianceFlag, const std::optional< Eigen::Matrix< double, 6, 6 > > &optionalPoseCovarianceInWorldRos=std::nullopt)
static RobustNorm None()
Definition Measurement.h:33