学习记录-自动驾驶与机器人中的SLAM技术

这篇具有很好参考价值的文章主要介绍了学习记录-自动驾驶与机器人中的SLAM技术。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

以下所有内容均为高翔大神所注的《自动驾驶与机器人中的SLAM技术》中的内容

2D SLAM

  • 作者实现了一个2D 的ICP,包含了点到线的处理方式
  • 实现了一个似然场法的配准,介绍了相关公式,使用了高斯牛顿法和g2o进行求解,其中g2o中有对核函数的使用

3D SLAM

ICP

  • 实现了一个并发的ICP配准
  • 实现了点到面的ICP
  • 实现了点到线的ICP
  • 点到线的ICP的结果与点到点的ICP相当,略差于点到面的、在三中算法中,点到面的ICP在精度和效率上都具有一定优势,明显快于PCL的内置版本,单其单次迭代中计算量明显大于原始ICP

NDT

学习记录-自动驾驶与机器人中的SLAM技术,学习,自动驾驶,机器人

本书各配准算法与PCL的对比

学习记录-自动驾驶与机器人中的SLAM技术,学习,自动驾驶,机器人学习记录-自动驾驶与机器人中的SLAM技术,学习,自动驾驶,机器人

增量式NDT

需要解决两个问题:

  1. 每个体素内的高斯参数如何改变
  2. 如何维护不断增加的体素

高斯分布的增量更新

学习记录-自动驾驶与机器人中的SLAM技术,学习,自动驾驶,机器人

学习记录-自动驾驶与机器人中的SLAM技术,学习,自动驾驶,机器人

体素的增量维护

学习记录-自动驾驶与机器人中的SLAM技术,学习,自动驾驶,机器人

融合导航

1. EKF和优化的关系

学习记录-自动驾驶与机器人中的SLAM技术,学习,自动驾驶,机器人

2. 组合导航eskf中的预测部分,主要是F矩阵的构建

template <typename S>
bool ESKF<S>::Predict(const IMU& imu) {
    assert(imu.timestamp_ >= current_time_);

    double dt = imu.timestamp_ - current_time_;
    if (dt > (5 * options_.imu_dt_) || dt < 0) {
        // 时间间隔不对,可能是第一个IMU数据,没有历史信息
        LOG(INFO) << "skip this imu because dt_ = " << dt;
        current_time_ = imu.timestamp_;
        return false;
    }

    // nominal state 递推
    VecT new_p = p_ + v_ * dt + 0.5 * (R_ * (imu.acce_ - ba_)) * dt * dt + 0.5 * g_ * dt * dt;
    VecT new_v = v_ + R_ * (imu.acce_ - ba_) * dt + g_ * dt;
    SO3 new_R = R_ * SO3::exp((imu.gyro_ - bg_) * dt);

    R_ = new_R;
    v_ = new_v;
    p_ = new_p;
    // 其余状态维度不变

    // error state 递推
    // 计算运动过程雅可比矩阵 F,见(3.47)
    // F实际上是稀疏矩阵,也可以不用矩阵形式进行相乘而是写成散装形式,这里为了教学方便,使用矩阵形式
    Mat18T F = Mat18T::Identity();                                                 // 主对角线
    F.template block<3, 3>(0, 3) = Mat3T::Identity() * dt;                         // p 对 v
    F.template block<3, 3>(3, 6) = -R_.matrix() * SO3::hat(imu.acce_ - ba_) * dt;  // v对theta
    F.template block<3, 3>(3, 12) = -R_.matrix() * dt;                             // v 对 ba
    F.template block<3, 3>(3, 15) = Mat3T::Identity() * dt;                        // v 对 g
    F.template block<3, 3>(6, 6) = SO3::exp(-(imu.gyro_ - bg_) * dt).matrix();     // theta 对 theta
    F.template block<3, 3>(6, 9) = -Mat3T::Identity() * dt;                        // theta 对 bg

    // mean and cov prediction
    dx_ = F * dx_;  // 这行其实没必要算,dx_在重置之后应该为零,因此这步可以跳过,但F需要参与Cov部分计算,所以保留
    cov_ = F * cov_.eval() * F.transpose() + Q_;
    current_time_ = imu.timestamp_;
    return true;
}

3. 以下是速度量测,主要是H矩阵的构建

template <typename S>
bool ESKF<S>::ObserveWheelSpeed(const Odom& odom) {
    assert(odom.timestamp_ >= current_time_);
    // odom 修正以及雅可比
    // 使用三维的轮速观测,H为3x18,大部分为零
    Eigen::Matrix<S, 3, 18> H = Eigen::Matrix<S, 3, 18>::Zero();
    H.template block<3, 3>(0, 3) = Mat3T::Identity();

    // 卡尔曼增益
    Eigen::Matrix<S, 18, 3> K = cov_ * H.transpose() * (H * cov_ * H.transpose() + odom_noise_).inverse();

    // velocity obs
    double velo_l = options_.wheel_radius_ * odom.left_pulse_ / options_.circle_pulse_ * 2 * M_PI / options_.odom_span_;
    double velo_r = options_.wheel_radius_ * odom.right_pulse_ / options_.circle_pulse_ * 2 * M_PI / options_.odom_span_;
    double average_vel = 0.5 * (velo_l + velo_r);

    VecT vel_odom(average_vel, 0.0, 0.0);
    VecT vel_world = R_ * vel_odom;

    dx_ = K * (vel_world - v_);//v_是状态递推后的速度

    // update cov
    cov_ = (Mat18T::Identity() - K * H) * cov_;

    UpdateAndReset();
    return true;
}

4. 以下是GPS的量测,主要任然是H矩阵的构建

template <typename S>
bool ESKF<S>::ObserveGps(const GNSS& gnss) {
    /// GNSS 观测的修正
    assert(gnss.unix_time_ >= current_time_);

    if (first_gnss_) {
        R_ = gnss.utm_pose_.so3();
        p_ = gnss.utm_pose_.translation();
        first_gnss_ = false;
        current_time_ = gnss.unix_time_;
        return true;
    }

    assert(gnss.heading_valid_);
    ObserveSE3(gnss.utm_pose_, options_.gnss_pos_noise_, options_.gnss_ang_noise_);
    current_time_ = gnss.unix_time_;

    return true;
}

template <typename S>
bool ESKF<S>::ObserveSE3(const SE3& pose, double trans_noise, double ang_noise) {
    /// 既有旋转,也有平移
    /// 观测状态变量中的p, R,H为6x18,其余为零
    Eigen::Matrix<S, 6, 18> H = Eigen::Matrix<S, 6, 18>::Zero();
    H.template block<3, 3>(0, 0) = Mat3T::Identity();  // P部分
    H.template block<3, 3>(3, 6) = Mat3T::Identity();  // R部分(3.66)

    // 卡尔曼增益和更新过程
    Vec6d noise_vec;
    noise_vec << trans_noise, trans_noise, trans_noise, ang_noise, ang_noise, ang_noise;

    Mat6d V = noise_vec.asDiagonal();
    Eigen::Matrix<S, 18, 6> K = cov_ * H.transpose() * (H * cov_ * H.transpose() + V).inverse();

    // 更新x和cov
    Vec6d innov = Vec6d::Zero();
    innov.template head<3>() = (pose.translation() - p_);          // 平移部分
    innov.template tail<3>() = (R_.inverse() * pose.so3()).log();  // 旋转部分(3.67)

    dx_ = K * innov;
    cov_ = (Mat18T::Identity() - K * H) * cov_;

    UpdateAndReset();
    return true;
}

IMU预积分

  • 书中有IMU预积分所有的公式推导,包括了预积分计算公式,预积分相较于状态量的雅克比矩阵公式,误差传播公式等等

学习记录-自动驾驶与机器人中的SLAM技术,学习,自动驾驶,机器人文章来源地址https://www.toymoban.com/news/detail-787804.html

/**
 * IMU 预积分器
 *
 * 调用Integrate来插入新的IMU读数,然后通过Get函数得到预积分的值
 * 雅可比也可以通过本类获得,可用于构建g2o的边类
 */
class IMUPreintegration {
   public:
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
    /// 参数配置项
    /// 初始的零偏需要设置,其他可以不改
    struct Options {
        Options() {}
        Vec3d init_bg_ = Vec3d::Zero();  // 初始零偏
        Vec3d init_ba_ = Vec3d::Zero();  // 初始零偏
        double noise_gyro_ = 1e-2;       // 陀螺噪声,标准差
        double noise_acce_ = 1e-1;       // 加计噪声,标准差
    };

    IMUPreintegration(Options options = Options());

    /**
     * 插入新的IMU数据
     * @param imu   imu 读数
     * @param dt    时间差
     */
    void Integrate(const IMU &imu, double dt);

    /**
     * 从某个起始点开始预测积分之后的状态
     * @param start 起始时时刻状态
     * @return  预测的状态
     */
    NavStated Predict(const NavStated &start, const Vec3d &grav = Vec3d(0, 0, -9.81)) const;

    /// 获取修正之后的观测量,bias可以与预积分时期的不同,会有一阶修正
    SO3 GetDeltaRotation(const Vec3d &bg);
    Vec3d GetDeltaVelocity(const Vec3d &bg, const Vec3d &ba);
    Vec3d GetDeltaPosition(const Vec3d &bg, const Vec3d &ba);

   public:
    double dt_ = 0;                          // 整体预积分时间
    Mat9d cov_ = Mat9d::Zero();              // 累计噪声矩阵
    Mat6d noise_gyro_acce_ = Mat6d::Zero();  // 测量噪声矩阵

    // 零偏
    Vec3d bg_ = Vec3d::Zero();
    Vec3d ba_ = Vec3d::Zero();

    // 预积分观测量
    SO3 dR_;
    Vec3d dv_ = Vec3d::Zero();
    Vec3d dp_ = Vec3d::Zero();

    // 雅可比矩阵
    Mat3d dR_dbg_ = Mat3d::Zero();
    Mat3d dV_dbg_ = Mat3d::Zero();
    Mat3d dV_dba_ = Mat3d::Zero();
    Mat3d dP_dbg_ = Mat3d::Zero();
    Mat3d dP_dba_ = Mat3d::Zero();
};

到了这里,关于学习记录-自动驾驶与机器人中的SLAM技术的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ChatGPT +工业机器人/自动驾驶控制器的一些尝试

    ChatGPT 的功能目前已扩展到机器人领域,可以用语言直观控制如机械臂、无人机、家庭辅助机器人等的多个平台。这会改变人机交互的未来形式吗? 你可曾想过用自己的话告诉机器人该做什么,就像对人说话那样? 比如说,只要告诉你的家庭助理机器人「请帮我热一下午餐」

    2023年04月08日
    浏览(37)
  • 机器人SLAM导航学习-All in one

    参考引用 张虎,机器人SLAM导航核心技术与实战[M]. 机械工业出版社,2022. 本博客未详尽之处可自行查阅上述书籍 移动机器人激光SLAM导航(文章链接汇总) 1. ROS 入门必备知识 ROS学习笔记(文章链接汇总) 2. C++ 编程范式 《21天学通C++》读书笔记(文章链接汇总) 3. OpenCV 图像

    2024年02月16日
    浏览(31)
  • RPA自动化中的机器人开发:如何开发机器人软件

    随着工业4.0时代的到来,企业对于提高生产效率、降低成本的需求越来越强烈,机器人自动化技术作为其中的一部分,逐渐被广泛应用。机器人自动化技术的其中一个分支——机器人软件,对于机器人的开发和应用具有重要的推动作用。本文旨在介绍如何进行机器人软件的开

    2024年02月13日
    浏览(39)
  • ROS学习笔记08、机器人导航仿真(slam、map_server、amcl、move_base与导航消息介绍)

    马上开学,目前学校很多实验室都是人工智能这块,大部分都是和机器人相关,然后软件这块就是和cv、ros相关,就打算开始学习一下。 本章节是虚拟机安装Ubuntu18.04以及安装ROS的环境。 学习教程:【Autolabor初级教程】ROS机器人入门,博客中一些知识点是来源于赵老师的笔记

    2023年04月12日
    浏览(33)
  • [机器人相关学习记录] KUKA 的仿真工具

    KUKA Sim Pro v3.1.2 和 Workvisual 的区别 项目 KUKA Sim Pro v3.1.2 Workvisual 功能 专注于机器人仿真和编程 集成机器人仿真、编程和监控 适用场景 适用于机器人研发、调试和教育 适用于机器人生产、调试、维修和管理 界面 简洁,侧重于机器人仿真和编程操作 更为全面,包含机器人状态

    2024年04月27日
    浏览(30)
  • 机器人SLAM与自主导航

    机器人技术的迅猛发展,促使机器人逐渐走进了人们的生活,服务型室内移动机器人更是获得了广泛的关注。但室内机器人的普及还存在许多亟待解决的问题,定位与导航就是其中的关键问题之一。在这类问题的研究中,需要把握三个重点:一是地图精确建模;二是机器人准

    2024年02月08日
    浏览(29)
  • 机器人强化学习环境mujoco官方文档学习记录(一)——XML

    鉴于研究生课题需要,开始在mujoco中配置仿真环境。而官方文档中各种对象参数纷繁复杂,且涉及mujoco底层计算,不便于初学者进行开发设计。因此本文将MJCF模型的常用对象参数进行总结。 本文档仅供学习参考,如有问题欢迎大家学习交流。 本章是MuJoCo中使用的MJCF建模语言

    2024年02月02日
    浏览(34)
  • 【RTB机器人工具箱学习记录】轨迹规划实例

    给定位置: 位姿插值: trinterp() trinterp(T0, T1, M) ​ T0:初始变换矩阵 ​ T1:结束变换矩阵 ​ M: 线性插值轨迹动画:(轨迹如上图左所示) 五次多项式插值轨迹动画:(轨迹如上图右所示,和上面用mtraj遍历方式的轨迹相同) 笛卡尔轨迹 ctraj() : TC = ctraj(T0, T1, N) ​ T0:初始变

    2023年04月22日
    浏览(35)
  • 移动机器人激光SLAM导航(五):Cartographer SLAM 篇

    参考 Cartographer 官方文档 Cartographer 从入门到精通 1.1 前置条件 推荐在刚装好的 Ubuntu 16.04 或 Ubuntu 18.04 上进行编译 ROS 安装:ROS学习1:ROS概述与环境搭建 1.2 依赖库安装 资源下载完解压并执行以下指令 https://pan.baidu.com/s/1LWqZ4SOKn2sZecQUDDXXEw?pwd=j6cf 1.3 编译 本文只编译 cartographer

    2024年02月21日
    浏览(33)
  • 机器人学|手机玻璃加工全自动化——AGV+机器人+视觉解决方案(含双目三维视觉SLAM建图、MATLAB的AGV路径规划导航避障、六轴机械手臂建模与路径规划仿真,附带源代码)

    文章目录 前言 一、国内外移动操作机器人现状 二、方案概述 三、主要部件BOM清单 1.差动轮式AGV: 2.UR5系列机械臂 3.Cognex智能相机 4.加工台 5.控制系统 6.电源和电缆 四、技术点及工作流程 五、计算自动化方案与人工方案成本收回时间 1.自动化方案成本分析: 2.人工方案成本

    2024年01月22日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包