px4Flow程序main.c解读

10 篇文章 3 订阅

程序下载https://github.com/PX4/Flow

主程序在Flow/src/modules/flow/main.c

进入主程序int main(void)

 

首先__enable_irq();启用IRQ中断,此函数通过清除程序状态寄存器中的I位来启用中断请求。只能在特权模式下执行

然后是初始化以及加载一些参数

global_data_reset_param_defaults();
	global_data_reset();
	...              
        board_led_rgb(  0,  0,255, 4);
	/*使能FPU浮点运算*/
	SCB_CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); 
        //设置CP10完全访问和设置CP11完全访问	
	if (SysTick_Config(SystemCoreClock / 100000))
	/*将定时器设置为每10微秒触发一次中断*/
	{
		/* capture clock error 捕获时钟错误*/
		LEDOn(LED_ERR);
		while (1);
	}

	/* 初始化 */
	USBD_Init(	&USB_OTG_dev,
				USB_OTG_FS_CORE_ID,
				...
				&USR_cb);

	/*初始化MAVLink*/
    	communication_init();	
	enable_image_capture();//启用图像捕获
	/*  配置陀螺仪*/
	gyro_config();
	/*初始化和清除快速图像缓冲区 */
	for (int i = 0; i < global_data.param[PARAM_IMAGE_WIDTH] * global_data.param[PARAM_IMAGE_HEIGHT]; i++)
	{
		...
	}

	...初始化其他配置

 

while (1)从这里进入程序主循环,会去调用其他函数

PROBE_1(false);

uavcan_run();//UAVCAN是一种轻量级协议,还不知道这里做了什么

PROBE_1(true);

probe应该是驱动吧,个人猜测这里是发布或者接受了消息

然后判断buffer_reset_needed= =1   必要时重置光流缓冲器

if(buffer_reset_needed)
        {
            buffer_reset_needed = 0;
            for (int i = 0; i < global_data.param[PARAM_IMAGE_WIDTH] * global_data.param[PARAM_IMAGE_HEIGHT]; i++)
            {
                image_buffer_8bit_1[i] = 0;
                image_buffer_8bit_2[i] = 0;
            }
            delay(500);
            continue;
        }

查代码发现是在communication.c 中handle_mavlink_message()有四种情况会重置光流缓存器

1. i == PARAM_SENSOR_POSITION)//当手动控制位置

2. i == PARAM_IMAGE_LOW_LIGHT || i == PARAM_IMAGE_ROW_NOISE_CORR|| i == PARAM_IMAGE_TEST_PATTERN)

//处理低光模式和噪声校正

3. i == PARAM_VIDEO_ONLY//手工校准

4 i == PARAM_SHTR_W_1 || i == PARAM_SHTR_W_2 || i == PARAM_SHTR_W_TOT ||    i == PARAM_EXPOSURE_MAX ||   i == PARAM_HDR ||   i == PARAM_AEC ||  i == PARAM_AGC ||     i == PARAM_BRIGHT ||   i == PARAM_GAIN_MAX

//快门/曝光参数到这些值时

 

接下来是校准,直到灯闪成功

if(FLOAT_AS_BOOL(global_data.param[PARAM_VIDEO_ONLY]))
		{
			while(FLOAT_AS_BOOL(global_data.param[PARAM_VIDEO_ONLY]))
			{
				dcmi_restart_calibration_routine();//校准图像采集程序重启

				...
				communication_parameter_send();//发送一条低优先级参数消息
				LEDToggle(LED_COM);//切换所选LED。
			}
			dcmi_restart_calibration_routine();//校准图像采集程序重启
			LEDOff(LED_COM);
		}

从参数PARAM_IMAGE_WIDTH和PARAM_IMAGE_HEIGHT设定图像大小 image_size

 然后读取当前的陀螺仪数据gyro_read(&x_rate_sensor, &y_rate_sensor, &z_rate_sensor,&gyro_temp);

在进行转换

计算焦距

 focal_length_px = (global_data.param[PARAM_FOCAL_LENGTH_MM]) / (4.0f * 6.0f) * 1000.0f;

//原始焦距:12毫米像素大小:6毫米,已启用4像素合并

获取声纳数据distance_validsonar_read(&sonar_distance_filtered, &sonar_distance_raw)当测量距离大于阈值时置零

当位置到最底了,计算光流if (FLOAT_EQ_INT(global_data.param[PARAM_SENSOR_POSITION], BOTTOM))

     将最近的图像复制到更快的RAM    dma_copy_image_buffers

 计算光流 qual = compute_flow(previous_image, current_image, x_rate, y_rate, z_rate, &pixel_flow_x, &pixel_flow_y);

compute_flow函数在flow.c文件中其作用是 计算从Image1到Image2的像素流

*从旧图像(image1)中搜索新图像(image2)中最多64个像素的相应位置,并计算所有偏移的平均值。其算法就是整个程序的核心了,可以参考这篇文章https://blog.csdn.net/qq_42237381/article/details/88821175

接下来就是超声波结合得到最终地面的速度

            float flow_compx = pixel_flow_x / focal_length_px / (get_time_between_images() / 1000000.0f);

            float flow_compy = pixel_flow_y / focal_length_px / (get_time_between_images() / 1000000.0f);

实点P(X,Y,Z),图像平面投影P(X,Y,Z),焦距F,到场景Z的距离x / f = X / Z

 

 

 

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
mini四轴飞行器除了在室外各种超炫动作,但在室内若想不碰壁,就要求mini四轴飞行器具有悬停功能,四轴要有定高功能?小四轴不像大四轴有完善的GPS模块,而且小四轴的重量也很难加装GPS。这个时候选择智能光学流动传感器PX4Flow就是比较好的方案了。 PX4Flow是一款智能光学流动传感器。传感器拥有原生 752×480 像素分辨率,计算光学流的过程中采用了4倍分级和剪裁算法,计算速度达到250Hz(白天,室外),具备非常高的感光度。与其他滑鼠传感器不同,它可以以120Hz(黑暗,室内)的计算速度在室内或者室外暗光环境下工作,而无需照明LED。你也可以对它重新编程,用于执行其他基础的,高效率的低等级机器视觉任务。 PX4Flow主要特征: MT9V034机器视觉CMOS传感器,全局快门 4×4分级图像算法,光流运算速度从120Hz(室内)至250Hz(室外) 高感光度,24×24 μm高像素 板载16位精度陀螺,最大感应角速率2000°/s,最大数据更新速度780 Hz,默认使用高精度模式时最大角速率500°/s 板载输入输出一体化超声波传感器 USB bootloader USB数据波特率最高921600(包含地面站软件QGroundControl所使用的摄像机实时视角) USB供电模式 电路板开孔适合MatrixVision Bluefox MV(摄像机中心作为基准) 电路城语:此资料为卖家免费分享,不提供技术支持,请大家使用前验证资料的正确性!如涉及版权问题,请联系管理员删除! 附件包含以下资料:
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值