【学习笔记--简单避障和里程计】

本文介绍了一种基于里程计的机器人避障算法,利用陀螺仪和编码器进行位置估计,结合红外激光测距实现精准避障。算法分为五个阶段:启动、到达障碍、越过障碍、角度修正及结束,确保机器人高效安全地绕过障碍。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习笔记--简单避障和里程计题


学习学长当年写的程序,好好积累,反复思考当时怎么自己没想到

里程计

通过陀螺仪和编码器来进行简单的位置估计。即通过编码器获得速度,将速度分解为X、Y方向,再进行积分,从而获得粗略的位置估计。

避障

避障分为5个阶段,当时采用了红外激光测距,当距离小于40cm时触发中断,进入避障控制程序。

typedef enum{
	BLOCK_AVOID_START=1,//开始避障
	BLOCK_AVOID_ARRIVE=2,//达到障碍位置,与障碍平行
	BLOCK_AVOID_PASS=3,//超过障碍
	BLOCK_AVOID_THETA_REPAIR=4,//回到赛道上之后,修正回角度
	BLOCK_AVOID_END=0//避障结束
}e_ba_procedure_t;

库文件(h)

#ifndef BLOCK_AVOID_H__
#define BLOCK_AVOID_H__


typedef enum{
	BLOCK_AVOID_START=1,//开始避障
	BLOCK_AVOID_ARRIVE=2,//达到障碍位置,与障碍平行
	BLOCK_AVOID_PASS=3,//超过障碍
	BLOCK_AVOID_THETA_REPAIR=4,//回到赛道上之后,修正回角度
	BLOCK_AVOID_END=0//避障结束
}e_ba_procedure_t;


typedef struct{
	float x;
	float y;
}s_ba_point_t;



typedef struct{
	s_ba_point_t car_position;
	s_ba_point_t position_want;
	
	e_ba_procedure_t step;
	
	float speed_x;//分解到x方向的速度
	float speed_y;//分解到y方向的速度
	float speed_line;//线速度
	
	float theta;//0是x轴方向  逆时针转角度加大
	
}s_block_avoid_data_t;


typedef struct{
	//输入参数
	float distance;//距离障碍的距离  米
	float speed_m_s;//速度 米每秒
	float rotation_th;//角速度 度每秒
	
	//输出参数
	float turn_want;//返回给控制器的转向期望
	uint8_t exit;//避障结束之后这个值置1
}s_ba_interface_t;


extern s_ba_interface_t s_ba_interface;

void block_avoid_handler_dt();
#endif

源文件(C)

#include "include.h"
const static float dt=0.005;
#define OBSTACLE_THICKNESS      (0.42) //障碍物厚度 (用于第二阶段向前这么多距离)
#define OBSTACLE_LENGTH		 	(0.4)//障碍物宽度
#define INFLATION_X				(0.2)//横向膨胀长度,这个值越大距离障碍就会越远

#define RADIUS_REPAIR           (0.04) //转向半径修正,让在跟障碍平行时与赛道平行前进

#define BACK_DISTANCE		 	 (0.3)//越过障碍之后返回赛道时向前走这么多米,这个值越大返回越平缓
#define BACK_X					 (0.1)//返回到赛道中心点向右这么多距离,之后修正角度

#define BACK_THETA				 (90+0)//修正到这个角度之后返回正常控制,90°是正前方,0°是正右方

static s_block_avoid_data_t s_block_avoid_data;
s_ba_interface_t s_ba_interface;

static void block_avoid_data_update(s_block_avoid_data_t *ps_ba_dat){
	ps_ba_dat->speed_line=s_ba_interface.speed_m_s;//速度
	ps_ba_dat->theta+=s_ba_interface.rotation_th*dt;//度数
        
        while(ps_ba_dat->theta>180) ps_ba_dat->theta-=360;
        while(ps_ba_dat->theta<-180) ps_ba_dat->theta+=360;
	
	//分解速度
	ps_ba_dat->speed_x=ps_ba_dat->speed_line*cosf(ps_ba_dat->theta*AtoR);
	ps_ba_dat->speed_y=ps_ba_dat->speed_line*sinf(ps_ba_dat->theta*AtoR);
	
	//位置估计
	ps_ba_dat->car_position.x+=ps_ba_dat->speed_x*dt;
	ps_ba_dat->car_position.y+=ps_ba_dat->speed_y*dt;
}

void block_avoid_handler_dt(){//避障服务函数
	(void)(dt);//avoid warning
	if(s_block_avoid_data.step==BLOCK_AVOID_END){//进入避障
		s_block_avoid_data.step=BLOCK_AVOID_START;
		s_block_avoid_data.theta=90.0f;
		s_block_avoid_data.car_position.x=s_block_avoid_data.car_position.y=0;//位置初始化
		s_block_avoid_data.position_want.x=-(OBSTACLE_LENGTH/2+INFLATION_X);//dubug//期望位置
		s_block_avoid_data.position_want.y=s_ba_interface.distance;
		s_block_avoid_data.step=BLOCK_AVOID_START;
	}else if(s_block_avoid_data.step==BLOCK_AVOID_START){
		block_avoid_data_update(&s_block_avoid_data);//更新数据
		s_ba_interface.turn_want=RtoA*atan2(s_block_avoid_data.position_want.y-s_block_avoid_data.car_position.y,
                                                    s_block_avoid_data.position_want.x-s_block_avoid_data.car_position.x)-s_block_avoid_data.theta;//转向期望角度返回
                while(s_ba_interface.turn_want>180) s_ba_interface.turn_want-=360;
                while(s_ba_interface.turn_want<-180) s_ba_interface.turn_want+=360;
                
		//判断是否达到障碍
		if(s_block_avoid_data.car_position.y>s_block_avoid_data.position_want.y&&s_block_avoid_data.car_position.x<s_block_avoid_data.position_want.x){//debug
			s_block_avoid_data.position_want.y=s_block_avoid_data.car_position.y+OBSTACLE_THICKNESS;
			s_block_avoid_data.position_want.x=s_block_avoid_data.car_position.x-RADIUS_REPAIR;//debug
			s_block_avoid_data.step=BLOCK_AVOID_ARRIVE;
		}
	}
	else if(s_block_avoid_data.step==BLOCK_AVOID_ARRIVE){//已经与障碍平行,再向前障碍厚度
		block_avoid_data_update(&s_block_avoid_data);//更新数据
		s_ba_interface.turn_want=RtoA*atan2(s_block_avoid_data.position_want.y-s_block_avoid_data.car_position.y,
                                                    s_block_avoid_data.position_want.x-s_block_avoid_data.car_position.x)-s_block_avoid_data.theta;//转向期望角度返回
                
                while(s_ba_interface.turn_want>180) s_ba_interface.turn_want-=360;
                while(s_ba_interface.turn_want<-180) s_ba_interface.turn_want+=360;
		
		//判断是否越过障碍厚度
		if(s_block_avoid_data.car_position.y>s_block_avoid_data.position_want.y){
			s_block_avoid_data.position_want.y=s_block_avoid_data.car_position.y+BACK_DISTANCE;
			s_block_avoid_data.position_want.x=-BACK_X;//dubug
			s_block_avoid_data.step=BLOCK_AVOID_PASS;
		}
	}
	else if(s_block_avoid_data.step==BLOCK_AVOID_PASS){
		block_avoid_data_update(&s_block_avoid_data);//更新数据
		s_ba_interface.turn_want=RtoA*atan2(s_block_avoid_data.position_want.y-s_block_avoid_data.car_position.y,
                                                    s_block_avoid_data.position_want.x-s_block_avoid_data.car_position.x)-s_block_avoid_data.theta;//转向期望角度返回
                
                while(s_ba_interface.turn_want>180) s_ba_interface.turn_want-=360;
                while(s_ba_interface.turn_want<-180) s_ba_interface.turn_want+=360;
		
		//判断是否返回赛道
		if(s_block_avoid_data.car_position.x>s_block_avoid_data.position_want.x){//debug
			s_block_avoid_data.step=BLOCK_AVOID_THETA_REPAIR;//下一步修正角度
		}
	}
	else if(s_block_avoid_data.step==BLOCK_AVOID_THETA_REPAIR){
		block_avoid_data_update(&s_block_avoid_data);//更新数据
		s_ba_interface.turn_want=BACK_THETA-s_block_avoid_data.theta;
                while(s_ba_interface.turn_want>180) s_ba_interface.turn_want-=360;
                while(s_ba_interface.turn_want<-180) s_ba_interface.turn_want+=360;
		if(fabsf(s_block_avoid_data.theta-BACK_THETA)<3){//近似达到角度
			s_block_avoid_data.step=BLOCK_AVOID_END;
                        s_ba_interface.exit=1;
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值