基于openmv的无人机Apriltag动态追踪降落完整项目资料(labview+openmv+apriltag+正点原子四轴)

前言:

之前假期做的一个小项目,炸了好几套桨叶233,分享出来希望能帮助更多人快速学习。
使用正点原子ATK-MiniFly 飞行器二次开发多旋翼Apriltag追踪;
使用LABVIEW自主设计地面站用于发送控制指令与信息接收;
飞行器: STM32F4+FreeRTOS;
遥控器: STM32F1+FreeRTOS;
OPENMV: STM32H7
用户可将OPENMV更换成高级视觉opencv、yolo等,只需根据已有接口设计协议即可快速二次开发其他功能。
本项目适用于STM32(涉及F1、F4、H7)以及FreeRTOS操作系统初学者以及对多旋翼飞行控制系统导航与控制开发感兴趣的人员,需一定编程能力,本项目已完完结,以下功能均已实现,欢迎评论区交流。

功能说明:

1.labview自主设计地面站(安装依赖包后可独立运行不依赖labview),地面站端包含一键起飞、一键急停、一键降落、一键追踪tag码按钮,以及相关信息的显示界面;
2. 使用openmv官方例程Apriltag识别tag标签与位姿信息,在图像中框出tag标签,并通过串口上传至四轴飞行器;
3. 遥控器与地面站之间采用USB/数传连接,飞行器与OPENMV采用串口连接;
4. 遥控器端可反应相关状态信息,一键接管自主控制状态,保证安全飞行;

材料说明:
1.ATK-MiniFly
2. OPENMV4
3. Apriltag (tag16h5)

地面站协议说明: (具体可反推飞控代码)
1.一键起飞、降落:0xaa 0x11 (地面状态则起飞,空中状态则降落)
2. 一键急停: 0xaa 0x22 (直接锁桨,注意安全)
3. 一键追踪tag码:0xaa 0x33(起飞完成后再点击,否则openmv视野不足)

地面站ui界面:
在这里插入图片描述
飞行器相关资料:(官方资料自行搜索下载)
在这里插入图片描述

OPENMV引导飞行器核心代码:

bool opv_control_state=0;
float opv_x_data=0,opv_y_data=0; //北西天坐标系  前x正  左y正 上z正
void opv_Communication_Task(void *param)
{
	while(1)
	{
		if(opv_control_state==1)
		{
			if(SDK_tag.Tx<0)opv_y_data=-5;
			else if(SDK_tag.Tx>0)opv_y_data=5;
			else opv_y_data=0;
			
			if(SDK_tag.Ty<0)opv_x_data=-5;
			else if(SDK_tag.Ty>0)opv_x_data=5;
			else opv_x_data=0;
		}
		else
		{
			opv_x_data=0;
			opv_y_data=0;
		}
		
		ledSet(LED_BLUE_L,opv_control_state);	//飞机左后小灯判断opv控制状态,亮(1)允许追踪tag
		vTaskDelay(200);
	}
}

飞行器位置输出核心代码:

	if(getOpDataState() && commander.ctrlMode == 0x03)	/*光流数据可用,定点模式*/ 
	{
		setpoint->attitude.yaw *= 0.5f;	/*定点模式减慢yaw调节*/
		
		/*调整位置 速度模式*/
		if(fabsf(setpoint->attitude.roll) > 1.5f || fabsf(setpoint->attitude.pitch) > 1.5f || opv_control_state == 1)
		{
			adjustPosXYTime = 0;
			isAdjustingPosXY = true;
			setpoint->mode.x = modeVelocity;
			setpoint->mode.y = modeVelocity;
			setpoint->velocity.x = setpoint->attitude.pitch * 4.0f + opv_x_data;//倾角大于1.5°时执行
			setpoint->velocity.y = setpoint->attitude.roll * 4.0f + opv_y_data;	
		}
		else if(isAdjustingPosXY == true)
		{
			if(adjustPosXYTime++ > 100)
			{
				adjustPosXYTime = 0;
				isAdjustingPosXY = false;
			}		
			setpoint->mode.x = modeAbs;
			setpoint->mode.y = modeAbs;
			setpoint->position.x = state->position.x + errorPosX;	//调整新位置 
			setpoint->position.y = state->position.y + errorPosY;	//调整新位置			
		}
		else if(isAdjustingPosXY == false)	/*位移误差*/
		{	
			errorPosX = setpoint->position.x - state->position.x ;//动摇杆后执行此处
			errorPosY = setpoint->position.y - state->position.y ;	
			errorPosX = constrainf(errorPosX, -30.0f, 30.0f);	/*误差限幅 单位cm*/
			errorPosY = constrainf(errorPosY, -30.0f, 30.0f);	/*误差限幅 单位cm*/
		}
	}
	else	/*手动模式*/
	{
		setpoint->mode.x = modeDisable;
		setpoint->mode.y = modeDisable;		
	}

一键起飞、降落、急停、追踪等指令核心代码:

		if(drone_control_state==0x11)//pc端一键起飞、一键降落
		{
			if( getRCLock()==false && getIsMFCanFly()==true &&
				(configParam.flight.ctrl == ALTHOLD_MODE || configParam.flight.ctrl == THREEHOLD_MODE)
			  )
			{
				sendRmotorCmd(CMD_FLIGHT_LAND, NULL);
			}
			drone_control_state=0;			
		}
		else if(drone_control_state==0x22)//pc端一键急停
		{
			sendRmotorCmd(CMD_EMER_STOP, NULL);
			drone_control_state=0;			
		}
		else if(drone_control_state==0x33)//pc端一键追踪tag码
		{
			sendRmotorCmd(CMD_TAG_TRACK, NULL);
			LED_RED  = !LED_RED;
			drone_control_state=0;			
		}
		else drone_control_state=0;	

部分飞行器信息发送至LABVIEW核心代码:

/***************************************************************************************************************************/		
	    printf("A");				//0
/***************************************************************************************************************************/		
		drone_pit=limit(plane_pitch*10,-999,999);//将flyControl.pitch*100替换为plane_pitch*10即可上传飞机姿态信息
		if(drone_pit>0)printf("+");
		else 
		{
			printf("-");			//1
			drone_pit=-drone_pit;
		}
		send_bai=drone_pit/100;
		send_shi=drone_pit%100/10;
		send_ge=drone_pit%100%10;		
	    printf("%d",send_bai);		//2
		printf("%d",send_shi);		//3
		printf("%d",send_ge);		//4
/***************************************************************************************************************************/
		drone_rol=limit(plane_roll*10,-999,999);		
		if(drone_rol>0)printf("+");
		else
		{
			printf("-");			//5
			drone_rol=-drone_rol;
		}			
		send_bai=drone_rol/100;
		send_shi=drone_rol%100/10;
		send_ge=drone_rol%100%10;	
	    printf("%d",send_bai);		//6
		printf("%d",send_shi);		//7
		printf("%d",send_ge);		//8
/***************************************************************************************************************************/
		drone_yaw=limit(plane_yaw*10,-1800,1800);		
		if(drone_yaw>0)printf("+");
		else
		{
			printf("-");			//9
			drone_yaw=-drone_yaw;
		}
		send_qian=drone_yaw/1000;
		send_bai=drone_yaw%1000/100;
		send_shi=drone_yaw%1000%100/10;
		send_ge=drone_yaw%1000%100%10;	
		printf("%d",send_qian);		//10
	    printf("%d",send_bai);		//11
		printf("%d",send_shi);		//12
		printf("%d",send_ge);		//13
/***************************************************************************************************************************/		

全部资料链接见评论区,有问题请留言或评论区讨论。
作者:锦官城外
时间:2021.11
祝好!
资料下载链接

  • 9
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

amusen.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值