在CLion下阅读karto_slam源码
程序员文章站
2024-03-25 09:31:16
...
第一步:
用CLion导入open_slam和karto_slam项目;因为这些都是包含了CMakeLists的文件,所以用
New Cmake Project from Resources导入项目,不要用open打开,否则会显示can’t find Cmake profile
第二步:
先看slam_karto 包下,slam_karto.cpp文件:
tf: transform listener: source frame----->target frame
source frame是Laser相对于base frame的坐标系,是通过相机看到的;
target frame是我们指定的世界坐标系,是最终建图用的;
常用函数:
/** \brief Transform a Stamped Pose Message into the target frame and time
* This can throw all that lookupTransform can throw as well as tf::InvalidTransform */
void transformPose(const std::string& target_frame, const ros::Time& target_time,
const geometry_msgs::PoseStamped& pin,
const std::string& fixed_frame, geometry_msgs::PoseStamped& pout) const;
karto::LaserRangeFinder*
SlamKarto::getLaser(const sensor_msgs::LaserScan::ConstPtr& scan)
// Check whether we know about this laser yet
if(lasers_.find(scan->header.frame_id) == lasers_.end())
{
// New laser; need to create a Karto device for it.
//得到基坐标系下,laser的位置
// Get the laser's pose, relative to base.
tf::Stamped<tf::Pose> ident;
tf::Stamped<tf::Transform> laser_pose;
ident.setIdentity();
ident.frame_id_ = scan->header.frame_id;
ident.stamp_ = scan->header.stamp;
try
{
tf_.transformPose(base_frame_, ident, laser_pose);
}
catch(tf::TransformException e)
{
ROS_WARN("Failed to compute laser pose, aborting initialization (%s)",
e.what());
return NULL;
}
//得到laser的旋转角度
double yaw = tf::getYaw(laser_pose.getRotation());
ROS_INFO("laser %s's pose wrt base: %.3f %.3f %.3f",
scan->header.frame_id.c_str(),
laser_pose.getOrigin().x(),
laser_pose.getOrigin().y(),
yaw);
// To account for lasers that are mounted upside-down,
// we create a point 1m above the laser and transform it into the laser frame
// if the point's z-value is <=0, it is upside-down
tf::Vector3 v;
v.setValue(0, 0, 1 + laser_pose.getOrigin().z());
tf::Stamped<tf::Vector3> up(v, scan->header.stamp, base_frame_);
try
{
tf_.transformPoint(scan->header.frame_id, up, up);
ROS_DEBUG("Z-Axis in sensor frame: %.3f", up.z());
}
catch (tf::TransformException& e)
{
ROS_WARN("Unable to determine orientation of laser: %s", e.what());
return NULL;
}
bool inverse = lasers_inverted_[scan->header.frame_id] = up.z() <= 0;
if (inverse)
ROS_INFO("laser is mounted upside-down");
//相当于对Laser中的数据限定一些条件
// Create a laser range finder device and copy in data from the first scan
std::string name = scan->header.frame_id;
karto::LaserRangeFinder* laser =
karto::LaserRangeFinder::CreateLaserRangeFinder(karto::LaserRangeFinder_Custom, karto::Name(name));
laser->SetOffsetPose(karto::Pose2(laser_pose.getOrigin().x(),
laser_pose.getOrigin().y(),
yaw));
laser->SetMinimumRange(scan->range_min);
laser->SetMaximumRange(scan->range_max);
laser->SetMinimumAngle(scan->angle_min);
laser->SetMaximumAngle(scan->angle_max);
laser->SetAngularResolution(scan->angle_increment);
// TODO: expose this, and many other parameters
//laser_->SetRangeThreshold(12.0);
// Store this laser device for later
lasers_[scan->header.frame_id] = laser;
// Add it to the dataset, which seems to be necessary
dataset_->Add(laser);
}
//通过时间戳,得到里程计的位姿信息;这里的位姿信息是相对于成像坐标系的?!
bool
SlamKarto::getOdomPose(karto::Pose2& karto_pose, const ros::Time& t)
{
// Get the robot's pose
tf::Stamped<tf::Pose> ident (tf::Transform(tf::createQuaternionFromRPY(0,0,0),
tf::Vector3(0,0,0)), t, base_frame_);
tf::Stamped<tf::Transform> odom_pose;
try
{
//转换到里程计坐标系(成像坐标系下?)
tf_.transformPose(odom_frame_, ident, odom_pose);
}
catch(tf::TransformException e)
{
ROS_WARN("Failed to compute odom pose, skipping scan (%s)", e.what());
return false;
}
double yaw = tf::getYaw(odom_pose.getRotation());
karto_pose =
karto::Pose2(odom_pose.getOrigin().x(),
odom_pose.getOrigin().y(),
yaw);
return true;
}
对于激光laser的输入数据scan,添加局部的scan 数据--------- range_scan
将局部数据range_scan 添加到地图中,会得到优化过的 pose 信息。
// Compute the map->odom transform??
bool
SlamKarto::addScan(karto::LaserRangeFinder* laser,
const sensor_msgs::LaserScan::ConstPtr& scan,
karto::Pose2& karto_pose)
待续未完。。。。
上一篇: opencv3的学习
下一篇: vue起步
推荐阅读
-
在CLion下阅读karto_slam源码
-
Python3.7源码在windows(VS2015)下的编译和安装
-
在CentOS 6.0下搭建LAMP环境(源码安装)
-
在CentOS 6.0下搭建LAMP环境(源码安装)
-
在Windows下编译Cef3.2623并加入mp3、mp4支持(附带源码包和最终DLL)
-
werkzeug源码阅读笔记(二) 下
-
【面试题】研究过tomcat的NioEndpoint源码吗?请阐述下Reactor多线程模型在tomcat中的实现。
-
ESP32 开发笔记(三)源码示例 16_WIFI_AP_TCP_Server 在AP模式下实现TCP服务端
-
Python3.7源码在windows(VS2015)下的编译和安装
-
在windows下编写tail命令,提供源码和exe下载