12#include <boost/filesystem.hpp>
105 this, ros::TransportHints().tcpNoDelay());
109 std::cout <<
YELLOW_START <<
"FactorGraphFiltering" <<
COLOR_END <<
" Initialized Position subscriber (on position_topic)." << std::endl;
144 holistic_fusion_ros_msgs::OfflineOptimizationTrigger::Response& res) {
145 std::cout <<
"Position3Estimator: srvOfflineSmootherOptimizeCallback (derived class) called." << std::endl;
150 std::map<std::string, std::ofstream> fileStreams;
155 if (timeString.empty()) {
166 REGULAR_COUT <<
" Wrote T_totalStation_totalStationOld to file." << std::endl;
175 REGULAR_COUT <<
" Wrote T_W_gnssReferenceFrame to file." << std::endl;
182 REGULAR_COUT <<
" Wrote T_W_totalStationReferenceFrame to file." << std::endl;
186 for (
auto& pair : fileStreams) {
199 std::string fixedFrame;
203 fixedFrame = leicaPositionPtr->header.frame_id;
207 Eigen::Vector3d positionMeas = Eigen::Vector3d(leicaPositionPtr->point.x, leicaPositionPtr->point.y, leicaPositionPtr->point.z);
212 REGULAR_COUT <<
" First prism position measurement received. Setting initial position to " << positionMeas.transpose() << std::endl;
224 << positionMeas.transpose() << std::endl;
229 bool addToGraphFlag =
true;
238 REGULAR_COUT <<
" Graph was initialized by GNSS, hence trying to align. Trajectory alignment not ready. Waiting for more motion."
241 addToGraphFlag =
false;
262 std::cout <<
"-------------------" << std::endl;
264 std::cout <<
"-------------------" << std::endl;
265 REGULAR_COUT <<
" Set yaw and position successfully." << std::endl;
267 REGULAR_COUT <<
" Could not set yaw and position." << std::endl;
272 const std::string& positionMeasFrame =
294 REGULAR_COUT <<
" Prism unary measurement is turned off." << std::endl;
299 std::string msgFixedFrame = fixedFrame;
313 throw std::runtime_error(
"Position3Estimator: outdated in terms of logic.");
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]));
328 REGULAR_COUT <<
" NOT ENOUGH GNSS MESSAGES ARRIVED!" << std::endl;
333 REGULAR_COUT <<
" GNSS Handler initialized." << std::endl;
338 Eigen::Vector3d W_t_W_Gnss;
341 std::string fixedFrame = gnssPositionPtr->header.frame_id;
349 REGULAR_COUT <<
" GNSS set yaw and position successfully, as there is no prism." << std::endl;
351 REGULAR_COUT <<
" Could not set yaw and position." << std::endl;
366 REGULAR_COUT <<
" GNSS unary measurement is turned off or roll/pitch not yet inited." << std::endl;
387 std::string fixedFrame;
391 fixedFrame = gnssOfflinePosePtr->header.frame_id;
396 REGULAR_COUT <<
" First GNSS offline pose measurement received." << std::endl;
402 Eigen::Isometry3d T_ENU_Gk = Eigen::Isometry3d::Identity();
404 double gnssUnaryTimeK = gnssOfflinePosePtr->header.stamp.toSec();
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]);
419 const std::string& gnssFrameName =
432 std::cout <<
"-------------------" << std::endl;
434 std::cout <<
"-------------------" << std::endl;
440 bool addToOnlineSmootherFlag =
true;
443 REGULAR_COUT <<
" PRISM HAS NOT MOVED ENOUGH YET! Not adding GNSS measurements to online graph." << std::endl;
445 addToOnlineSmootherFlag =
false;
#define NUM_GNSS_CALLBACKS_UNTIL_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)
std::string sensorFrameCorrectedNameId
static void addToPathMsg(const nav_msgs::PathPtr &pathPtr, const std::string &frameName, const ros::Time &stamp, const Eigen::Vector3d &t, int maxBufferLength)
std::string referenceFrameAlignedNameId
std::string optimizationResultLoggingPath
ros::NodeHandle privateNode
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)
bool areYawAndPositionInited() const
bool areRollAndPitchInited() const
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_
std::string gnssReferenceFrame_
bool alignedPrismAndGnssFlag_
Eigen::Vector3d initialPrismPosition_
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_
int prismPositionCallbackCounter_
void initializeServices(ros::NodeHandle &privateNode) override
void gnssPositionCallback_(const sensor_msgs::NavSatFix::ConstPtr &gnssPositionPtr)
Eigen::Matrix< double, 6, 1 > gnssSe3AlignmentRandomWalk_
ros::Publisher pubMeasWorldPrismPositionPath_
void initializePublishers(ros::NodeHandle &privateNode) override
ros::Subscriber subGnssOfflinePose_
void readParams(const ros::NodeHandle &privateNode) override
ros::Publisher pubMeasWorldGnssOfflinePosePath_
double prismPositionRate_
void gnssOfflinePoseCallback_(const nav_msgs::Odometry::ConstPtr &gnssOfflinePosePtr)
Eigen::Matrix< double, 6, 1 > gnssOfflinePoseMeasUnaryNoise_
std::string totalStationReferenceFrame_
bool initializeUsingGnssFlag_
void prismPositionCallback_(const geometry_msgs::PointStamped::ConstPtr &leicaPositionPtr)
double gnssOfflinePoseRate_
Eigen::Matrix< double, 6, 1 > initialSe3AlignmentNoise_
double prismPositionMeasUnaryNoise_
ros::ServiceServer srvToggleGnssOfflinePoseUnary_
ros::ServiceServer srvTogglePrismPositionUnary_
bool prismMovedEnoughFlag_
int gnssOfflinePoseCallbackCounter_
std::shared_ptr< holistic_fusion::TrajectoryAlignmentHandler > trajectoryAlignmentHandler_
nav_msgs::PathPtr measPosition_worldGnssOfflinePosePathPtr_
Eigen::Isometry3d T_totalStation_enu_
ros::Subscriber subPrismPosition_
int gnssPositionCallbackCounter_
Eigen::Matrix< double, 6, 1 > prismSe3AlignmentRandomWalk_
static constexpr bool constexprUseGnssPositionUnaryFlag_
Eigen::Vector3d accumulatedGnssCoordinates_
bool usePrismPositionUnaryFlag_
ros::Publisher pubMeasWorldGnssPositionPath_
static constexpr bool constexprUsePrismPositionUnaryFlag_
static constexpr double PRISM_MOVED_ENOUGH_THRESHOLD
bool useGnssPositionUnaryFlag_
nav_msgs::PathPtr measPosition_worldPrismPositionPathPtr_
bool srvToggleGnssOfflinePoseUnaryCallback_(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
void initializeSubscribers(ros::NodeHandle &privateNode) override
ros::Subscriber subGnssPosition_
static constexpr bool constexprUseGnssOfflinePoseUnaryFlag_
bool srvToggleGnssUnaryCallback_(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
bool useGnssOfflinePoseUnaryFlag_
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)