2011-06-20 16:49:22 +00:00
|
|
|
/*
|
2016-07-17 22:06:11 -04:00
|
|
|
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
2014-08-11 17:03:39 +00:00
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
|
modification, are permitted provided that the following conditions are met:
|
|
|
|
|
* Redistributions of source code must retain the above copyright
|
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
|
* Redistributions in binary form must reproduce the above copyright
|
|
|
|
|
notice, this list of conditions and the following disclaimer in the
|
|
|
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
|
* Neither the name of the Universite de Sherbrooke nor the
|
|
|
|
|
names of its contributors may be used to endorse or promote products
|
|
|
|
|
derived from this software without specific prior written permission.
|
|
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
|
|
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
|
|
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
|
|
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
|
|
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
|
|
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
|
|
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
*/
|
2011-06-20 16:49:22 +00:00
|
|
|
|
2016-07-27 16:44:48 -07:00
|
|
|
#include "rtabmap_ros/GuiWrapper.h"
|
2016-05-04 17:07:40 -04:00
|
|
|
#include <QApplication>
|
|
|
|
|
#include <QDir>
|
2012-06-24 17:19:34 +00:00
|
|
|
|
|
|
|
|
#include <std_srvs/Empty.h>
|
|
|
|
|
#include <std_msgs/Empty.h>
|
|
|
|
|
|
2013-04-30 20:25:52 +00:00
|
|
|
#include <rtabmap/utilite/UEventsManager.h>
|
2013-12-11 00:12:44 +00:00
|
|
|
#include <rtabmap/utilite/UConversion.h>
|
2015-10-16 17:46:37 -04:00
|
|
|
#include <rtabmap/utilite/UDirectory.h>
|
2012-06-24 17:19:34 +00:00
|
|
|
|
|
|
|
|
#include <opencv2/highgui/highgui.hpp>
|
|
|
|
|
|
|
|
|
|
#include <rtabmap/gui/MainWindow.h>
|
|
|
|
|
#include <rtabmap/core/RtabmapEvent.h>
|
2011-06-20 16:49:22 +00:00
|
|
|
#include <rtabmap/core/Parameters.h>
|
2013-02-04 16:41:10 +00:00
|
|
|
#include <rtabmap/core/ParamEvent.h>
|
2013-12-11 00:12:44 +00:00
|
|
|
#include <rtabmap/core/OdometryEvent.h>
|
2015-08-27 17:29:47 -04:00
|
|
|
#include <rtabmap/core/util2d.h>
|
2015-05-31 01:28:54 -04:00
|
|
|
#include <rtabmap/core/util3d.h>
|
2015-05-30 20:08:20 -04:00
|
|
|
#include <rtabmap/core/util3d_transforms.h>
|
2015-04-01 18:22:54 -04:00
|
|
|
#include <rtabmap/utilite/UTimer.h>
|
2013-12-11 00:12:44 +00:00
|
|
|
|
2014-11-25 17:13:15 -05:00
|
|
|
#include "rtabmap_ros/MsgConversion.h"
|
|
|
|
|
#include "rtabmap_ros/GetMap.h"
|
2015-06-21 20:17:31 -04:00
|
|
|
#include "rtabmap_ros/SetGoal.h"
|
2015-07-26 15:59:40 -04:00
|
|
|
#include "rtabmap_ros/SetLabel.h"
|
2022-01-20 19:00:05 -05:00
|
|
|
#include "rtabmap_ros/RemoveLabel.h"
|
2016-07-27 16:44:48 -07:00
|
|
|
#include "rtabmap_ros/PreferencesDialogROS.h"
|
2011-06-20 16:49:22 +00:00
|
|
|
|
2015-02-24 16:08:08 -05:00
|
|
|
float max3( const float& a, const float& b, const float& c)
|
|
|
|
|
{
|
|
|
|
|
float m=a>b?a:b;
|
|
|
|
|
return m>c?m:c;
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-26 16:37:31 -04:00
|
|
|
namespace rtabmap_ros {
|
|
|
|
|
|
2013-12-11 00:12:44 +00:00
|
|
|
GuiWrapper::GuiWrapper(int & argc, char** argv) :
|
2016-09-30 16:21:06 -04:00
|
|
|
CommonDataSubscriber(true),
|
2013-12-11 00:12:44 +00:00
|
|
|
mainWindow_(0),
|
|
|
|
|
frameId_("base_link"),
|
2016-09-26 16:37:31 -04:00
|
|
|
odomFrameId_(""),
|
2015-07-20 16:13:56 -04:00
|
|
|
waitForTransform_(true),
|
2016-03-17 17:14:43 -04:00
|
|
|
waitForTransformDuration_(0.2), // 200 ms
|
2016-08-25 14:33:06 -04:00
|
|
|
odomSensorSync_(false),
|
2019-01-15 15:50:10 -05:00
|
|
|
maxOdomUpdateRate_(10),
|
2015-01-23 15:18:06 -05:00
|
|
|
cameraNodeName_(""),
|
2021-09-08 15:24:37 -04:00
|
|
|
lastOdomInfoUpdateTime_(0),
|
|
|
|
|
rtabmapNodeName_("rtabmap")
|
2011-06-20 16:49:22 +00:00
|
|
|
{
|
2012-03-03 01:46:30 +00:00
|
|
|
ros::NodeHandle nh;
|
2016-09-30 16:21:06 -04:00
|
|
|
ros::NodeHandle pnh("~");
|
|
|
|
|
|
2013-12-11 00:12:44 +00:00
|
|
|
QString configFile = QDir::homePath()+"/.ros/rtabmapGUI.ini";
|
2013-01-29 20:33:08 +00:00
|
|
|
for(int i=1; i<argc; ++i)
|
|
|
|
|
{
|
|
|
|
|
if(strcmp(argv[i], "-d") == 0)
|
|
|
|
|
{
|
|
|
|
|
++i;
|
|
|
|
|
if(i < argc)
|
|
|
|
|
{
|
|
|
|
|
configFile = argv[i];
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-11 00:12:44 +00:00
|
|
|
configFile.replace('~', QDir::homePath());
|
|
|
|
|
|
2021-09-08 15:24:37 -04:00
|
|
|
pnh.param("rtabmap", rtabmapNodeName_, rtabmapNodeName_);
|
|
|
|
|
|
2013-12-11 00:12:44 +00:00
|
|
|
ROS_INFO("rtabmapviz: Using configuration from \"%s\"", configFile.toStdString().c_str());
|
|
|
|
|
uSleep(500);
|
2021-09-08 15:24:37 -04:00
|
|
|
prefDialog_ = new PreferencesDialogROS(configFile, rtabmapNodeName_);
|
2021-04-02 19:08:58 -04:00
|
|
|
mainWindow_ = new MainWindow(prefDialog_);
|
2013-12-11 00:12:44 +00:00
|
|
|
mainWindow_->setWindowTitle(mainWindow_->windowTitle()+" [ROS]");
|
2011-06-20 16:49:22 +00:00
|
|
|
mainWindow_->show();
|
2021-09-08 15:24:37 -04:00
|
|
|
|
2013-12-11 00:12:44 +00:00
|
|
|
bool paused = false;
|
2021-09-08 15:24:37 -04:00
|
|
|
ros::NodeHandle rnh(rtabmapNodeName_);
|
|
|
|
|
rnh.param("is_rtabmap_paused", paused, paused);
|
2013-12-11 00:12:44 +00:00
|
|
|
mainWindow_->setMonitoringState(paused);
|
2011-06-20 16:49:22 +00:00
|
|
|
|
2013-12-11 00:12:44 +00:00
|
|
|
// To receive odometry events
|
2015-10-16 17:46:37 -04:00
|
|
|
std::string initCachePath;
|
2013-12-11 00:12:44 +00:00
|
|
|
pnh.param("frame_id", frameId_, frameId_);
|
2015-05-30 20:08:20 -04:00
|
|
|
pnh.param("odom_frame_id", odomFrameId_, odomFrameId_); // set to use odom from TF
|
2014-12-03 22:35:43 -05:00
|
|
|
pnh.param("wait_for_transform", waitForTransform_, waitForTransform_);
|
2015-08-14 15:01:51 -04:00
|
|
|
pnh.param("wait_for_transform_duration", waitForTransformDuration_, waitForTransformDuration_);
|
2016-08-25 14:33:06 -04:00
|
|
|
pnh.param("odom_sensor_sync", odomSensorSync_, odomSensorSync_);
|
2019-01-15 15:50:10 -05:00
|
|
|
pnh.param("max_odom_update_rate", maxOdomUpdateRate_, maxOdomUpdateRate_);
|
2015-06-17 16:04:06 -04:00
|
|
|
pnh.param("camera_node_name", cameraNodeName_, cameraNodeName_); // used to pause the rtabmap_ros/camera when pausing the process
|
2015-10-16 17:46:37 -04:00
|
|
|
pnh.param("init_cache_path", initCachePath, initCachePath);
|
|
|
|
|
if(initCachePath.size())
|
|
|
|
|
{
|
|
|
|
|
initCachePath = uReplaceChar(initCachePath, '~', UDirectory::homeDir());
|
|
|
|
|
if(initCachePath.at(0) != '/')
|
|
|
|
|
{
|
|
|
|
|
initCachePath = UDirectory::currentDir(true) + initCachePath;
|
|
|
|
|
}
|
|
|
|
|
ROS_INFO("rtabmapviz: Initializing cache with local database \"%s\"", initCachePath.c_str());
|
|
|
|
|
uSleep(2000); // make sure rtabmap node is created if launched at the same time
|
|
|
|
|
rtabmap_ros::GetMap getMapSrv;
|
|
|
|
|
getMapSrv.request.global = false;
|
|
|
|
|
getMapSrv.request.optimized = true;
|
|
|
|
|
getMapSrv.request.graphOnly = true;
|
|
|
|
|
if(!ros::service::call("get_map", getMapSrv))
|
|
|
|
|
{
|
|
|
|
|
ROS_WARN("Can't call \"get_map\" service. The cache will still be loaded "
|
|
|
|
|
"but the clouds won't be created until next time rtabmapviz "
|
|
|
|
|
"receives the optimized graph.");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// this will update the poses and constraints of the MainWindow
|
|
|
|
|
processRequestedMap(getMapSrv.response.data);
|
|
|
|
|
}
|
|
|
|
|
QMetaObject::invokeMethod(mainWindow_, "updateCacheFromDatabase", Q_ARG(QString, QString(initCachePath.c_str())));
|
|
|
|
|
}
|
2015-06-17 16:04:06 -04:00
|
|
|
|
2021-06-14 14:15:34 -04:00
|
|
|
if(pnh.hasParam("tf_prefix"))
|
2015-06-17 16:04:06 -04:00
|
|
|
{
|
2021-06-14 14:15:34 -04:00
|
|
|
ROS_ERROR("tf_prefix parameter has been removed, use directly odom_frame_id and frame_id parameters.");
|
2015-06-17 16:04:06 -04:00
|
|
|
}
|
|
|
|
|
|
2011-06-20 16:49:22 +00:00
|
|
|
UEventsManager::addHandler(this);
|
|
|
|
|
UEventsManager::addHandler(mainWindow_);
|
2013-12-11 00:12:44 +00:00
|
|
|
|
2014-12-14 16:44:13 -05:00
|
|
|
infoTopic_.subscribe(nh, "info", 1);
|
2014-07-06 19:58:15 +00:00
|
|
|
mapDataTopic_.subscribe(nh, "mapData", 1);
|
2015-05-31 01:28:54 -04:00
|
|
|
infoMapSync_ = new message_filters::Synchronizer<MyInfoMapSyncPolicy>(
|
2016-09-26 16:37:31 -04:00
|
|
|
MyInfoMapSyncPolicy(this->getQueueSize()),
|
2015-05-31 01:28:54 -04:00
|
|
|
infoTopic_,
|
|
|
|
|
mapDataTopic_);
|
2022-05-09 08:51:05 -07:00
|
|
|
infoMapSync_->registerCallback(boost::bind(&GuiWrapper::infoMapCallback, this, boost::placeholders::_1, boost::placeholders::_2));
|
2015-09-21 16:37:35 -04:00
|
|
|
|
|
|
|
|
goalTopic_.subscribe(nh, "goal_node", 1);
|
|
|
|
|
pathTopic_.subscribe(nh, "global_path", 1);
|
|
|
|
|
goalPathSync_ = new message_filters::Synchronizer<MyGoalPathSyncPolicy>(
|
2016-09-26 16:37:31 -04:00
|
|
|
MyGoalPathSyncPolicy(this->getQueueSize()),
|
2015-09-21 16:37:35 -04:00
|
|
|
goalTopic_,
|
|
|
|
|
pathTopic_);
|
2022-05-09 08:51:05 -07:00
|
|
|
goalPathSync_->registerCallback(boost::bind(&GuiWrapper::goalPathCallback, this, boost::placeholders::_1, boost::placeholders::_2));
|
2015-10-13 13:24:37 -04:00
|
|
|
goalReachedTopic_ = nh.subscribe("goal_reached", 1, &GuiWrapper::goalReachedCallback, this);
|
2016-09-26 16:37:31 -04:00
|
|
|
|
2016-10-18 11:49:56 -04:00
|
|
|
setupCallbacks(nh, pnh, ros::this_node::getName()); // do it at the end
|
2011-06-20 16:49:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GuiWrapper::~GuiWrapper()
|
|
|
|
|
{
|
2016-03-17 17:14:43 -04:00
|
|
|
UDEBUG("");
|
2015-05-31 01:28:54 -04:00
|
|
|
|
2015-01-23 15:18:06 -05:00
|
|
|
delete infoMapSync_;
|
2011-06-20 16:49:22 +00:00
|
|
|
delete mainWindow_;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-06 19:58:15 +00:00
|
|
|
void GuiWrapper::infoMapCallback(
|
2014-12-14 16:44:13 -05:00
|
|
|
const rtabmap_ros::InfoConstPtr & infoMsg,
|
2014-11-25 17:13:15 -05:00
|
|
|
const rtabmap_ros::MapDataConstPtr & mapMsg)
|
2011-06-20 16:49:22 +00:00
|
|
|
{
|
2013-12-11 00:12:44 +00:00
|
|
|
//ROS_INFO("rtabmapviz: RTAB-Map info ex received!");
|
2012-03-03 04:44:40 +00:00
|
|
|
|
|
|
|
|
// Map from ROS struct to rtabmap struct
|
2013-01-29 16:04:54 +00:00
|
|
|
rtabmap::Statistics stat;
|
2012-03-03 04:44:40 +00:00
|
|
|
|
2015-02-03 11:16:06 -05:00
|
|
|
// Info
|
|
|
|
|
rtabmap_ros::infoFromROS(*infoMsg, stat);
|
2012-03-03 04:44:40 +00:00
|
|
|
|
2015-02-03 11:16:06 -05:00
|
|
|
// MapData
|
|
|
|
|
rtabmap::Transform mapToOdom;
|
|
|
|
|
std::map<int, rtabmap::Transform> poses;
|
2015-05-30 20:08:20 -04:00
|
|
|
std::map<int, Signature> signatures;
|
2016-09-26 16:37:31 -04:00
|
|
|
std::multimap<int, rtabmap::Link> links;
|
2014-12-14 16:44:13 -05:00
|
|
|
|
2015-05-30 20:08:20 -04:00
|
|
|
rtabmap_ros::mapDataFromROS(*mapMsg, poses, links, signatures, mapToOdom);
|
2014-12-14 16:44:13 -05:00
|
|
|
|
|
|
|
|
stat.setMapCorrection(mapToOdom);
|
|
|
|
|
stat.setPoses(poses);
|
2018-11-09 11:38:08 -05:00
|
|
|
if(signatures.size())
|
|
|
|
|
{
|
|
|
|
|
stat.setLastSignatureData(signatures.rbegin()->second);
|
|
|
|
|
}
|
2014-12-14 16:44:13 -05:00
|
|
|
stat.setConstraints(links);
|
2014-01-08 16:11:44 +00:00
|
|
|
|
2013-12-11 00:12:44 +00:00
|
|
|
this->post(new RtabmapEvent(stat));
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-21 16:37:35 -04:00
|
|
|
void GuiWrapper::goalPathCallback(
|
|
|
|
|
const rtabmap_ros::GoalConstPtr & goalMsg,
|
|
|
|
|
const nav_msgs::PathConstPtr & pathMsg)
|
|
|
|
|
{
|
|
|
|
|
// we don't have the node ids, just generate fake ones.
|
|
|
|
|
std::vector<std::pair<int, Transform> > poses(pathMsg->poses.size());
|
|
|
|
|
for(unsigned int i=0; i<pathMsg->poses.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
poses[i].first = -int(i)-1;
|
|
|
|
|
poses[i].second = rtabmap_ros::transformFromPoseMsg(pathMsg->poses[i].pose);
|
|
|
|
|
}
|
2015-10-27 09:31:05 -04:00
|
|
|
this->post(new RtabmapGlobalPathEvent(goalMsg->node_id, goalMsg->node_label, poses, 0.0));
|
2015-09-21 16:37:35 -04:00
|
|
|
}
|
|
|
|
|
|
2015-10-13 13:24:37 -04:00
|
|
|
void GuiWrapper::goalReachedCallback(
|
|
|
|
|
const std_msgs::BoolConstPtr & value)
|
|
|
|
|
{
|
|
|
|
|
this->post(new RtabmapGoalStatusEvent(value->data?1:-1));
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-25 17:13:15 -05:00
|
|
|
void GuiWrapper::processRequestedMap(const rtabmap_ros::MapData & map)
|
2013-12-11 00:12:44 +00:00
|
|
|
{
|
2022-01-26 15:42:07 -05:00
|
|
|
// Make sure parameters are loaded
|
|
|
|
|
if(((PreferencesDialogROS*)prefDialog_)->hasAllParameters())
|
|
|
|
|
{
|
|
|
|
|
QMetaObject::invokeMethod(((PreferencesDialogROS*)prefDialog_), "readRtabmapNodeParameters");
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-26 21:49:30 +00:00
|
|
|
std::map<int, Signature> signatures;
|
2013-12-11 00:12:44 +00:00
|
|
|
std::map<int, Transform> poses;
|
2014-12-14 16:44:13 -05:00
|
|
|
std::multimap<int, rtabmap::Link> constraints;
|
|
|
|
|
Transform mapToOdom;
|
2014-08-13 19:25:44 +00:00
|
|
|
|
2015-05-30 20:08:20 -04:00
|
|
|
rtabmap_ros::mapDataFromROS(map, poses, constraints, signatures, mapToOdom);
|
2014-10-26 21:49:30 +00:00
|
|
|
|
2015-03-20 15:57:09 -04:00
|
|
|
RtabmapEvent3DMap e(signatures,
|
|
|
|
|
poses,
|
2015-05-30 20:08:20 -04:00
|
|
|
constraints);
|
2015-03-20 15:57:09 -04:00
|
|
|
QMetaObject::invokeMethod(mainWindow_, "processRtabmapEvent3DMap", Q_ARG(rtabmap::RtabmapEvent3DMap, e));
|
2011-06-20 16:49:22 +00:00
|
|
|
}
|
|
|
|
|
|
2017-03-12 21:47:22 -04:00
|
|
|
bool GuiWrapper::handleEvent(UEvent * anEvent)
|
2011-06-20 16:49:22 +00:00
|
|
|
{
|
2012-03-03 01:46:30 +00:00
|
|
|
if(anEvent->getClassName().compare("ParamEvent") == 0)
|
2011-06-20 16:49:22 +00:00
|
|
|
{
|
|
|
|
|
const rtabmap::ParametersMap & defaultParameters = rtabmap::Parameters::getDefaultParameters();
|
|
|
|
|
rtabmap::ParametersMap parameters = ((rtabmap::ParamEvent *)anEvent)->getParameters();
|
|
|
|
|
bool modified = false;
|
2021-09-08 15:24:37 -04:00
|
|
|
ros::NodeHandle rnh(rtabmapNodeName_);
|
2011-06-20 16:49:22 +00:00
|
|
|
for(rtabmap::ParametersMap::iterator i=parameters.begin(); i!=parameters.end(); ++i)
|
|
|
|
|
{
|
|
|
|
|
//save only parameters with valid names
|
|
|
|
|
if(defaultParameters.find((*i).first) != defaultParameters.end())
|
|
|
|
|
{
|
2021-09-08 15:24:37 -04:00
|
|
|
rnh.setParam((*i).first, (*i).second);
|
2011-06-20 16:49:22 +00:00
|
|
|
modified = true;
|
|
|
|
|
}
|
|
|
|
|
else if((*i).first.find('/') != (*i).first.npos)
|
|
|
|
|
{
|
|
|
|
|
ROS_WARN("Parameter %s is not used by the rtabmap node.", (*i).first.c_str());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(modified)
|
|
|
|
|
{
|
|
|
|
|
ROS_INFO("Parameters updated");
|
2013-12-11 00:12:44 +00:00
|
|
|
std_srvs::Empty srv;
|
|
|
|
|
if(!ros::service::call("update_parameters", srv))
|
|
|
|
|
{
|
|
|
|
|
ROS_ERROR("Can't call \"update_parameters\" service");
|
|
|
|
|
}
|
2011-06-20 16:49:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if(anEvent->getClassName().compare("RtabmapEventCmd") == 0)
|
|
|
|
|
{
|
2014-07-06 19:58:15 +00:00
|
|
|
std_srvs::Empty emptySrv;
|
2013-12-11 00:12:44 +00:00
|
|
|
rtabmap::RtabmapEventCmd * cmdEvent = (rtabmap::RtabmapEventCmd *)anEvent;
|
|
|
|
|
rtabmap::RtabmapEventCmd::Cmd cmd = cmdEvent->getCmd();
|
2014-10-28 01:23:52 +00:00
|
|
|
if(cmd == rtabmap::RtabmapEventCmd::kCmdResetMemory)
|
2011-06-20 16:49:22 +00:00
|
|
|
{
|
2014-07-06 19:58:15 +00:00
|
|
|
if(!ros::service::call("reset", emptySrv))
|
2011-06-20 16:49:22 +00:00
|
|
|
{
|
2013-12-11 00:12:44 +00:00
|
|
|
ROS_ERROR("Can't call \"reset\" service");
|
2011-06-20 16:49:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
2013-12-11 00:12:44 +00:00
|
|
|
else if(cmd == rtabmap::RtabmapEventCmd::kCmdPause)
|
2011-06-20 16:49:22 +00:00
|
|
|
{
|
2015-08-03 18:21:00 -04:00
|
|
|
// Pause the camera if the rtabmap/camera node is used
|
|
|
|
|
if(!cameraNodeName_.empty())
|
2011-06-20 16:49:22 +00:00
|
|
|
{
|
2015-08-03 18:21:00 -04:00
|
|
|
std::string str = uFormat("rosrun dynamic_reconfigure dynparam set %s pause true", cameraNodeName_.c_str());
|
2017-07-13 11:39:19 -04:00
|
|
|
if(system(str.c_str()) !=0)
|
|
|
|
|
{
|
|
|
|
|
ROS_ERROR("Command \"%s\" returned non zero value.", str.c_str());
|
|
|
|
|
}
|
2013-12-11 00:12:44 +00:00
|
|
|
}
|
2015-08-03 18:21:00 -04:00
|
|
|
|
|
|
|
|
// Pause visual_odometry
|
|
|
|
|
ros::service::call("pause_odom", emptySrv);
|
|
|
|
|
|
|
|
|
|
// Pause rtabmap
|
|
|
|
|
if(!ros::service::call("pause", emptySrv))
|
2013-12-11 00:12:44 +00:00
|
|
|
{
|
2015-08-03 18:21:00 -04:00
|
|
|
ROS_ERROR("Can't call \"pause\" service");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if(cmd == rtabmap::RtabmapEventCmd::kCmdResume)
|
|
|
|
|
{
|
|
|
|
|
// Resume rtabmap
|
|
|
|
|
if(!ros::service::call("resume", emptySrv))
|
|
|
|
|
{
|
|
|
|
|
ROS_ERROR("Can't call \"resume\" service");
|
|
|
|
|
}
|
2013-12-11 00:12:44 +00:00
|
|
|
|
2015-08-03 18:21:00 -04:00
|
|
|
// Pause visual_odometry
|
|
|
|
|
ros::service::call("resume_odom", emptySrv);
|
2014-06-11 18:14:28 +00:00
|
|
|
|
2015-08-03 18:21:00 -04:00
|
|
|
// Resume the camera if the rtabmap/camera node is used
|
|
|
|
|
if(!cameraNodeName_.empty())
|
|
|
|
|
{
|
|
|
|
|
std::string str = uFormat("rosrun dynamic_reconfigure dynparam set %s pause false", cameraNodeName_.c_str());
|
2017-07-13 11:39:19 -04:00
|
|
|
if(system(str.c_str()) !=0)
|
|
|
|
|
{
|
|
|
|
|
ROS_ERROR("Command \"%s\" returned non zero value.", str.c_str());
|
|
|
|
|
}
|
2011-06-20 16:49:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
2013-12-11 00:12:44 +00:00
|
|
|
else if(cmd == rtabmap::RtabmapEventCmd::kCmdTriggerNewMap)
|
2011-06-20 16:49:22 +00:00
|
|
|
{
|
2014-07-06 19:58:15 +00:00
|
|
|
if(!ros::service::call("trigger_new_map", emptySrv))
|
2011-06-20 16:49:22 +00:00
|
|
|
{
|
2013-12-11 00:12:44 +00:00
|
|
|
ROS_ERROR("Can't call \"trigger_new_map\" service");
|
2011-06-20 16:49:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
2015-08-03 18:21:00 -04:00
|
|
|
else if(cmd == rtabmap::RtabmapEventCmd::kCmdPublish3DMap)
|
2011-06-20 16:49:22 +00:00
|
|
|
{
|
2015-08-03 18:21:00 -04:00
|
|
|
UASSERT(cmdEvent->value1().isBool());
|
|
|
|
|
UASSERT(cmdEvent->value2().isBool());
|
|
|
|
|
UASSERT(cmdEvent->value3().isBool());
|
|
|
|
|
|
2014-11-25 17:13:15 -05:00
|
|
|
rtabmap_ros::GetMap getMapSrv;
|
2015-08-03 18:21:00 -04:00
|
|
|
getMapSrv.request.global = cmdEvent->value1().toBool();
|
|
|
|
|
getMapSrv.request.optimized = cmdEvent->value2().toBool();
|
|
|
|
|
getMapSrv.request.graphOnly = cmdEvent->value3().toBool();
|
2016-08-21 19:38:28 -04:00
|
|
|
if(!ros::service::call("get_map_data", getMapSrv))
|
2011-06-20 16:49:22 +00:00
|
|
|
{
|
2016-08-21 19:38:28 -04:00
|
|
|
ROS_WARN("Can't call \"get_map_data\" service");
|
2014-07-06 19:58:15 +00:00
|
|
|
this->post(new RtabmapEvent3DMap(1)); // service error
|
2014-01-22 19:57:52 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2014-07-06 19:58:15 +00:00
|
|
|
processRequestedMap(getMapSrv.response.data);
|
2014-02-17 22:59:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
2015-06-21 20:17:31 -04:00
|
|
|
else if(cmd == rtabmap::RtabmapEventCmd::kCmdGoal)
|
|
|
|
|
{
|
2015-08-03 18:21:00 -04:00
|
|
|
UASSERT(cmdEvent->value1().isStr() || cmdEvent->value1().isInt() || cmdEvent->value1().isUInt());
|
2015-06-21 20:17:31 -04:00
|
|
|
rtabmap_ros::SetGoal setGoalSrv;
|
2015-08-03 18:21:00 -04:00
|
|
|
setGoalSrv.request.node_id = !cmdEvent->value1().isStr()?cmdEvent->value1().toInt():0;
|
|
|
|
|
setGoalSrv.request.node_label = cmdEvent->value1().isStr()?cmdEvent->value1().toStr():"";
|
2015-06-21 20:17:31 -04:00
|
|
|
if(!ros::service::call("set_goal", setGoalSrv))
|
|
|
|
|
{
|
|
|
|
|
ROS_ERROR("Can't call \"set_goal\" service");
|
|
|
|
|
}
|
2015-09-21 16:37:35 -04:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UASSERT(setGoalSrv.response.path_ids.size() == setGoalSrv.response.path_poses.size());
|
|
|
|
|
std::vector<std::pair<int, Transform> > poses(setGoalSrv.response.path_poses.size());
|
|
|
|
|
for(unsigned int i=0; i<setGoalSrv.response.path_poses.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
poses[i].first = setGoalSrv.response.path_ids[i];
|
|
|
|
|
poses[i].second = rtabmap_ros::transformFromPoseMsg(setGoalSrv.response.path_poses[i]);
|
|
|
|
|
}
|
2015-10-27 09:31:05 -04:00
|
|
|
this->post(new RtabmapGlobalPathEvent(setGoalSrv.request.node_id, setGoalSrv.request.node_label, poses, setGoalSrv.response.planning_time));
|
2015-09-21 16:37:35 -04:00
|
|
|
}
|
2015-06-21 20:17:31 -04:00
|
|
|
}
|
|
|
|
|
else if(cmd == rtabmap::RtabmapEventCmd::kCmdCancelGoal)
|
|
|
|
|
{
|
|
|
|
|
if(!ros::service::call("cancel_goal", emptySrv))
|
|
|
|
|
{
|
|
|
|
|
ROS_ERROR("Can't call \"cancel_goal\" service");
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-07-26 15:59:40 -04:00
|
|
|
else if(cmd == rtabmap::RtabmapEventCmd::kCmdLabel)
|
|
|
|
|
{
|
2015-08-04 14:17:46 -04:00
|
|
|
UASSERT(cmdEvent->value1().isStr());
|
|
|
|
|
UASSERT(cmdEvent->value2().isUndef() || cmdEvent->value2().isInt() || cmdEvent->value2().isUInt());
|
2015-07-26 15:59:40 -04:00
|
|
|
rtabmap_ros::SetLabel setLabelSrv;
|
2015-08-04 14:17:46 -04:00
|
|
|
setLabelSrv.request.node_label = cmdEvent->value1().toStr();
|
|
|
|
|
setLabelSrv.request.node_id = cmdEvent->value2().isUndef()?0:cmdEvent->value2().toInt();
|
2015-07-26 15:59:40 -04:00
|
|
|
if(!ros::service::call("set_label", setLabelSrv))
|
|
|
|
|
{
|
|
|
|
|
ROS_ERROR("Can't call \"set_label\" service");
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-01-20 19:00:05 -05:00
|
|
|
else if(cmd == rtabmap::RtabmapEventCmd::kCmdRemoveLabel)
|
|
|
|
|
{
|
|
|
|
|
UASSERT(cmdEvent->value1().isStr());
|
|
|
|
|
rtabmap_ros::RemoveLabel removeLabelSrv;
|
|
|
|
|
removeLabelSrv.request.label = cmdEvent->value1().toStr();
|
|
|
|
|
if(!ros::service::call("remove_label", removeLabelSrv))
|
|
|
|
|
{
|
|
|
|
|
ROS_ERROR("Can't call \"remove_label\" service");
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-06-20 16:49:22 +00:00
|
|
|
else
|
|
|
|
|
{
|
2013-12-11 00:12:44 +00:00
|
|
|
ROS_WARN("Not handled command (%d)...", cmd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if(anEvent->getClassName().compare("OdometryResetEvent") == 0)
|
|
|
|
|
{
|
|
|
|
|
std_srvs::Empty srv;
|
|
|
|
|
if(!ros::service::call("reset_odom", srv))
|
|
|
|
|
{
|
|
|
|
|
ROS_ERROR("Can't call \"reset_odom\" service, (will only work with rtabmap/visual_odometry node.)");
|
2011-06-20 16:49:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
2017-03-12 21:47:22 -04:00
|
|
|
return false;
|
2011-06-20 16:49:22 +00:00
|
|
|
}
|
2013-12-11 00:12:44 +00:00
|
|
|
|
2015-05-30 20:08:20 -04:00
|
|
|
void GuiWrapper::commonDepthCallback(
|
|
|
|
|
const nav_msgs::OdometryConstPtr & odomMsg,
|
2016-09-26 16:37:31 -04:00
|
|
|
const rtabmap_ros::UserDataConstPtr & userDataMsg,
|
|
|
|
|
const std::vector<cv_bridge::CvImageConstPtr> & imageMsgs,
|
|
|
|
|
const std::vector<cv_bridge::CvImageConstPtr> & depthMsgs,
|
|
|
|
|
const std::vector<sensor_msgs::CameraInfo> & cameraInfoMsgs,
|
2020-05-03 22:42:01 -04:00
|
|
|
const sensor_msgs::LaserScan& scan2dMsg,
|
|
|
|
|
const sensor_msgs::PointCloud2& scan3dMsg,
|
|
|
|
|
const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg,
|
|
|
|
|
const std::vector<rtabmap_ros::GlobalDescriptor> & globalDescriptorMsgs,
|
|
|
|
|
const std::vector<std::vector<rtabmap_ros::KeyPoint> > & localKeyPoints,
|
|
|
|
|
const std::vector<std::vector<rtabmap_ros::Point3f> > & localPoints3d,
|
|
|
|
|
const std::vector<cv::Mat> & localDescriptors)
|
2015-05-31 01:28:54 -04:00
|
|
|
{
|
2019-01-16 19:33:04 -05:00
|
|
|
UASSERT(imageMsgs.size() == 0 || (imageMsgs.size() == cameraInfoMsgs.size()));
|
2016-06-17 15:01:30 -04:00
|
|
|
|
|
|
|
|
std_msgs::Header odomHeader;
|
2020-12-18 17:04:28 -05:00
|
|
|
std::string frameId = frameId_;
|
2016-06-17 15:01:30 -04:00
|
|
|
if(odomMsg.get())
|
|
|
|
|
{
|
|
|
|
|
odomHeader = odomMsg->header;
|
2021-01-22 14:18:30 -05:00
|
|
|
if(!odomMsg->child_frame_id.empty())
|
|
|
|
|
{
|
|
|
|
|
frameId = odomMsg->child_frame_id;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ROS_WARN("Received odom topic with child_frame_id not set! Using \"%s\" as base frame.", frameId_.c_str());
|
|
|
|
|
}
|
2016-06-17 15:01:30 -04:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-05-03 22:42:01 -04:00
|
|
|
if(!scan2dMsg.ranges.empty())
|
2016-06-17 15:01:30 -04:00
|
|
|
{
|
2020-05-03 22:42:01 -04:00
|
|
|
odomHeader = scan2dMsg.header;
|
2016-06-17 15:01:30 -04:00
|
|
|
}
|
2020-05-03 22:42:01 -04:00
|
|
|
else if(!scan3dMsg.data.empty())
|
2016-06-17 15:01:30 -04:00
|
|
|
{
|
2020-05-03 22:42:01 -04:00
|
|
|
odomHeader = scan3dMsg.header;
|
2016-06-17 15:01:30 -04:00
|
|
|
}
|
2016-09-26 16:37:31 -04:00
|
|
|
else if(cameraInfoMsgs.size())
|
2016-06-17 15:01:30 -04:00
|
|
|
{
|
2016-09-26 16:37:31 -04:00
|
|
|
odomHeader = cameraInfoMsgs[0].header;
|
2016-06-17 15:01:30 -04:00
|
|
|
}
|
|
|
|
|
else if(depthMsgs.size() && depthMsgs[0].get())
|
|
|
|
|
{
|
|
|
|
|
odomHeader = depthMsgs[0]->header;
|
|
|
|
|
}
|
|
|
|
|
else if(imageMsgs.size() && imageMsgs[0].get())
|
|
|
|
|
{
|
|
|
|
|
odomHeader = imageMsgs[0]->header;
|
|
|
|
|
}
|
|
|
|
|
odomHeader.frame_id = odomFrameId_;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-18 17:04:28 -05:00
|
|
|
Transform odomT = rtabmap_ros::getTransform(odomHeader.frame_id, frameId, odomHeader.stamp, tfListener_, waitForTransform_?waitForTransformDuration_:0);
|
2016-06-17 15:01:30 -04:00
|
|
|
cv::Mat covariance = cv::Mat::eye(6,6,CV_64FC1);
|
|
|
|
|
if(odomMsg.get())
|
|
|
|
|
{
|
2016-08-05 14:22:45 -04:00
|
|
|
UASSERT(odomMsg->twist.covariance.size() == 36);
|
|
|
|
|
if(odomMsg->twist.covariance[0] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[7] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[14] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[21] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[28] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[35] != 0)
|
2016-06-17 15:01:30 -04:00
|
|
|
{
|
2016-08-05 14:22:45 -04:00
|
|
|
covariance = cv::Mat(6,6,CV_64FC1,(void*)odomMsg->twist.covariance.data()).clone();
|
2016-06-17 15:01:30 -04:00
|
|
|
}
|
|
|
|
|
}
|
2020-03-28 18:51:38 -04:00
|
|
|
else if(odomInfoMsg.get() && odomInfoMsg->covariance.size() == 36)
|
|
|
|
|
{
|
|
|
|
|
if(odomInfoMsg->covariance[0] != 0 &&
|
|
|
|
|
odomInfoMsg->covariance[7] != 0 &&
|
|
|
|
|
odomInfoMsg->covariance[14] != 0 &&
|
|
|
|
|
odomInfoMsg->covariance[21] != 0 &&
|
|
|
|
|
odomInfoMsg->covariance[28] != 0 &&
|
|
|
|
|
odomInfoMsg->covariance[35] != 0)
|
|
|
|
|
{
|
|
|
|
|
covariance = cv::Mat(6,6,CV_64FC1,(void*)odomInfoMsg->covariance.data()).clone();
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-06-17 15:01:30 -04:00
|
|
|
if(odomHeader.frame_id.empty())
|
|
|
|
|
{
|
|
|
|
|
ROS_ERROR("Odometry frame not set!?");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cv::Mat rgb;
|
|
|
|
|
cv::Mat depth;
|
|
|
|
|
std::vector<CameraModel> cameraModels;
|
2019-02-06 18:45:29 -05:00
|
|
|
LaserScan scan;
|
2016-06-17 15:01:30 -04:00
|
|
|
rtabmap::OdometryInfo info;
|
|
|
|
|
bool ignoreData = false;
|
|
|
|
|
|
2019-01-15 15:50:10 -05:00
|
|
|
// limit update rate
|
|
|
|
|
if(maxOdomUpdateRate_<=0.0 ||
|
|
|
|
|
(UTimer::now() - lastOdomInfoUpdateTime_ > 1.0/maxOdomUpdateRate_ &&
|
2015-05-30 20:08:20 -04:00
|
|
|
!mainWindow_->isProcessingOdometry() &&
|
2019-01-15 15:50:10 -05:00
|
|
|
!mainWindow_->isProcessingStatistics()))
|
2015-05-30 20:08:20 -04:00
|
|
|
{
|
|
|
|
|
lastOdomInfoUpdateTime_ = UTimer::now();
|
|
|
|
|
|
2019-01-16 19:33:04 -05:00
|
|
|
if(imageMsgs.size() && imageMsgs[0].get() && depthMsgs.size() && depthMsgs[0].get())
|
2015-05-30 20:08:20 -04:00
|
|
|
{
|
2016-08-24 12:17:12 -04:00
|
|
|
if(!rtabmap_ros::convertRGBDMsgs(
|
|
|
|
|
imageMsgs,
|
|
|
|
|
depthMsgs,
|
|
|
|
|
cameraInfoMsgs,
|
2020-12-18 17:04:28 -05:00
|
|
|
frameId,
|
2016-08-25 14:33:06 -04:00
|
|
|
odomSensorSync_?odomHeader.frame_id:"",
|
2016-08-24 12:17:12 -04:00
|
|
|
odomHeader.stamp,
|
|
|
|
|
rgb,
|
|
|
|
|
depth,
|
|
|
|
|
cameraModels,
|
|
|
|
|
tfListener_,
|
|
|
|
|
waitForTransform_?waitForTransformDuration_:0.0))
|
2015-05-31 01:28:54 -04:00
|
|
|
{
|
2016-08-24 12:17:12 -04:00
|
|
|
ROS_ERROR("Could not convert rgb/depth msgs! Aborting rtabmapviz update...");
|
|
|
|
|
return;
|
2015-08-14 13:21:49 -04:00
|
|
|
}
|
2015-05-30 20:08:20 -04:00
|
|
|
}
|
|
|
|
|
|
2020-05-03 22:42:01 -04:00
|
|
|
if(!scan2dMsg.ranges.empty())
|
2015-05-30 20:08:20 -04:00
|
|
|
{
|
2016-08-24 12:17:12 -04:00
|
|
|
if(!rtabmap_ros::convertScanMsg(
|
|
|
|
|
scan2dMsg,
|
2020-12-18 17:04:28 -05:00
|
|
|
frameId,
|
2016-08-25 14:33:06 -04:00
|
|
|
odomSensorSync_?odomHeader.frame_id:"",
|
2016-08-24 12:17:12 -04:00
|
|
|
odomHeader.stamp,
|
|
|
|
|
scan,
|
|
|
|
|
tfListener_,
|
|
|
|
|
waitForTransform_?waitForTransformDuration_:0))
|
2015-05-30 20:08:20 -04:00
|
|
|
{
|
2016-08-24 12:17:12 -04:00
|
|
|
ROS_ERROR("Could not convert laser scan msg! Aborting rtabmapviz update...");
|
2015-05-30 20:08:20 -04:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-05-03 22:42:01 -04:00
|
|
|
else if(!scan3dMsg.data.empty())
|
2015-11-26 16:06:42 -05:00
|
|
|
{
|
2016-08-24 12:17:12 -04:00
|
|
|
if(!rtabmap_ros::convertScan3dMsg(
|
|
|
|
|
scan3dMsg,
|
2020-12-18 17:04:28 -05:00
|
|
|
frameId,
|
2016-08-25 14:33:06 -04:00
|
|
|
odomSensorSync_?odomHeader.frame_id:"",
|
2016-08-24 12:17:12 -04:00
|
|
|
odomHeader.stamp,
|
|
|
|
|
scan,
|
|
|
|
|
tfListener_,
|
|
|
|
|
waitForTransform_?waitForTransformDuration_:0))
|
2016-08-21 19:38:28 -04:00
|
|
|
{
|
2016-08-24 12:17:12 -04:00
|
|
|
ROS_ERROR("Could not convert 3d laser scan msg! Aborting rtabmapviz update...");
|
2016-08-21 19:38:28 -04:00
|
|
|
return;
|
|
|
|
|
}
|
2015-11-26 16:06:42 -05:00
|
|
|
}
|
2015-03-20 15:57:09 -04:00
|
|
|
|
2015-05-30 20:08:20 -04:00
|
|
|
if(odomInfoMsg.get())
|
|
|
|
|
{
|
|
|
|
|
info = rtabmap_ros::odomInfoFromROS(*odomInfoMsg);
|
|
|
|
|
}
|
2016-06-17 15:01:30 -04:00
|
|
|
ignoreData = false;
|
2015-03-20 15:57:09 -04:00
|
|
|
}
|
2016-06-28 15:12:58 -04:00
|
|
|
else if(odomInfoMsg.get())
|
2016-06-17 15:01:30 -04:00
|
|
|
{
|
|
|
|
|
info = rtabmap_ros::odomInfoFromROS(*odomInfoMsg).copyWithoutData();
|
|
|
|
|
ignoreData = true;
|
|
|
|
|
}
|
2016-06-28 15:12:58 -04:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// don't update GUI odom stuff if we don't use visual odometry
|
|
|
|
|
return;
|
|
|
|
|
}
|
2016-06-17 15:01:30 -04:00
|
|
|
|
2017-09-11 13:26:34 -04:00
|
|
|
info.reg.covariance = covariance;
|
2016-06-17 15:01:30 -04:00
|
|
|
rtabmap::OdometryEvent odomEvent(
|
|
|
|
|
rtabmap::SensorData(
|
2019-02-06 18:45:29 -05:00
|
|
|
scan,
|
2016-06-17 15:01:30 -04:00
|
|
|
rgb,
|
|
|
|
|
depth,
|
|
|
|
|
cameraModels,
|
|
|
|
|
odomHeader.seq,
|
|
|
|
|
rtabmap_ros::timestampFromROS(odomHeader.stamp)),
|
|
|
|
|
odomMsg.get()?rtabmap_ros::transformFromPoseMsg(odomMsg->pose.pose):odomT,
|
|
|
|
|
info);
|
|
|
|
|
|
|
|
|
|
QMetaObject::invokeMethod(mainWindow_, "processOdometry", Q_ARG(rtabmap::OdometryEvent, odomEvent), Q_ARG(bool, ignoreData));
|
2013-12-11 00:12:44 +00:00
|
|
|
}
|
|
|
|
|
|
2015-05-30 20:08:20 -04:00
|
|
|
void GuiWrapper::commonStereoCallback(
|
|
|
|
|
const nav_msgs::OdometryConstPtr & odomMsg,
|
2018-02-13 21:35:15 -05:00
|
|
|
const rtabmap_ros::UserDataConstPtr & userDataMsg,
|
|
|
|
|
const cv_bridge::CvImageConstPtr& leftImageMsg,
|
|
|
|
|
const cv_bridge::CvImageConstPtr& rightImageMsg,
|
|
|
|
|
const sensor_msgs::CameraInfo& leftCamInfoMsg,
|
|
|
|
|
const sensor_msgs::CameraInfo& rightCamInfoMsg,
|
2020-05-03 22:42:01 -04:00
|
|
|
const sensor_msgs::LaserScan& scan2dMsg,
|
|
|
|
|
const sensor_msgs::PointCloud2& scan3dMsg,
|
|
|
|
|
const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg,
|
|
|
|
|
const std::vector<rtabmap_ros::GlobalDescriptor> & globalDescriptorMsgs,
|
2020-11-05 16:38:08 -05:00
|
|
|
const std::vector<rtabmap_ros::KeyPoint> & localKeyPoints,
|
|
|
|
|
const std::vector<rtabmap_ros::Point3f> & localPoints3d,
|
|
|
|
|
const cv::Mat & localDescriptors)
|
2015-05-30 20:08:20 -04:00
|
|
|
{
|
2016-06-17 15:01:30 -04:00
|
|
|
std_msgs::Header odomHeader;
|
2020-12-18 17:04:28 -05:00
|
|
|
std::string frameId = frameId_;
|
2016-06-17 15:01:30 -04:00
|
|
|
if(odomMsg.get())
|
|
|
|
|
{
|
|
|
|
|
odomHeader = odomMsg->header;
|
2021-01-22 14:18:30 -05:00
|
|
|
if(!odomMsg->child_frame_id.empty())
|
|
|
|
|
{
|
|
|
|
|
frameId = odomMsg->child_frame_id;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ROS_WARN("Received odom topic with child_frame_id not set! Using \"%s\" as base frame.", frameId_.c_str());
|
|
|
|
|
}
|
2016-06-17 15:01:30 -04:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-05-03 22:42:01 -04:00
|
|
|
if(!scan2dMsg.ranges.empty())
|
2016-06-17 15:01:30 -04:00
|
|
|
{
|
2020-05-03 22:42:01 -04:00
|
|
|
odomHeader = scan2dMsg.header;
|
2016-06-17 15:01:30 -04:00
|
|
|
}
|
2020-05-03 22:42:01 -04:00
|
|
|
else if(!scan3dMsg.data.empty())
|
2016-06-17 15:01:30 -04:00
|
|
|
{
|
2020-05-03 22:42:01 -04:00
|
|
|
odomHeader = scan3dMsg.header;
|
2016-06-17 15:01:30 -04:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2018-02-13 21:35:15 -05:00
|
|
|
odomHeader = leftCamInfoMsg.header;
|
2016-06-17 15:01:30 -04:00
|
|
|
}
|
|
|
|
|
odomHeader.frame_id = odomFrameId_;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-18 17:04:28 -05:00
|
|
|
Transform odomT = rtabmap_ros::getTransform(odomHeader.frame_id, frameId, odomHeader.stamp, tfListener_, waitForTransform_?waitForTransformDuration_:0);
|
2016-06-17 15:01:30 -04:00
|
|
|
cv::Mat covariance = cv::Mat::eye(6,6,CV_64FC1);
|
|
|
|
|
if(odomMsg.get())
|
|
|
|
|
{
|
2016-08-05 14:22:45 -04:00
|
|
|
UASSERT(odomMsg->twist.covariance.size() == 36);
|
|
|
|
|
if(odomMsg->twist.covariance[0] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[7] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[14] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[21] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[28] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[35] != 0)
|
2016-06-17 15:01:30 -04:00
|
|
|
{
|
2016-08-05 14:22:45 -04:00
|
|
|
covariance = cv::Mat(6,6,CV_64FC1,(void*)odomMsg->twist.covariance.data()).clone();
|
2016-06-17 15:01:30 -04:00
|
|
|
}
|
|
|
|
|
}
|
2020-03-28 18:51:38 -04:00
|
|
|
else if(odomInfoMsg.get() && odomInfoMsg->covariance.size() == 36)
|
|
|
|
|
{
|
|
|
|
|
if(odomInfoMsg->covariance[0] != 0 &&
|
|
|
|
|
odomInfoMsg->covariance[7] != 0 &&
|
|
|
|
|
odomInfoMsg->covariance[14] != 0 &&
|
|
|
|
|
odomInfoMsg->covariance[21] != 0 &&
|
|
|
|
|
odomInfoMsg->covariance[28] != 0 &&
|
|
|
|
|
odomInfoMsg->covariance[35] != 0)
|
|
|
|
|
{
|
|
|
|
|
covariance = cv::Mat(6,6,CV_64FC1,(void*)odomInfoMsg->covariance.data()).clone();
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-06-17 15:01:30 -04:00
|
|
|
if(odomHeader.frame_id.empty())
|
|
|
|
|
{
|
|
|
|
|
ROS_ERROR("Odometry frame not set!?");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cv::Mat left;
|
|
|
|
|
cv::Mat right;
|
2019-02-06 18:45:29 -05:00
|
|
|
LaserScan scan;
|
2016-06-17 15:01:30 -04:00
|
|
|
rtabmap::StereoCameraModel stereoModel;
|
|
|
|
|
rtabmap::OdometryInfo info;
|
|
|
|
|
bool ignoreData = false;
|
|
|
|
|
|
2019-01-15 15:50:10 -05:00
|
|
|
// limit update rate
|
|
|
|
|
if(maxOdomUpdateRate_<=0.0 ||
|
|
|
|
|
(UTimer::now() - lastOdomInfoUpdateTime_ > 1.0/maxOdomUpdateRate_ &&
|
2015-05-30 20:08:20 -04:00
|
|
|
!mainWindow_->isProcessingOdometry() &&
|
2019-01-15 15:50:10 -05:00
|
|
|
!mainWindow_->isProcessingStatistics()))
|
2015-05-30 20:08:20 -04:00
|
|
|
{
|
|
|
|
|
lastOdomInfoUpdateTime_ = UTimer::now();
|
|
|
|
|
|
2021-04-02 19:08:58 -04:00
|
|
|
ParametersMap allParameters = prefDialog_->getAllParameters();
|
|
|
|
|
bool imagesAlreadyRectified = Parameters::defaultRtabmapImagesAlreadyRectified();
|
|
|
|
|
Parameters::parse(allParameters, Parameters::kRtabmapImagesAlreadyRectified(), imagesAlreadyRectified);
|
|
|
|
|
|
2016-08-24 12:17:12 -04:00
|
|
|
if(!rtabmap_ros::convertStereoMsg(
|
|
|
|
|
leftImageMsg,
|
|
|
|
|
rightImageMsg,
|
|
|
|
|
leftCamInfoMsg,
|
|
|
|
|
rightCamInfoMsg,
|
2020-12-18 17:04:28 -05:00
|
|
|
frameId,
|
2016-08-25 14:33:06 -04:00
|
|
|
odomSensorSync_?odomHeader.frame_id:"",
|
2016-08-24 12:17:12 -04:00
|
|
|
odomHeader.stamp,
|
|
|
|
|
left,
|
|
|
|
|
right,
|
|
|
|
|
stereoModel,
|
|
|
|
|
tfListener_,
|
2020-07-30 12:43:44 -04:00
|
|
|
waitForTransform_?waitForTransformDuration_:0.0,
|
2021-04-02 19:08:58 -04:00
|
|
|
imagesAlreadyRectified))
|
2015-10-09 12:28:20 -04:00
|
|
|
{
|
2016-08-24 12:17:12 -04:00
|
|
|
ROS_ERROR("Could not convert stereo msgs! Aborting rtabmapviz update...");
|
|
|
|
|
return;
|
2015-10-09 12:28:20 -04:00
|
|
|
}
|
|
|
|
|
|
2020-05-03 22:42:01 -04:00
|
|
|
if(!scan2dMsg.ranges.empty())
|
2015-05-30 20:08:20 -04:00
|
|
|
{
|
2016-08-24 12:17:12 -04:00
|
|
|
if(!rtabmap_ros::convertScanMsg(
|
|
|
|
|
scan2dMsg,
|
2020-12-18 17:04:28 -05:00
|
|
|
frameId,
|
2016-08-25 14:33:06 -04:00
|
|
|
odomSensorSync_?odomHeader.frame_id:"",
|
2016-08-24 12:17:12 -04:00
|
|
|
odomHeader.stamp,
|
|
|
|
|
scan,
|
|
|
|
|
tfListener_,
|
|
|
|
|
waitForTransform_?waitForTransformDuration_:0))
|
2015-05-30 20:08:20 -04:00
|
|
|
{
|
2016-08-24 12:17:12 -04:00
|
|
|
ROS_ERROR("Could not convert laser scan msg! Aborting rtabmapviz update...");
|
2015-05-30 20:08:20 -04:00
|
|
|
return;
|
|
|
|
|
}
|
2015-11-26 16:06:42 -05:00
|
|
|
}
|
2020-05-03 22:42:01 -04:00
|
|
|
else if(!scan3dMsg.data.empty())
|
2015-11-26 16:06:42 -05:00
|
|
|
{
|
2016-08-24 12:17:12 -04:00
|
|
|
if(!rtabmap_ros::convertScan3dMsg(
|
|
|
|
|
scan3dMsg,
|
2020-12-18 17:04:28 -05:00
|
|
|
frameId,
|
2016-08-25 14:33:06 -04:00
|
|
|
odomSensorSync_?odomHeader.frame_id:"",
|
2016-08-24 12:17:12 -04:00
|
|
|
odomHeader.stamp,
|
|
|
|
|
scan,
|
|
|
|
|
tfListener_,
|
|
|
|
|
waitForTransform_?waitForTransformDuration_:0))
|
2016-08-21 19:38:28 -04:00
|
|
|
{
|
2016-08-24 12:17:12 -04:00
|
|
|
ROS_ERROR("Could not convert 3d laser scan msg! Aborting rtabmapviz update...");
|
2016-08-21 19:38:28 -04:00
|
|
|
return;
|
|
|
|
|
}
|
2015-05-30 20:08:20 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(odomInfoMsg.get())
|
|
|
|
|
{
|
|
|
|
|
info = rtabmap_ros::odomInfoFromROS(*odomInfoMsg);
|
|
|
|
|
}
|
2016-06-17 15:01:30 -04:00
|
|
|
ignoreData = false;
|
2015-05-30 20:08:20 -04:00
|
|
|
}
|
2016-06-28 15:12:58 -04:00
|
|
|
else if(odomInfoMsg.get())
|
2016-06-17 15:01:30 -04:00
|
|
|
{
|
|
|
|
|
info = rtabmap_ros::odomInfoFromROS(*odomInfoMsg).copyWithoutData();
|
|
|
|
|
ignoreData = true;
|
|
|
|
|
}
|
2016-06-28 15:12:58 -04:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// don't update GUI odom stuff if we don't use visual odometry
|
|
|
|
|
return;
|
|
|
|
|
}
|
2016-06-17 15:01:30 -04:00
|
|
|
|
2017-09-11 13:26:34 -04:00
|
|
|
info.reg.covariance = covariance;
|
2016-06-17 15:01:30 -04:00
|
|
|
rtabmap::OdometryEvent odomEvent(
|
|
|
|
|
rtabmap::SensorData(
|
2019-02-06 18:45:29 -05:00
|
|
|
scan,
|
2016-06-17 15:01:30 -04:00
|
|
|
left,
|
|
|
|
|
right,
|
|
|
|
|
stereoModel,
|
|
|
|
|
odomHeader.seq,
|
|
|
|
|
rtabmap_ros::timestampFromROS(odomHeader.stamp)),
|
|
|
|
|
odomMsg.get()?rtabmap_ros::transformFromPoseMsg(odomMsg->pose.pose):odomT,
|
|
|
|
|
info);
|
|
|
|
|
|
|
|
|
|
QMetaObject::invokeMethod(mainWindow_, "processOdometry", Q_ARG(rtabmap::OdometryEvent, odomEvent), Q_ARG(bool, ignoreData));
|
2015-05-30 20:08:20 -04:00
|
|
|
}
|
|
|
|
|
|
2018-11-14 17:51:47 -05:00
|
|
|
void GuiWrapper::commonLaserScanCallback(
|
|
|
|
|
const nav_msgs::OdometryConstPtr & odomMsg,
|
|
|
|
|
const rtabmap_ros::UserDataConstPtr & userDataMsg,
|
2020-05-03 22:42:01 -04:00
|
|
|
const sensor_msgs::LaserScan& scan2dMsg,
|
|
|
|
|
const sensor_msgs::PointCloud2& scan3dMsg,
|
|
|
|
|
const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg,
|
|
|
|
|
const rtabmap_ros::GlobalDescriptor & globalDescriptor)
|
2018-11-14 17:51:47 -05:00
|
|
|
{
|
|
|
|
|
std_msgs::Header odomHeader;
|
2020-12-18 17:04:28 -05:00
|
|
|
std::string frameId = frameId_;
|
2018-11-14 17:51:47 -05:00
|
|
|
if(odomMsg.get())
|
|
|
|
|
{
|
|
|
|
|
odomHeader = odomMsg->header;
|
2021-01-22 14:18:30 -05:00
|
|
|
if(!odomMsg->child_frame_id.empty())
|
|
|
|
|
{
|
|
|
|
|
frameId = odomMsg->child_frame_id;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ROS_WARN("Received odom topic with child_frame_id not set! Using \"%s\" as base frame.", frameId_.c_str());
|
|
|
|
|
}
|
2018-11-14 17:51:47 -05:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-05-03 22:42:01 -04:00
|
|
|
if(!scan2dMsg.ranges.empty())
|
2018-11-14 17:51:47 -05:00
|
|
|
{
|
2020-05-03 22:42:01 -04:00
|
|
|
odomHeader = scan2dMsg.header;
|
2018-11-14 17:51:47 -05:00
|
|
|
}
|
2020-05-03 22:42:01 -04:00
|
|
|
else if(!scan3dMsg.data.empty())
|
2018-11-14 17:51:47 -05:00
|
|
|
{
|
2020-05-03 22:42:01 -04:00
|
|
|
odomHeader = scan3dMsg.header;
|
2018-11-14 17:51:47 -05:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
odomHeader.frame_id = odomFrameId_;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-18 17:04:28 -05:00
|
|
|
Transform odomT = rtabmap_ros::getTransform(odomHeader.frame_id, frameId, odomHeader.stamp, tfListener_, waitForTransform_?waitForTransformDuration_:0);
|
2018-11-14 17:51:47 -05:00
|
|
|
cv::Mat covariance = cv::Mat::eye(6,6,CV_64FC1);
|
|
|
|
|
if(odomMsg.get())
|
|
|
|
|
{
|
|
|
|
|
UASSERT(odomMsg->twist.covariance.size() == 36);
|
|
|
|
|
if(odomMsg->twist.covariance[0] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[7] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[14] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[21] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[28] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[35] != 0)
|
|
|
|
|
{
|
|
|
|
|
covariance = cv::Mat(6,6,CV_64FC1,(void*)odomMsg->twist.covariance.data()).clone();
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-28 18:51:38 -04:00
|
|
|
else if(odomInfoMsg.get() && odomInfoMsg->covariance.size() == 36)
|
|
|
|
|
{
|
|
|
|
|
if(odomInfoMsg->covariance[0] != 0 &&
|
|
|
|
|
odomInfoMsg->covariance[7] != 0 &&
|
|
|
|
|
odomInfoMsg->covariance[14] != 0 &&
|
|
|
|
|
odomInfoMsg->covariance[21] != 0 &&
|
|
|
|
|
odomInfoMsg->covariance[28] != 0 &&
|
|
|
|
|
odomInfoMsg->covariance[35] != 0)
|
|
|
|
|
{
|
|
|
|
|
covariance = cv::Mat(6,6,CV_64FC1,(void*)odomInfoMsg->covariance.data()).clone();
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-11-14 17:51:47 -05:00
|
|
|
if(odomHeader.frame_id.empty())
|
|
|
|
|
{
|
|
|
|
|
ROS_ERROR("Odometry frame not set!?");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-06 18:45:29 -05:00
|
|
|
LaserScan scan;
|
2018-11-14 17:51:47 -05:00
|
|
|
rtabmap::OdometryInfo info;
|
|
|
|
|
bool ignoreData = false;
|
|
|
|
|
|
2019-01-15 15:50:10 -05:00
|
|
|
// limit update rate
|
|
|
|
|
if(maxOdomUpdateRate_<=0.0 ||
|
|
|
|
|
(UTimer::now() - lastOdomInfoUpdateTime_ > 1.0/maxOdomUpdateRate_ &&
|
2018-11-14 17:51:47 -05:00
|
|
|
!mainWindow_->isProcessingOdometry() &&
|
2019-01-15 15:50:10 -05:00
|
|
|
!mainWindow_->isProcessingStatistics()))
|
2018-11-14 17:51:47 -05:00
|
|
|
{
|
|
|
|
|
lastOdomInfoUpdateTime_ = UTimer::now();
|
|
|
|
|
|
2020-05-03 22:42:01 -04:00
|
|
|
if(!scan2dMsg.ranges.empty())
|
2018-11-14 17:51:47 -05:00
|
|
|
{
|
|
|
|
|
if(!rtabmap_ros::convertScanMsg(
|
|
|
|
|
scan2dMsg,
|
2020-12-18 17:04:28 -05:00
|
|
|
frameId,
|
2018-11-14 17:51:47 -05:00
|
|
|
odomSensorSync_?odomHeader.frame_id:"",
|
|
|
|
|
odomHeader.stamp,
|
|
|
|
|
scan,
|
|
|
|
|
tfListener_,
|
|
|
|
|
waitForTransform_?waitForTransformDuration_:0))
|
|
|
|
|
{
|
|
|
|
|
ROS_ERROR("Could not convert laser scan msg! Aborting rtabmapviz update...");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-05-03 22:42:01 -04:00
|
|
|
else if(!scan3dMsg.data.empty())
|
2018-11-14 17:51:47 -05:00
|
|
|
{
|
|
|
|
|
if(!rtabmap_ros::convertScan3dMsg(
|
|
|
|
|
scan3dMsg,
|
2020-12-18 17:04:28 -05:00
|
|
|
frameId,
|
2018-11-14 17:51:47 -05:00
|
|
|
odomSensorSync_?odomHeader.frame_id:"",
|
|
|
|
|
odomHeader.stamp,
|
|
|
|
|
scan,
|
|
|
|
|
tfListener_,
|
|
|
|
|
waitForTransform_?waitForTransformDuration_:0))
|
|
|
|
|
{
|
|
|
|
|
ROS_ERROR("Could not convert 3d laser scan msg! Aborting rtabmapviz update...");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(odomInfoMsg.get())
|
|
|
|
|
{
|
|
|
|
|
info = rtabmap_ros::odomInfoFromROS(*odomInfoMsg);
|
|
|
|
|
}
|
|
|
|
|
ignoreData = false;
|
|
|
|
|
}
|
|
|
|
|
else if(odomInfoMsg.get())
|
|
|
|
|
{
|
|
|
|
|
info = rtabmap_ros::odomInfoFromROS(*odomInfoMsg).copyWithoutData();
|
|
|
|
|
ignoreData = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// don't update GUI odom stuff if we don't use visual odometry
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
info.reg.covariance = covariance;
|
|
|
|
|
rtabmap::OdometryEvent odomEvent(
|
|
|
|
|
rtabmap::SensorData(
|
2019-02-06 18:45:29 -05:00
|
|
|
scan,
|
2021-01-22 12:53:49 -05:00
|
|
|
cv::Mat(),
|
|
|
|
|
cv::Mat(),
|
|
|
|
|
CameraModel(),
|
2018-11-14 17:51:47 -05:00
|
|
|
odomHeader.seq,
|
|
|
|
|
rtabmap_ros::timestampFromROS(odomHeader.stamp)),
|
|
|
|
|
odomMsg.get()?rtabmap_ros::transformFromPoseMsg(odomMsg->pose.pose):odomT,
|
|
|
|
|
info);
|
|
|
|
|
|
|
|
|
|
QMetaObject::invokeMethod(mainWindow_, "processOdometry", Q_ARG(rtabmap::OdometryEvent, odomEvent), Q_ARG(bool, ignoreData));
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-16 19:33:04 -05:00
|
|
|
void GuiWrapper::commonOdomCallback(
|
|
|
|
|
const nav_msgs::OdometryConstPtr & odomMsg,
|
|
|
|
|
const rtabmap_ros::UserDataConstPtr & userDataMsg,
|
|
|
|
|
const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg)
|
2015-05-30 20:08:20 -04:00
|
|
|
{
|
2019-01-16 19:33:04 -05:00
|
|
|
UASSERT(odomMsg.get());
|
|
|
|
|
|
|
|
|
|
std_msgs::Header odomHeader = odomMsg->header;
|
|
|
|
|
|
2020-12-18 17:04:28 -05:00
|
|
|
Transform odomT = rtabmap_ros::getTransform(odomHeader.frame_id, odomMsg->child_frame_id, odomHeader.stamp, tfListener_, waitForTransform_?waitForTransformDuration_:0);
|
2019-01-16 19:33:04 -05:00
|
|
|
cv::Mat covariance = cv::Mat::eye(6,6,CV_64FC1);
|
|
|
|
|
if(odomMsg.get())
|
|
|
|
|
{
|
|
|
|
|
UASSERT(odomMsg->twist.covariance.size() == 36);
|
|
|
|
|
if(odomMsg->twist.covariance[0] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[7] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[14] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[21] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[28] != 0 &&
|
|
|
|
|
odomMsg->twist.covariance[35] != 0)
|
|
|
|
|
{
|
|
|
|
|
covariance = cv::Mat(6,6,CV_64FC1,(void*)odomMsg->twist.covariance.data()).clone();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(odomHeader.frame_id.empty())
|
|
|
|
|
{
|
|
|
|
|
ROS_ERROR("Odometry frame not set!?");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rtabmap::OdometryInfo info;
|
|
|
|
|
bool ignoreData = false;
|
|
|
|
|
|
|
|
|
|
// limit update rate
|
|
|
|
|
if(maxOdomUpdateRate_<=0.0 ||
|
|
|
|
|
(UTimer::now() - lastOdomInfoUpdateTime_ > 1.0/maxOdomUpdateRate_ &&
|
|
|
|
|
!mainWindow_->isProcessingOdometry() &&
|
|
|
|
|
!mainWindow_->isProcessingStatistics()))
|
|
|
|
|
{
|
|
|
|
|
lastOdomInfoUpdateTime_ = UTimer::now();
|
|
|
|
|
|
|
|
|
|
if(odomInfoMsg.get())
|
|
|
|
|
{
|
|
|
|
|
info = rtabmap_ros::odomInfoFromROS(*odomInfoMsg);
|
|
|
|
|
}
|
|
|
|
|
ignoreData = false;
|
|
|
|
|
}
|
|
|
|
|
else if(odomInfoMsg.get())
|
|
|
|
|
{
|
|
|
|
|
info = rtabmap_ros::odomInfoFromROS(*odomInfoMsg).copyWithoutData();
|
|
|
|
|
ignoreData = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// don't update GUI odom stuff if we don't use visual odometry
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
info.reg.covariance = covariance;
|
|
|
|
|
rtabmap::OdometryEvent odomEvent(
|
|
|
|
|
rtabmap::SensorData(
|
2021-01-22 12:53:49 -05:00
|
|
|
cv::Mat(),
|
|
|
|
|
cv::Mat(),
|
|
|
|
|
CameraModel(),
|
2019-01-16 19:33:04 -05:00
|
|
|
odomHeader.seq,
|
|
|
|
|
rtabmap_ros::timestampFromROS(odomHeader.stamp)),
|
|
|
|
|
odomMsg.get()?rtabmap_ros::transformFromPoseMsg(odomMsg->pose.pose):odomT,
|
|
|
|
|
info);
|
|
|
|
|
|
|
|
|
|
QMetaObject::invokeMethod(mainWindow_, "processOdometry", Q_ARG(rtabmap::OdometryEvent, odomEvent), Q_ARG(bool, ignoreData));
|
2015-05-30 20:08:20 -04:00
|
|
|
}
|
|
|
|
|
|
2013-12-11 00:12:44 +00:00
|
|
|
}
|