px4+vins+ego单机鲁棒飞行二-1(更改px4外部视觉估计固件)

2023-05-16

px4+vins+ego单机鲁棒飞行二-1(更改px4外部视觉估计固件)

  • 一、EKF2源码-获取视觉里程计信息
  • 二、EKF2源码-设置外部视觉数据
  • 三、源码中对位置的发送
  • 四、测试

前提:固件1.11.2

一、EKF2源码-获取视觉里程计信息

位置:PX4-Autopolot/src/modules/ekf2/ekf2_main.cpp中void Ekf2::Run()函数,大概在第1100行

		// get external vision data
		// if error estimates are unavailable, use parameter defined defaults
		new_ev_data_received = false;

		if (_ev_odom_sub.updated()) {
			new_ev_data_received = true;

			// copy both attitude & position, we need both to fill a single extVisionSample
			_ev_odom_sub.copy(&_ev_odom);

			extVisionSample ev_data {};

			// check for valid velocity data
			if (PX4_ISFINITE(_ev_odom.vx) && PX4_ISFINITE(_ev_odom.vy) && PX4_ISFINITE(_ev_odom.vz)) {
				ev_data.vel(0) = _ev_odom.vx;
				ev_data.vel(1) = _ev_odom.vy;
				ev_data.vel(2) = _ev_odom.vz;

				if (_ev_odom.velocity_frame == vehicle_odometry_s::BODY_FRAME_FRD) {
					ev_data.vel_frame = estimator::BODY_FRAME_FRD;

				} else {
					ev_data.vel_frame = estimator::LOCAL_FRAME_FRD;
				}

				// velocity measurement error from ev_data or parameters
				float param_evv_noise_var = sq(_param_ekf2_evv_noise.get());

				if (!_param_ekf2_ev_noise_md.get() && PX4_ISFINITE(_ev_odom.velocity_covariance[_ev_odom.COVARIANCE_MATRIX_VX_VARIANCE])
				    && PX4_ISFINITE(_ev_odom.velocity_covariance[_ev_odom.COVARIANCE_MATRIX_VY_VARIANCE])
				    && PX4_ISFINITE(_ev_odom.velocity_covariance[_ev_odom.COVARIANCE_MATRIX_VZ_VARIANCE])) {
					ev_data.velCov(0, 0) = _ev_odom.velocity_covariance[_ev_odom.COVARIANCE_MATRIX_VX_VARIANCE];
					ev_data.velCov(0, 1) = ev_data.velCov(1, 0) = _ev_odom.velocity_covariance[1];
					ev_data.velCov(0, 2) = ev_data.velCov(2, 0) = _ev_odom.velocity_covariance[2];
					ev_data.velCov(1, 1) = _ev_odom.velocity_covariance[_ev_odom.COVARIANCE_MATRIX_VY_VARIANCE];
					ev_data.velCov(1, 2) = ev_data.velCov(2, 1) = _ev_odom.velocity_covariance[7];
					ev_data.velCov(2, 2) = _ev_odom.velocity_covariance[_ev_odom.COVARIANCE_MATRIX_VZ_VARIANCE];

				} else {
					ev_data.velCov = matrix::eye<float, 3>() * param_evv_noise_var;
				}
			}

			// check for valid position data
			if (PX4_ISFINITE(_ev_odom.x) && PX4_ISFINITE(_ev_odom.y) && PX4_ISFINITE(_ev_odom.z)) {
				ev_data.pos(0) = _ev_odom.x;
				ev_data.pos(1) = _ev_odom.y;
				ev_data.pos(2) = _ev_odom.z;

				float param_evp_noise_var = sq(_param_ekf2_evp_noise.get());

				// position measurement error from ev_data or parameters
				if (!_param_ekf2_ev_noise_md.get() && PX4_ISFINITE(_ev_odom.pose_covariance[_ev_odom.COVARIANCE_MATRIX_X_VARIANCE])
				    && PX4_ISFINITE(_ev_odom.pose_covariance[_ev_odom.COVARIANCE_MATRIX_Y_VARIANCE])
				    && PX4_ISFINITE(_ev_odom.pose_covariance[_ev_odom.COVARIANCE_MATRIX_Z_VARIANCE])) {
					ev_data.posVar(0) = fmaxf(param_evp_noise_var, _ev_odom.pose_covariance[_ev_odom.COVARIANCE_MATRIX_X_VARIANCE]);
					ev_data.posVar(1) = fmaxf(param_evp_noise_var, _ev_odom.pose_covariance[_ev_odom.COVARIANCE_MATRIX_Y_VARIANCE]);
					ev_data.posVar(2) = fmaxf(param_evp_noise_var, _ev_odom.pose_covariance[_ev_odom.COVARIANCE_MATRIX_Z_VARIANCE]);

				} else {
					ev_data.posVar.setAll(param_evp_noise_var);
				}
			}

			// check for valid orientation data
			if (PX4_ISFINITE(_ev_odom.q[0])) {
				ev_data.quat = matrix::Quatf(_ev_odom.q);

				// orientation measurement error from ev_data or parameters
				float param_eva_noise_var = sq(_param_ekf2_eva_noise.get());

				if (!_param_ekf2_ev_noise_md.get() && PX4_ISFINITE(_ev_odom.pose_covariance[_ev_odom.COVARIANCE_MATRIX_YAW_VARIANCE])) {
					ev_data.angVar = fmaxf(param_eva_noise_var, _ev_odom.pose_covariance[_ev_odom.COVARIANCE_MATRIX_YAW_VARIANCE]);

				} else {
					ev_data.angVar = param_eva_noise_var;
				}
			}

			// use timestamp from external computer, clocks are synchronized when using MAVROS
			ev_data.time_us = _ev_odom.timestamp_sample;
			_ekf.setExtVisionData(ev_data);

			ekf2_timestamps.visual_odometry_timestamp_rel = (int16_t)((int64_t)_ev_odom.timestamp / 100 -
					(int64_t)ekf2_timestamps.timestamp / 100);
		}

		bool vehicle_land_detected_updated = _vehicle_land_detected_sub.updated();

		if (vehicle_land_detected_updated) {
			if (_vehicle_land_detected_sub.copy(&_vehicle_land_detected)) {
				_ekf.set_in_air_status(!_vehicle_land_detected.landed);
			}
		}

最终使用函数_ekf.setExtVisionData(ev_data)将外部数据数据传入。

二、EKF2源码-设置外部视觉数据

位置:PX4-Autopolot/src/modules/ekf2/estimator_interface.cpp中大概在400行的位置

// set attitude and position data derived from an external vision system
void EstimatorInterface::setExtVisionData(const extVisionSample& evdata)
{
	if (!_initialised || _ev_buffer_fail) {
		return;
	}

	// Allocate the required buffer size if not previously done
	// Do not retry if allocation has failed previously
	if (_ext_vision_buffer.get_length() < _obs_buffer_length) {
		_ev_buffer_fail = !_ext_vision_buffer.allocate(_obs_buffer_length);

		if (_ev_buffer_fail) {
			printBufferAllocationFailed("vision");
			return;
		}
	}

	// limit data rate to prevent data being lost
	if ((evdata.time_us - _time_last_ext_vision) > _min_obs_interval_us) {
		_time_last_ext_vision = evdata.time_us;

		extVisionSample ev_sample_new = evdata;
		// calculate the system time-stamp for the mid point of the integration period
		ev_sample_new.time_us -= _params.ev_delay_ms * 1000;
		ev_sample_new.time_us -= FILTER_UPDATE_PERIOD_MS * 1000 / 2;

		_ext_vision_buffer.push(ev_sample_new);
	}
}

最后一行将数据压入_ext_vision_buffer中。

三、源码中对位置的发送

位置:PX4-Autopolot/src/modules/ekf2/ekf2_main.cpp中void Ekf2::Run()函数,大概在第1210行

		// run the EKF update and output
		perf_begin(_ekf_update_perf);
		const bool ekf_updated = _ekf.update();
		perf_end(_ekf_update_perf);

		// integrate time to monitor time slippage
		if (_start_time_us == 0) {
			_start_time_us = now;
			_last_time_slip_us = 0;

		} else if (_start_time_us > 0) {
			_integrated_time_us += imu_dt;
			_last_time_slip_us = (now - _start_time_us) - _integrated_time_us;
		}

		if (ekf_updated) {

			filter_control_status_u control_status;
			_ekf.get_control_mode(&control_status.value);

			// only publish position after successful alignment
			if (control_status.flags.tilt_align) {
				// generate vehicle local position data
				vehicle_local_position_s &lpos = _vehicle_local_position_pub.get();

				// generate vehicle odometry data
				vehicle_odometry_s odom{};

				lpos.timestamp = now;

				odom.timestamp = hrt_absolute_time();
				odom.timestamp_sample = now;

				odom.local_frame = vehicle_odometry_s::LOCAL_FRAME_NED;

				// Position of body origin in local NED frame
				Vector3f position = _ekf.getPosition();
				const float lpos_x_prev = lpos.x;
				const float lpos_y_prev = lpos.y;
				lpos.x = (_ekf.local_position_is_valid()) ? position(0) : 0.0f;
				lpos.y = (_ekf.local_position_is_valid()) ? position(1) : 0.0f;
				lpos.z = position(2);

				lpos.x = ev_data.pos(0);
				lpos.y = ev_data.pos(1);
				lpos.z = ev_data.pos(2);

				// Vehicle odometry position
				odom.x = lpos.x;
				odom.y = lpos.y;
				odom.z = lpos.z;

				// Velocity of body origin in local NED frame (m/s)
				const Vector3f velocity = _ekf.getVelocity();
				lpos.vx = velocity(0);
				lpos.vy = velocity(1);
				lpos.vz = velocity(2);

				// Vehicle odometry linear velocity
				odom.velocity_frame = vehicle_odometry_s::LOCAL_FRAME_FRD;
				odom.vx = lpos.vx;
				odom.vy = lpos.vy;
				odom.vz = lpos.vz;

				// vertical position time derivative (m/s)
				lpos.z_deriv = _ekf.getVerticalPositionDerivative();

				// Acceleration of body origin in local frame
				Vector3f vel_deriv = _ekf.getVelocityDerivative();
				lpos.ax = vel_deriv(0);
				lpos.ay = vel_deriv(1);
				lpos.az = vel_deriv(2);

下面三行代码是我自己添加的,目的就是直接使用外部视觉估计的位置

lpos.x = ev_data.pos(0);
lpos.y = ev_data.pos(1);
lpos.z = ev_data.pos(2);

四、测试

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

px4+vins+ego单机鲁棒飞行二-1(更改px4外部视觉估计固件) 的相关文章

  • 云服务器 搭建 AWTRIX 服务器

    Java 环境 首先检查 java 版本 如果没有 安装 openjdk 后再执行 sh脚本 yum list java 1 8 yum install java 1 8 0 openjdk y wget N https blueforce
  • esp8266对接天猫精灵(1)前言

    本系列文章小狂决定一步步来完成其他智能设备与天猫精灵的对接 xff0c 简单粗暴的目的就是使用ESP8266或者其他的wifi设备制造一个智能设备 xff0c 完成一次天猫精灵智能音箱对我们自己制造的智能设备的控制 xff0c 以来验证天猫
  • 牢记公式,ardupilot EKF2就是纸老虎(二)!

    版权声明 xff1a 本文为博主原创文章 xff0c 转载请附上博文链接 xff01 二 扩展卡尔曼滤波器 因为卡尔曼滤波器针对的是线性系统 xff0c 状态转移模型 xff08 说的白话一点就是知道上一时刻被估计量的值 xff0c 通过状
  • esp8266对接天猫精灵(3)原理

    这一篇文章主要讲解服务器端的设置 xff0c 这里我使用的是腾讯云 xff0c 当时学生价1块钱一个月买的 xff0c 现在的学生价涨到了10块 xff0c 为我当时的机智点赞 为什么一定要使用服务器呢 xff0c 这个是因为天猫精灵协议的
  • esp8266对接天猫精灵(8)开发者网关地址

    洋洋洒洒六七千字已经搭进去了 xff0c 终于把服务器篇写的差不多了 xff0c 当然小狂不是专业的写手 xff0c 有些东西写的凑合看吧 xff0c 只是说明过程 xff0c 并不修饰言辞 xff0c 看的舒服就点个赞 xff0c 不舒服
  • esp8266对接天猫精灵(10)nodumcu固件编译

    一 下载编译器 进入这个网站 xff0c https esp8266 ru esplorer xff0c 找到这个地方 xff0c 可以直接下载 xff0c 下载完成后双击红框中的内容就能打开 打开后的截图如下图所示 xff0c 左边为代码
  • esp8266对接天猫精灵(11)终端编程

    一 编写lua脚本获取控制信息 xff08 8266 xff09 前边也说过 xff0c 这个脚本要实现的步骤可以分三步 xff0c 第一步是联网 xff0c 第二步是使用http get到数据 xff0c 然后控制要控制的设备 我们的lu
  • Altium Designer -- 精心总结

    如需转载请注明出处 xff1a http blog csdn net qq 29350001 article details 52199356 以前是使用DXP2004来画图的 xff0c 后来转行 想来已经有一年半的时间没有画过了 突然转
  • Arduino点亮ws2812

    先加载ws2812库文件 span style color rgb 68 68 68 font family none font size 14px background color rgb 255 255 255 a target bla
  • Arduino 旋转编码器ky-040

    int pinA 61 3 Connected to CLK on KY 040 CLK接 pin3 int pinB 61 4 Connected to DT on KY 040 DT接pin4 SW是按键 xff0c 不用接 int e
  • Dockerfile

    Dockerfile文件 xff0c 自创镜像 一 概念 xff1a 二 案例 xff1a 1 先创建一个Dockerfile文件2 编写内容3 构建镜像4 运行 三 指令 xff1a FROM xff1a MAINTAINER xff1a
  • 关于嵌入式无人机之模型创建-使用3D打印装配体01

    做嵌入式的同学离不开硬件的支撑 那么无人机作为一套综合性工程 span class token punctuation span 涉及软件 span class token punctuation span 嵌入式 span class t
  • 牢记公式,ardupilot EKF2就是纸老虎(三)!

    版权声明 xff1a 本文为博主原创文章 xff0c 转载请附上博文链接 xff01 三 掀开EKF2的神秘面纱 EKF2是EKF算法在ardupilot上的代码实现 读到这里你也许已经忘了 xff0c EKF的5大公式 虽然下面是7个公式
  • ROS节点 报错process has died [pid 3322522, exit code -11

    偶尔出现 我的情况是两个节点 ros span class token double colon punctuation span span class token function init span span class token p
  • JS的冒泡函数

    今天下午学习了冒泡函数的加载和运行 一 var a 61 20 30 40 20 15 5 25 for var i 61 0 i lt a length i 43 43 for var j 61 1 j lt a length j 43
  • ubuntu server 版安装桌面

    安装xfce4 xff08 或其他桌面 xff09 amp xinit sudo apt install xfce4 xinit安装Display Manager 安装xdm xff0c 虽然有着古早的界面 xff0c 但是不会安装任何依赖
  • ubuntu下gazebo加载很慢解决办法

    ubuntu下gazebo加载很慢解决办法 前言 刚安装好 r o s ros r o s 后 xff0c 在终端输入命令 gazebo 启动 g
  • 从用户态是怎么切换到核心态的?

    此文章参考了 Linux 用户态通过中断切换到内核态详解 简答来说 xff0c 用户态和核心态的区别就是 xff1a 两者的操作权限不同 xff0c 用户态的进程能够访问的资源受到了极大的控制 xff0c 而运行在内核态的进程可以 为所欲为
  • 将rgbd数据集制作成rosbag,并发布图片和camera_info消息

    因为最近做的项目需要和别的开源项目做一些对比 xff0c 比如rgbdslamV2 xff0c 但是rdgbslamV2使用的输入是rosbag xff0c 并且他必须要订阅四个话题才能运行 xff0c 这四个话题分别是 xff1a cam
  • PX4添加自定义日志消息

    固件版本 xff11 11 一 将要观察的数据声明成uORB消息 xff0c 并发布 我这里随便添加了一个 在logged topics cpp里的add default topics函数里加上一行add topic fanbu 100 或

随机推荐