ROS小车搭建之编码器值得获取

好久没有更新博客了,这节主要给大家讲解一下ROS小车STM32F4控制器通过STM32定时器的编码器模式获取编码的值。

STM32F4定时器具有编码器功能的包括两个高级定时器1、8和四个通用定时器2、3、4、5。这节主要使用定时器5进行讲解。

假如对定时器5的编码器引脚对应不太明白的可以使用STM32CubeMx软件进行查看,如下图可以看到定时器5的编码器接口是在PA0和PA1上。

弄清楚引脚后开始编写代码,文章使用的是库函数版本进行配置,

timer.c

#include "timer.h"
/* total value since startup */
int32_t position;
/* last read of timer */
uint16_t last_timer;
/* last difference between timer reads */
int16_t last_timer_diff;
//arr:自动重装值(TIM2,TIM5是32位的!!) 0xffff
//psc:时钟预分频数                    0
//
void TIM5_CH1_Cap_Init(u32 arr,u16 psc)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
    TIM_ICInitTypeDef  TIM_ICInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);  	  //TIM5时钟使能    
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 	//使能PORTA时钟	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //GPIOA0
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA0

	GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5); //PA0复用位定时器5
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource1,GPIO_AF_TIM5); //PA0复用位定时器5
	  
	TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
	TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);
    TIM_EncoderInterfaceConfig(TIM5, 
    TIM_EncoderMode_TI12,TIM_ICPolarity_BothEdge,TIM_ICPolarity_BothEdge);
    TIM_ICStructInit(&TIM_ICInitStructure);
	TIM_ICInitStructure.TIM_ICFilter = 6; 
	TIM_ICInit(TIM5, &TIM_ICInitStructure);
	TIM_ClearFlag(TIM5, TIM_FLAG_Update); 
	TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE); 
	TIM_SetCounter(TIM5, 0);
	TIM_Cmd(TIM5, ENABLE); 	
}
int32_t read()
{
	uint16_t timer_value = TIM_GetCounter(TIM5);
	last_timer_diff = timer_value - last_timer;
	last_timer = timer_value;
	position += (int32_t) last_timer_diff;

	return position;
}

 

timer.h

#ifndef _TIMER_H
#define _TIMER_H
#include "sys.h"
void TIM5_CH1_Cap_Init(u32 arr,u16 psc);
int32_t read();
#endif

 

计数方向与编码器信号的关系如下图:

编码器的详细配置请参考STM32F4XX中文参考手册中的15.3.12通用定时器(TIM2到TIM5)编码器接口模式,看一下相关寄存器该怎么配置。获取编码器的值直接调用read()函数即可。

写在后面的话:目前正在把之前写好的底盘工程移植到FreeTROS中,因为跑裸机消息发送的频率不够,导致了上层里程计更新频率不够,建图出现较大误差的问题,后期也会和大家分享,希望大家多多关注我的博客。

### ROS小车自动驾驶中的应用 ROS(Robot Operating System)是一种灵活的软件框架,广泛应用于机器人开发领域。它提供了丰富的库和工具集,支持多种传感器数据处理、路径规划以及控制系统集成等功能。以下是关于如何利用ROS实现小车自动驾驶的一些具体方法和技术要点。 #### 1. **硬件选型** 选择适合的小车底盘硬件是项目的第一步。通常情况下,可以选择带有电机控制器、编码器反馈机制的轮式底盘结构[^2]。此外,还需要配备计算单元(如树莓派或NVIDIA Jetson系列),用于运行ROS环境及相关算法。 #### 2. **软件环境搭建** 安装Linux操作系统(推荐Ubuntu版本)之后,在其上部署最新稳定版的ROS发行包。创个人工作区目录,并初始化catkin编译系统以便管理自定义代码模块[^1]。 ```bash sudo apt update && sudo apt upgrade -y wget https://raw.githubusercontent.com/ros-noetic/noetic_install.sh && chmod +x noetic_install.sh && ./noetic_install.sh source /opt/ros/noetic/setup.bash mkdir -p ~/catkin_ws/src && cd ~/catkin_ws/ && catkin_make echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc ``` #### 3. **感知层设计** 为了使小车具备自主导航能力,需引入各类传感设备获取外界信息。例如使用激光扫描仪SLAM;摄像头配合计算机视觉识别障碍物或者标志线等特征点[^3]。 - 配置Lidar驱动插件读取距离测量。 - 利用OpenCV库分析像帧提取语义理解线索。 #### 4. **决策与控制逻辑制定** 基于收集到的数据源,执行相应的判断操作决定下一步行动方向。这一步涉及高级别的行为模式设定比如避障策略调整速度矢量输出给底层执行机构完成实际位移动作转换过程[^4]。 - 编写Python/C++节点订阅主题消息流解析意指令。 - 发布命令至actuator接口改变物理状态响应外部刺激变化情况。 #### 5. **测试验证阶段** 完成后端编程部分后即可进入调试环节确认整体流程运转正常无误。启动模拟器观察虚拟场景下表现效果评估性能指标满足预期目标后再迁移到真实世界环境中进一步优化完善细节之处直至达到理想水平为止。 --- ### 示例代码片段展示 下面给出一段简单的ROS节点示例用来演示基本概念: ```python #!/usr/bin/env python import rospy from geometry_msgs.msg import Twist def move(): velocity_publisher = rospy.Publisher('/cmd_vel', Twist, queue_size=10) vel_msg = Twist() # 设置前进速率 speed = input("Input your speed:") distance = input("Type your distance:") isForward = input("Foward?: ")==True if(isForward): vel_msg.linear.x = abs(speed) else: vel_msg.linear.x = -abs(speed) t0 = float(rospy.Time.now().to_sec()) current_distance = 0 while(current_distance < distance): velocity_publisher.publish(vel_msg) t1=float(rospy.Time.now().to_sec()) current_distance= speed*(t1-t0) if __name__ == '__main__': try: rospy.init_node('robot_cleaner', anonymous=True) move() except rospy.ROSInterruptException: pass ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值