多传感器融合MSF算法源码阅读(三)

2023-05-16

文章目录

  • 1.触发测量更新回调函数
  • 2.测量更新状态量
  • 3.总结

无人驾驶算法学习(六):多传感器融合MSF算法
多传感器融合MSF算法源码阅读(一)
多传感器融合MSF算法源码阅读(二)

1.触发测量更新回调函数

  • 查看主类PoseSensorManager的构造函数。注意,在构造函数中调用了类PoseSensorHandler

ethzasl_msf/msf_updates/src/pose_msf/pose_sensormanager.h中查看

 typedef PoseSensorHandler<msf_updates::pose_measurement::PoseMeasurement<>,
      PoseSensorManager> PoseSensorHandler_T;
      
PoseSensorManager(ros::NodeHandle pnh = ros::NodeHandle("~/pose_sensor")) {
    bool distortmeas = false;  ///< Distort the pose measurements.

    imu_handler_.reset(
        new msf_core::IMUHandler_ROS<msf_updates::EKFState>(*this, "msf_core",
                                                            "imu_handler"));
    pose_handler_.reset(
        new PoseSensorHandler_T(*this, "", "pose_sensor", distortmeas));

    AddHandler(pose_handler_);

    reconf_server_.reset(new ReconfigureServer(pnh));
    ReconfigureServer::CallbackType f = boost::bind(&PoseSensorManager::Config,
                                                    this, _1, _2);
    reconf_server_->setCallback(f);

    init_scale_srv_ = pnh.advertiseService("initialize_msf_scale",
                                           &PoseSensorManager::InitScale, this);
    init_height_srv_ = pnh.advertiseService("initialize_msf_height",
                                            &PoseSensorManager::InitHeight,
                                            this);
  }
  • 类PoseSensorHandler中,在构造函数中挂载了三个不同的MeasurementCallback函数:

ethzasl_msf/msf_updates/include/msf_updates/pose_sensor_handler/implementation/pose_sensorhandler.hpp查看:
重载函数的形参:
geometry_msgs::PoseWithCovarianceStamped,geometry_msgs::TransformStamped,geometry_msgs::PoseStamped三种消息类型。

如geometry_msgs::PoseWithCovarianceStamped:
subPoseWithCovarianceStamped_ =
      nh.subscribe < geometry_msgs::PoseWithCovarianceStamped
          > ("pose_with_covariance_input", 20, &PoseSensorHandler::MeasurementCallback, this);

实现:
template<typename MEASUREMENT_TYPE, typename MANAGER_TYPE>
void PoseSensorHandler<MEASUREMENT_TYPE, MANAGER_TYPE>::MeasurementCallback(
    const geometry_msgs::PoseStampedConstPtr & msg) {
  this->SequenceWatchDog(msg->header.seq, subPoseStamped_.getTopic());
  MSF_INFO_STREAM_ONCE(
      "*** pose sensor got first measurement from topic "
          << this->topic_namespace_ << "/" << subPoseStamped_.getTopic()
          << " ***");

  geometry_msgs::PoseWithCovarianceStampedPtr pose(
      new geometry_msgs::PoseWithCovarianceStamped());

  if (!use_fixed_covariance_)  // Take covariance from sensor.
  {
    MSF_WARN_STREAM_THROTTLE(
        2,
        "Provided message type without covariance but set fixed_covariance =="
        "false at the same time. Discarding message.");
    return;
  }
*重要*
template<typename MEASUREMENT_TYPE, typename MANAGER_TYPE>
void PoseSensorHandler<MEASUREMENT_TYPE, MANAGER_TYPE>::MeasurementCallback(
    const geometry_msgs::PoseWithCovarianceStampedConstPtr & msg) {

  this->SequenceWatchDog(msg->header.seq,
                         subPoseWithCovarianceStamped_.getTopic());
  MSF_INFO_STREAM_ONCE(
      "*** pose sensor got first measurement from topic "
          << this->topic_namespace_ << "/"
          << subPoseWithCovarianceStamped_.getTopic() << " ***");
  ProcessPoseMeasurement(msg);
}

2.测量更新状态量

ethzasl_msf/msf_updates/include/msf_updates/pose_sensor_handler/implementation/pose_sensorhandler.hpp查看:
ProcessPoseMeasurement(msg)函数:

template<typename MEASUREMENT_TYPE, typename MANAGER_TYPE>
void PoseSensorHandler<MEASUREMENT_TYPE, MANAGER_TYPE>::ProcessPoseMeasurement(const geometry_msgs::PoseWithCovarianceStampedConstPtr & msg) 
{
  received_first_measurement_ = true;

  // Get the fixed states.
  int fixedstates = 0;
  static_assert(msf_updates::EKFState::nStateVarsAtCompileTime < 32, "Your state "
      "has more than 32 variables. The code needs to be changed here to have a "
      "larger variable to mark the fixed_states");
  // Do not exceed the 32 bits of int.

  // Get all the fixed states and set flag bits.
  MANAGER_TYPE* mngr = dynamic_cast<MANAGER_TYPE*>(&manager_);

  // TODO(acmarkus): if we have multiple sensor handlers, they all share the same dynparams,
  // which me maybe don't want. E.g. if we have this for multiple AR Markers, we
  // may want to keep one fix --> move this to fixed parameters? Could be handled
  // with parameter namespace then.
  if (mngr) {
    if (mngr->Getcfg().pose_fixed_scale) {
      fixedstates |= 1 << MEASUREMENT_TYPE::AuxState::L;
    }
    if (mngr->Getcfg().pose_fixed_p_ic) {
      fixedstates |= 1 << MEASUREMENT_TYPE::AuxState::p_ic;
    }
    if (mngr->Getcfg().pose_fixed_q_ic) {
      fixedstates |= 1 << MEASUREMENT_TYPE::AuxState::q_ic;
    }
    if (mngr->Getcfg().pose_fixed_p_wv) {
      fixedstates |= 1 << MEASUREMENT_TYPE::AuxState::p_wv;
    }
    if (mngr->Getcfg().pose_fixed_q_wv) {
      fixedstates |= 1 << MEASUREMENT_TYPE::AuxState::q_wv;
    }
  }

  shared_ptr<MEASUREMENT_TYPE> meas(new MEASUREMENT_TYPE(
      n_zp_, n_zq_, measurement_world_sensor_, use_fixed_covariance_,
      provides_absolute_measurements_, this->sensorID,
      enable_mah_outlier_rejection_, mah_threshold_, fixedstates, distorter_));

  meas->MakeFromSensorReading(msg, msg->header.stamp.toSec() - delay_);

  z_p_ = meas->z_p_;  //store this for the init procedure
  z_q_ = meas->z_q_;

  this->manager_.msf_core_->AddMeasurement(meas);
}

这里调用了this->manager_.msf_core_->AddMeasurement(meas),查看AddMeasurement方法, 注意AddMeasurement方法中的 it_meas->second->Apply(state, this); 这句代码,调用了PoseMeasurement的Apply方法。Apply方法要求this参数,将MSF_Core作为参数传入,这在Apply执行过程中有一个调用core.ApplyCorrection()的步骤。

shared_ptr<MEASUREMENT_TYPE> meas(new MEASUREMENT_TYPE( n_zp_, n_zq_, measurement_world_sensor_, use_fixed_covariance_, provides_absolute_measurements_, this->sensorID, enable_mah_outlier_rejection_, mah_threshold_, fixedstates, distorter_));中new MEASUREMENT_TYPE,也就是new了一个struct PoseMeasurement
原因:主类PoseSensorManager的构造函数:
typedef PoseSensorHandler<msf_updates::pose_measurement::PoseMeasurement<>,
PoseSensorManager> PoseSensorHandler_T;
所以MEASUREMENT_TYPE就是msf_updates::pose_measurement::PoseMeasurement<>

ethzasl_msf/msf_updates/include/msf_updates/pose_sensor_handler/pose_measurement.h查看
struct PoseMeasurement : public PoseMeasurementBase 数据结构完成测量更新

分析其中最核心的Apply函数:
里面有2个方法CalculateAndApplyCorrection和CalculateAndApplyCorrectionRelative,这2个方法在父类MSF_MeasurementBase<EKFState_T>中实现, 这2个方法实现了EKF方法的更新步骤.

/**
   * The method called by the msf_core to apply the measurement represented by
   * this object
   */
  virtual void Apply(shared_ptr<EKFState_T> state_nonconst_new,
                     msf_core::MSF_Core<EKFState_T>& core) {

    if (isabsolute_) {  // Does this measurement refer to an absolute measurement,
      // or is is just relative to the last measurement.
      // Get a const ref, so we can read core states
      const EKFState_T& state = *state_nonconst_new;
      // init variables
      Eigen::Matrix<double, nMeasurements,
          msf_core::MSF_Core<EKFState_T>::nErrorStatesAtCompileTime> H_new;
      Eigen::Matrix<double, nMeasurements, 1> r_old;

      CalculateH(state_nonconst_new, H_new);

      // Get rotation matrices.
      Eigen::Matrix<double, 3, 3> C_wv = state.Get<StateQwvIdx>()

          .conjugate().toRotationMatrix();
      Eigen::Matrix<double, 3, 3> C_q = state.Get<StateDefinition_T::q>()
          .conjugate().toRotationMatrix();

      // Construct residuals.
      // Position.
      r_old.block<3, 1>(0, 0) = z_p_
          - (C_wv.transpose()
              * (-state.Get<StatePwvIdx>()
                  + state.Get<StateDefinition_T::p>()
                  + C_q.transpose() * state.Get<StatePicIdx>()))
              * state.Get<StateLIdx>();

      // Attitude.
      Eigen::Quaternion<double> q_err;
      q_err = (state.Get<StateQwvIdx>()
          * state.Get<StateDefinition_T::q>()
          * state.Get<StateQicIdx>()).conjugate() * z_q_;
      r_old.block<3, 1>(3, 0) = q_err.vec() / q_err.w() * 2;
      // Vision world yaw drift.
      q_err = state.Get<StateQwvIdx>();

      r_old(6, 0) = -2 * (q_err.w() * q_err.z() + q_err.x() * q_err.y())
          / (1 - 2 * (q_err.y() * q_err.y() + q_err.z() * q_err.z()));

      if (!CheckForNumeric(r_old, "r_old")) {
        MSF_ERROR_STREAM("r_old: "<<r_old);
        MSF_WARN_STREAM(
            "state: "<<const_cast<EKFState_T&>(state). ToEigenVector().transpose());
      }
      if (!CheckForNumeric(H_new, "H_old")) {
        MSF_ERROR_STREAM("H_old: "<<H_new);
        MSF_WARN_STREAM(
            "state: "<<const_cast<EKFState_T&>(state). ToEigenVector().transpose());
      }
      if (!CheckForNumeric(R_, "R_")) {
        MSF_ERROR_STREAM("R_: "<<R_);
        MSF_WARN_STREAM(
            "state: "<<const_cast<EKFState_T&>(state). ToEigenVector().transpose());
      }

      // Call update step in base class.
      this->CalculateAndApplyCorrection(state_nonconst_new, core, H_new, r_old,
                                        R_);
    } else {
      // Init variables: Get previous measurement.
      shared_ptr < msf_core::MSF_MeasurementBase<EKFState_T> > prevmeas_base =
          core.GetPreviousMeasurement(this->time, this->sensorID_);

      if (prevmeas_base->time == msf_core::constants::INVALID_TIME) {
        MSF_WARN_STREAM(
            "The previous measurement is invalid. Could not apply measurement! " "time:"<<this->time<<" sensorID: "<<this->sensorID_);
        return;
      }

      // Make this a pose measurement.
      shared_ptr<PoseMeasurement> prevmeas = dynamic_pointer_cast
          < PoseMeasurement > (prevmeas_base);
      if (!prevmeas) {
        MSF_WARN_STREAM(
            "The dynamic cast of the previous measurement has failed. "
            "Could not apply measurement");
        return;
      }

      // Get state at previous measurement.
      shared_ptr<EKFState_T> state_nonconst_old = core.GetClosestState(
          prevmeas->time);

      if (state_nonconst_old->time == msf_core::constants::INVALID_TIME) {
        MSF_WARN_STREAM(
            "The state at the previous measurement is invalid. Could "
            "not apply measurement");
        return;
      }

      // Get a const ref, so we can read core states.
      const EKFState_T& state_new = *state_nonconst_new;
      const EKFState_T& state_old = *state_nonconst_old;

      Eigen::Matrix<double, nMeasurements,
          msf_core::MSF_Core<EKFState_T>::nErrorStatesAtCompileTime> H_new,
          H_old;
      Eigen::Matrix<double, nMeasurements, 1> r_new, r_old;

      CalculateH(state_nonconst_old, H_old);

      H_old *= -1;

      CalculateH(state_nonconst_new, H_new);

      //TODO (slynen): check that both measurements have the same states fixed!
      Eigen::Matrix<double, 3, 3> C_wv_old, C_wv_new;
      Eigen::Matrix<double, 3, 3> C_q_old, C_q_new;

      C_wv_new = state_new.Get<StateQwvIdx>().conjugate().toRotationMatrix();
      C_q_new = state_new.Get<StateDefinition_T::q>().conjugate()
          .toRotationMatrix();

      C_wv_old = state_old.Get<StateQwvIdx>().conjugate().toRotationMatrix();
      C_q_old = state_old.Get<StateDefinition_T::q>().conjugate()
          .toRotationMatrix();

      // Construct residuals.
      // Position:
      Eigen::Matrix<double, 3, 1> diffprobpos = (C_wv_new.transpose()
          * (-state_new.Get<StatePwvIdx>() + state_new.Get<StateDefinition_T::p>()
              + C_q_new.transpose() * state_new.Get<StatePicIdx>()))
          * state_new.Get<StateLIdx>() - (C_wv_old.transpose()
          * (-state_old.Get<StatePwvIdx>() + state_old.Get<StateDefinition_T::p>()
              + C_q_old.transpose() * state_old.Get<StatePicIdx>()))
              * state_old.Get<StateLIdx>();


      Eigen::Matrix<double, 3, 1> diffmeaspos = z_p_ - prevmeas->z_p_;

      r_new.block<3, 1>(0, 0) = diffmeaspos - diffprobpos;

      // Attitude:
      Eigen::Quaternion<double> diffprobatt = (state_new.Get<StateQwvIdx>()
          * state_new.Get<StateDefinition_T::q>()
          * state_new.Get<StateQicIdx>()).conjugate()
          * (state_old.Get<StateQwvIdx>()
              * state_old.Get<StateDefinition_T::q>()
              * state_old.Get<StateQicIdx>());

      Eigen::Quaternion<double> diffmeasatt = z_q_.conjugate() * prevmeas->z_q_;

      Eigen::Quaternion<double> q_err;
      q_err = diffprobatt.conjugate() * diffmeasatt;

      r_new.block<3, 1>(3, 0) = q_err.vec() / q_err.w() * 2;
      // Vision world yaw drift.
      q_err = state_new.Get<StateQwvIdx>();

      r_new(6, 0) = -2 * (q_err.w() * q_err.z() + q_err.x() * q_err.y())
          / (1 - 2 * (q_err.y() * q_err.y() + q_err.z() * q_err.z()));

      if (!CheckForNumeric(r_old, "r_old")) {
        MSF_ERROR_STREAM("r_old: "<<r_old);
        MSF_WARN_STREAM(
            "state: "<<const_cast<EKFState_T&>(state_new). ToEigenVector().transpose());
      }
      if (!CheckForNumeric(H_new, "H_old")) {
        MSF_ERROR_STREAM("H_old: "<<H_new);
        MSF_WARN_STREAM(
            "state: "<<const_cast<EKFState_T&>(state_new). ToEigenVector().transpose());
      }
      if (!CheckForNumeric(R_, "R_")) {
        MSF_ERROR_STREAM("R_: "<<R_);
        MSF_WARN_STREAM(
            "state: "<<const_cast<EKFState_T&>(state_new). ToEigenVector().transpose());
      }

      // Call update step in base class.
      this->CalculateAndApplyCorrectionRelative(state_nonconst_old,
                                                state_nonconst_new, core, H_old,
                                                H_new, r_new, R_);

    }

3.总结

MSF_Core类负责汇集IMU消息和位姿观测值,同时实现了状态预测

在这里插入图片描述

而msf_updates::pose_measurement::PoseMeasurement<>实现了状态的更新。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多传感器融合MSF算法源码阅读(三) 的相关文章

  • ROS与C++入门教程-消息-序列化和适配类型

    原文地址 xff1a ROS与C 43 43 入门教程 消息 序列化和适配类型 创客智造 说明 xff1a 介绍序列化和适配类型在C Turtle版本增加 序列化到内存 使用ros serialization serialize 函数 xf
  • 前方高能,官方教程:教你如何玩转 GitHub !

    回复 1024 xff0c 送你一个特别推送 作为程序员 xff0c 一般手上会有三把剑 xff0c 用好了这三把剑 xff0c 对于编程来说 xff0c 对于解决编程中遇到的 Bug xff0c 都应该能够轻而易举的解决 程序员手中的三把
  • 树莓派安装宝塔面板后无法连接VNC

    解决方法 xff1a 登陆宝塔面板后台 xff0c 在 安全 中放行端口5900即可
  • Python并行处理视频帧

    参考链接 xff1a Speedy Computer Vision Pipelines using Parallelism 方案 xff1a 使用Python多进程编程 xff0c 将视频分成多个小段 xff0c 可按照CPU核数num p
  • 深度学习目标检测之SSD

    经典论文SSD笔记 论文链接 xff1a SSD Single Shot MultiBox Detector论文报告 xff1a ssd eccv2016 slide目标检测百页综述 xff0c 从传统方法到深度学习 xff1a Objec
  • C++编译报错fmt未定义的引用

    对 fmt v5 internal basic data POWERS OF 10 64 未定义的引用 1 最简单的方法 xff1a 把代码中printf的输出全部换成std cout或者其他的 2 安装fmt包 git clone htt
  • PyG/torch_geometric的一些坑

    安装PyG span class token keyword import span os span class token keyword import span torch os span class token punctuation
  • Pixhawk官网飞行模式介绍

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a Flight Mode 飞行模式 原文地址 http dev px4 io concept flight modes html 飞行模式定义了系统在任何给定时间的状态
  • PX4中文维基汉化项目启动

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a 敬启者 xff1a 打算进行PX4官网的汉化工作 GitBook 与官网的方式相同 xff0c 我们也是将网站以GitBook的方式呈现给大家 汉化后的版本先点点点点
  • Windows / Ubuntu操作系统下Pixhawk原生固件PX4的编译方法

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a 更新于2017 3 13 FAQ 本文说明针对 PX4 Firmware 1 6 0 问题 1 xff1a 找不到python jinja2模块 CMake Erro
  • Sublime Text中文乱码的解决方法

    Sublime Text Sublime Text这款代码编译器相当不错 xff0c 自带高亮显示 xff0c 界面清新 但是Sublime Text默认是不支持中文显示的 xff0c 这种中文乱码的行为万万是不能够接受的 这里简单介绍一下
  • 自制Pixhawk飞控板烧写BootLoader教程

    对于自己制作的飞控板 xff0c 通过USB连接电脑之后 xff0c 开始电脑是无法检测到飞控板的端口存在的 检测不到端口 xff0c 就不能用控制台给飞控板烧写固件 xff0c 就不能用QGroundControl xff0c 就不能进行
  • Pixhawk原生固件PX4之常用函数解读

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a PX4Firmware 经常有人将Pixhawk PX4 APM还有ArduPilot弄混 这里首先还是简要说明一下 xff1a Pixhawk是飞控硬件平台 xff
  • Pixhawk原生固件PX4之添加uORB主题

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a 本说明针对 Firmware v1 5 4 1 添加流程说明 1 在Firmware msg下新建uORB的成员变量 xff0c eg xxx msg 2 在Firm
  • Pixhawk原生固件PX4之SITL软件在环仿真

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a 故事开始之前 xff0c 先按照笔者的这一篇博客在Ubuntu上完成固件的编译 jMAVSim仿真 jMAVSim仿真不需要任何配置 xff0c 直接输入指令即可 s
  • Pixhawk原生固件PX4之串口读取信息

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a 这篇博客纯粹出于对FreeApe这位先行者贡献的复现 xff0c 也是本人一直想要进行的一项操作 在此还是做一下记录 时代在改变 xff0c 代码在更新 xff0c
  • Effective Modern C++ 条款21 比起直接使用new,更偏爱使用std::make_unique和std::make_shared

    比起直接使用new xff0c 更偏爱使用std make unique和std make shared 让我们从std make unique和std make shared之间的比较开始讲起吧 std make shared是C 43
  • Pixhawk原生固件PX4之串口添加读取传感器实现

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a 本博客承接前一篇 xff0c 对FreeApe的串口添加超声波传感器博文后半部分进行学习 为什么叫前奏呢 xff0c 因为用了伪传感器 xff0c 把单片机用串口发送
  • Pixhawk原生固件PX4之MAVLink协议解析

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a PX4 对Mavlink 协议提供了良好的原生支持 该协议既可以用于地面站 Ground ControlStation GCS 对无人机 UAV 的控制 xff0c
  • Pixhawk原生固件PX4之TAKEOFF的启动流程

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a 以TAKEOFF为例说明PX4中一个飞行模式的启动流程 众所周知由遥控器或者地面站决定Main state作为用户期望到达的飞行模式然后有commander进行条件判

随机推荐

  • Pixhawk原生固件PX4之驱动ID

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a 驱动ID PX4使用驱动ID将独立传感器贯穿于整个系统 这些ID存储于配置参数中 xff0c 用于匹配传感器校正值 xff0c 以及决定哪些传感器被记录到log中 传
  • Pixhawk原生固件PX4之SPI驱动注册过程

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a 一切事出有因 xff0c 为了添加一个自定义SPI总线连接的传感器 xff0c 首先要弄清楚一个SPI设备的注册过程 xff0c 大致涉及以下的一些文件 接下来就该以
  • Pixhawk原生固件PX4之MPU6000驱动分析

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a 要想自己添加一个传感器的话 xff0c 最好先搞明白已有的传感器的工作过程 这里记录一下PX4中MPU6000加速度计陀螺仪的解读过程 xff0c 从mpu6000
  • Pixhawk原生固件PX4之日期时间的确定

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a 偶然注意到PX4日志中老是出现类似于2000 01 01 00 00 00这种日期 有兴趣的可以搜索一下千年虫问题 xff0c 于是结合代码进行了一波分析 最后定位到
  • Pixhawk原生固件PX4之添外置传感器MPU6500

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a 成功的在Pixhawk上添加了一个自定义的传感器MPU6500 Pixhawk飞控板上空余出一个SPI4接口 提示 xff1a 多出来的GPIO EXT引脚可以作为片
  • 多旋翼无人机进阶教程

    无人机是一个系统的工程 xff0c 不可谓不庞大 开源飞控盛行 xff0c 重复造轮子的工作实在无需再做 但是若决定真正的去研究飞控 xff0c 必须从本质出发 xff0c 熟悉并了解其实现原理 纷繁复杂的资料 xff0c 让人无法分辨 笔
  • Pixhawk原生固件PX4之MAVLink外部通讯

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a 目前的需求是 xff1a 一台电脑连数传 xff0c Pixhawk飞控上电连数传 xff0c 电脑向Pixhawk发送MAVlink消息 至少有5种方案 xff1a
  • rtsp流浏览器播放方案

    rtsp流在主流浏览器并不支持直接播放 比如大华的视频流 xff1a rtsp admin 123456 64 192 168 10 129 cam realmonitor channel 61 1 amp subtype 61 0 xff
  • PX4开发指南中文版维护说明

    PX4中文维基现已与PX4开发者官网合并 现在大家可以直接进入官网进行语言切换 PX4中文版的维护依然需要你的贡献 贡献说明 xff1a 官方的GitHub仓库为https github com PX4 Devguide 我将其Fork后的
  • OpenCV图像坐标系与行列宽高的关系

    刚开始接触图像处理 xff0c 关于图像坐标系与行列宽高的关系感到纠结 xff0c 但是似乎没有更好的处理方法了 xff0c 其对应关系大致如下 row 61 61 height 61 61 Point y col 61 61 width
  • Pixhawk原生固件PX4之位姿控制算法解读

    欢迎交流 个人 Gitter 交流平台 xff0c 点击直达 xff1a 参考文献 xff1a Minimum Snap Trajectory Generation and Control for Quadrotors PX4中多旋翼无人机
  • Pixhawk精准着陆之IRLock配置

    安装说明 下载Pixymon和pixy对应markone的固件 xff0c 在这里 固件必须是firmware IRLOCKpixy 1 0 1 hex irlock 61 markone 然后固件里 irlock 61 pixy 给Pix
  • Pixhawk原生固件PX4之offboard

    offboard PX4中的offboard 暂译作外部控制 是一个非常强大的功能 可以接受来自外部的控制指令 xff0c 按照目前的了解来看 xff0c offboard搭配上MAVROS以及类似于TX1 NUC板载计算器 xff0c 在
  • 相机标定原理

    cnblogs上的这篇讲相机标定的博文值得一看 csdn上这篇也可以参考 相机标定基础知识 相机标定技术涉及到一些数学原理和几何模型 xff0c 这些数学原理和几何模型是相机标定算法使用和进一步发展的基础 下面对相机标定技术中涉及到的齐次坐
  • VS Code的Git插件

    Visual Studio Code是微软公司推出的一款跨平台代码编辑 Edit 编译 Build 调试 Debug 工具 笔者认为其相当于是Sublime Text这款代码编辑器的升级版 集成了丰富的插件 xff0c 包括代码管理中极为常
  • Ubuntu缺少libncurses.so.5的解决办法

    执行arm none eabi gdb时候出错 xff1a arm none eabi gdb error while loading shared libraries libncurses so 5 cannot open shared
  • freeRTOS的任务抢占和时间片轮转

    实时操作系统的一个特点就是可以任务抢占 xff0c 高优先级的任务可以抢占比自己优先级低的任务 xff0c 如果新任务优先级和当前人任务优先级一样 xff0c 且在使能了时间片的方式的话 xff0c 二者以时间片的方式共享cpu xff0c
  • RH850 F1L freeRTOS 任务栈的切换

    pxCurrentTCB指向的任务块中 xff0c 有2个和栈相关的变量pxTopOfStack和pxStack pxTopOfStack指向当前堆栈栈顶 xff0c 随着进栈出栈 xff0c pxTopOfStack指向的位置是会变化的
  • opencv 3.0 图像去畸变 undistortion

    主要用到的是 initUndistortRectif yMap这个函数 在opencv中这个函数是用于 去除镜头畸变的图像拉伸 为了快速算法 xff1a 使用了坐标查找变和双线性差值的方法 先上结果图 原图 去畸变至全图 去畸变并保留最大图
  • 多传感器融合MSF算法源码阅读(三)

    文章目录 1 触发测量更新回调函数2 测量更新状态量3 总结 无人驾驶算法学习 xff08 六 xff09 xff1a 多传感器融合MSF算法 多传感器融合MSF算法源码阅读 一 多传感器融合MSF算法源码阅读 二 1 触发测量更新回调函数