从零开始做一辆简易麦克纳姆轮小车

news2024/11/24 5:54:33

一、前期准备

麦克纳姆轮小车(Mecanum wheel robot)是一种能够实现全向移动的机器人,其核心在于使用了特殊设计的麦克纳姆轮。要从头开始制作一辆麦克纳姆轮小车,你可能需要准备以下组件和工具:

1. 材料和部件
麦克纳姆轮:选择合适尺寸和承载能力的麦克纳姆轮。这些轮子通常由橡胶或塑料制成,并带有自由旋转的滚轮。可以在专业的机器人配件商店或在线市场购买。
电机:根据设计需求选择步进电机或伺服电机。电机的扭矩和转速应与麦克纳姆轮的规格相匹配。例如,对于小型机器人,可以使用NEMA17步进电机。
电机控制器:如果使用步进电机,则需要相应的驱动器,如A4988模块;若使用伺服电机,则需ESC电子调速器。确保控制器可以处理所需的电流和电压。
电池:依据电机和控制板的电源要求,选择合适的锂电池或镍氢电池。容量需要足够以支持预期的操作时间。
微控制器:Arduino UNO、Nano或Raspberry Pi等开发板是常见选择。它们用于接收传感器数据和控制电机。
结构框架:可使用木板、亚克力板或3D打印部件来构建车体。设计时要考虑强度和重量。
传感器:超声波传感器用于避障,编码器可用于轮速反馈,提高运动精度。
其他电子元件:包括电线、插座、电阻、LED指示灯等。
2. 工具
螺丝刀:一套交叉和一字螺丝刀,适用于不同大小的螺丝。
烙铁和焊锡:用于电子元件的焊接工作,确保连接牢固可靠。
剥线钳和剪刀:用于准备电线和切割材料。
尺子和标记笔:测量和标记材料以便准确切割。
锯子或激光切割机:根据所选材料类型进行切割。
3D打印机:如果有3D设计文件,可以直接打印复杂的零件。
螺丝和螺母套装:用于组装结构的各种尺寸螺丝和螺母。
3. 软件
编程环境:Arduino IDE用于编写和上传代码到Arduino板;PyCharm或Thonny用于Raspberry Pi的Python编程;Keil5 和 Cubemx 用于单片机编程。
CAD软件:如AutoCAD或SolidWorks,用于设计和修改车辆的结构部件。
固件库:如Arduino的Stepper或Servo库,简化电机控制代码的编写。
4. 组装步骤
设计框架:在CAD软件中设计车体框架,考虑到所有部件的布局。
打印/制造部件:使用3D打印机打印非标准部件,或者按照设计切割木板或亚克力板。
安装电机:将电机固定到框架上,并确保麦克纳姆轮能自由旋转不受阻碍。
连接电子部件:按照电路图连接电机控制器、电池、微控制器和传感器。
上传代码:编写控制代码并在微控制器上运行测试。
调试:检查所有运动是否符合预期,调整代码以优化性能。
image
在这里我使用的芯片型号是STM32F103C8T6,编程环境为 Keil5 、Cubemx,电机驱动模块为TB6612,蓝牙模块为HC-05或者HC-08,地板轮子和电机在网上购买即可。
电机驱动基础知识具体可看我之前写的文章:https://blog.csdn.net/m0_74712453/article/details/140008931?spm=1001.2014.3001.5501

二、麦克纳姆轮工作原理

麦克纳姆轮的核心原理是轮子上小滚子的独特布局和角度,它们能够将轮毂传来的力分解为水平和垂直于滚子轴线的两个分力。通过适当地控制四个麦克纳姆轮的相对速度和方向,可以实现车辆在不改变车体方向的前提下向任意方向移动。例如,当所有轮子向前旋转时,如果相邻轮子的旋转方向相反,车辆将侧向滑动;而如果是对角线上的轮子旋转方向相同,则可以实现原地旋转。
前面提到麦轮分A,B两种,如果A轮向前运动时同时向右运动,即斜向右前方运动,那么相反,A轮向后运动的同时会向左运动,即斜向左后方运动;相应B轮就可以斜向左前和右后方运动。
例:以小车车头为正方向,约定轮子前进时的方向为电机正转,轮子后退时的方向为电机反转。
image
拿A轮来说,辊子移动方向上由于滚动从而无法提供前进的力,而在辊子轴线方向上辊子无法滚动并且与地面摩擦产生辊子轴向上的摩擦力,即斜向右前或左后方向,从而A轮的速度方向是斜向右前或左后;同理可分析B轮。
image
根据我们高中学到的物理知识,我们知道速度是可以正交分解的,决定车体运动取决于四个麦轮的合速度方向。
那么A轮就可以分解成轴向向右和垂直轴向向前的速度分量,或者说轴向向左和垂直轴向向后的速度分量。
image
这样,B轮的速度分量和A轮互为镜像关系了。
image

三、麦克纳拉姆轮安装组合及运动分析

1.麦克纳姆轮正确安装组合

从上面我们可以知道麦克纳姆轮主要分为A,B轮,知道对应轮子的速度分量后我们就可以对四轮的麦克纳姆轮底盘进行排列组合,例如:AABB,AAAA,BBBB等,但是通过速度分量分析我们可以得知并不是每一种组合都可以实现全方向移动,在这里我列出麦克纳姆轮一种错误的安装组合,其余可以自行推理,例如错误例子AAAA型:左图为俯视图,右图为麦轮与地面接触的部分,投影到地面的情况!
image
由图我们可以得知:当四个轮子同时向前转动的时候,每个轮子都会有一个向左的速度分量,这样就会导致整个底盘前进的时候必然会同时向左运动;同理,后退的时候必然会向右运动,这样就没办法使用了,这个东西不受控制到处乱跑,这不是我们想要的全向移动。
image
所以我们可以通过组装正确方式,来确保四个轮子同时向前或者向后转动时,实现整个底盘前进或者后退,不发生其他偏移。
如下图所示,一种正确的安装组合:
image
当四个轮子都向前转的时候,AB轮可以相互抵消轴向速度,只剩下向前的速度,这样底盘就是向前直行、不会跑偏,后退也是一样的;
image
如果当A轮正转、B轮反转的时候,向前向后的速度会抵消,仅剩下向右的速度,那么底盘就会向右平移;相反,如果A轮反转,B轮正转,就会向左平移;其他方向都可以自行推理,我在上一篇已经列出常见麦轮组合运动方向。
image
image

2.麦克纳姆轮常见运动方式

根据上面的原理,我们可以推理得出麦克纳姆轮常见的运动方式。

1.对角线方向

对角线方向02
对角线方向

2.前进和后退

前进、后退

3.左移和右移

左移。右移

4.绕正前方左右摆尾

绕正前方,左,右摆尾

5.绕正后方左右摆尾

绕正后端,左,右摆尾

6.绕左右上角转动

绕左右上角转动

7.绕左右下角转动

绕左、右下角转动

四、软件程序代码编写

在这里我们先实现蓝牙控制小车可以前进后退左右移动,具体涉及编码器和pid的知识后面我有时间再单独写一篇总结一下。

1.接线

电机驱动模块与单片机对应引脚接线:

  • AIN1,AIN2 对应 PB2,PB10 左上轮
  • BIN1,BIN2 对应 PB1,PB0 左下轮
  • DIN1,DIN2 对应 PB5,PB6 右上轮
  • CIN1,CIN2 对应 PB8, PB7 右下轮

HC-08蓝牙模块与单片机接线:

  • 蓝牙模块TX接RX(PA10),RX接TX(PA9),VCC接5V,GND接GND

2.Cubemx配置

SYS:Debug设置成Serial Wire
image
RCC:配置外部高速晶振
image
配置时钟树:
image
配置八个GPIO口为输出模式:
image
配置UART:设置波特率为9600,因为蓝牙模块默认波特率为9600,开启NVIC中断接收信息。
image
image
配置完后最后点击 generate code 生成代码。

3.代码示例

(1)实现前进和后退

前进、后退

//前进
void goForward(void)
{
	// 左轮前进 左上轮 PB2,PB10 左下轮 PB1,PB0
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
	
	// 右轮前进 右上轮 PB5,PB6 右下轮PB8 , PB7    
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
}

//后退
void goBack(void)
{
	// 左轮后退 左上轮 PB2,PB10 左下轮 PB1,PB0
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
	
	// 右轮后退 右上轮 PB5,PB6 右下轮PB8 , PB7
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
}

(2)实现左移和右移

左移。右移

//左移
void goLeft(void)
{
	// 左上轮后退 左上轮 PB2,PB10 左下轮前进 左下轮 PB1,PB0
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);

	
	// 右上轮前进 右上轮 PB5,PB6  右下轮后退 右下轮 PB8,PB7
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
}

//右移
void goRight(void)
{
	// 左上轮前进 左上轮 PB2,PB10 左下轮后退 左下轮 PB1,PB0
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
	
	// 右上轮后退 右上轮 PB5,PB6  右下轮前进 右下轮 PB8,PB7
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
}

###(3)蓝牙接收信息
可以使用HC-05(下图蓝色)或者HC-08(下图绿色),这两种我都测试通过。
image
使用串口中断测试收发的数据,串口重映射设置:
image
重映射代码:

int fputc(int ch, FILE *f)
{      
	unsigned char temp[1]={ch};
	HAL_UART_Transmit(&huart1,temp,1,0xffff);  
	return ch;
}

中断接收信息代码:

// 串口接收缓存
uint8_t buf=0;

// 定义最大接收字节数
#define UART1_REC_LEN 200

// 接收缓冲,串口接收到的数据存放在这个数组里,最大UART1_REC_LEN个字节
uint8_t UART1_RX_Buffer[UART1_REC_LEN];

//  接收状态
//  bit15,     接收完成标志
//  bit14,     接收到0x0d
//  bit13~0,   接收到的有效字节数目
uint16_t UART1_RX_STA=0;

#define SIZE 12

char buffer[SIZE];

// 接收完成回调函数,收到数据后在这里处理
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	// 判断中断是有哪个串口触发的
	if(huart->Instance == USART1)
	{
		// 判断接收是否完成(UART1_RX_STA bit15 位是否为1)
		if((UART1_RX_STA & 0x8000) == 0)
		{
			// 如果已经收到了 0x0d (回车)
			if(UART1_RX_STA & 0x4000)
			{
				// 则接着判断是否收到 0x0a (换行)
				if(buf == 0x0a)
				{
					// 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1
					UART1_RX_STA |= 0x8000;

					// 控制小车运动方向指令
					if(!strcmp(UART1_RX_Buffer, "M1"))
					{
						goForward();
						printf("goForward success\r\n");
					}
					else if(!strcmp(UART1_RX_Buffer, "M2"))
					{
						goBack();
						printf("goBack success\r\n");
					}
					else if(!strcmp(UART1_RX_Buffer, "M3"))
					{
						goLeft();
						printf("goLeft success\r\n");
					}
					else if(!strcmp(UART1_RX_Buffer, "M4"))
					{
						goRight();	
						printf("goRight success\r\n");
					}
					else
					{
						if(UART1_RX_Buffer[0] != '\0')
						{
							stop();
							printf("Ö¸Áî·¢ËÍ´íÎó£º%s\r\n", UART1_RX_Buffer);
						}
					}
					
					memset(UART1_RX_Buffer, 0, UART1_REC_LEN);
					UART1_RX_STA = 0;
				}
				else
					// 否则认为接收错误,重新开始
					UART1_RX_STA = 0;
			}
			// 如果没有收到了 0x0d (回车)
			else	
			{
				// 则先判断收到的这个字符是否是 0x0d (回车)
				if(buf == 0x0d)
				{
					// 是的话则将 bit14 位置为1
					UART1_RX_STA |= 0x4000;
				}
				else
				{
					// 否则将接收到的数据保存在缓存数组里
					UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;
					UART1_RX_STA++;
					
					// 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收
					if(UART1_RX_STA > UART1_REC_LEN - 1)
						UART1_RX_STA = 0;
				}
			}
		}
		// 重新开启中断
		HAL_UART_Receive_IT(&huart1, &buf, 1);
	}
}

在main.c函数中记得开启接收中断

// 开启接收中断
HAL_UART_Receive_IT(&huart1, &buf, 1);

手机打开蓝牙助手,记得把发送新行勾上,不然中断接收不到数据。
image
最后就可以实现手机通过蓝牙模块控制小车运动:
image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1869170.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AIGC在游戏行业落地如何了?一起看看这篇文章

在2023年初AIGC开始被大众所认知的时候,游戏领域的股票一片飘红,AIGC被认为可以赋能游戏制作的各个环节,游戏板块(BK1046)从2023年初的800左右到2023年中翻倍至1600左右。 到今天,距离这个概念普及一年半有余,期待的效…

vscode安装lean4

本教程演示在Windows系统下如何安装Lean 4正式版。Linux和MacOS版本请参考Lean Manual。 如果你身在中国,在运行安装程序前需要做如下准备: 在系统目录C:\Windows\System32\drivers\etc文件夹下找到hosts文件。对于其它系统用户也都是找到各自系统的host…

Mind+在线图形编程软件(Sractch类软件)

Scratch作为图形编程软件,可以为小朋友学习编程提供很好的入门,是初次接触编程的小朋友的首选开发软件。这里介绍的Mind软件与Sractch用法几乎完全一致,并且可以提供在线免安装版本使用,浏览器直接打开网址: ide.mindp…

各省药品集中采购平台-地方药品集采分析数据库

国家第十批药品集中采购的启动时间暂未明确,但即将到来,在5月,国家医保局发布了《关于加强区域协同做好2024年医药集中采购提质扩面的通知》,其中明确指出将“开展新批次国家组织药品和医用耗材集中带量采购,对协议期满…

python爬虫--scrapy框架

Scrapy 一 介绍 Scrapy简介 1.Scrapy是用纯Python实现一个为了爬取网站数据、提取结构性数据而编写的应用框架,用途非常广泛2.框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片,非…

模拟物理弧线轨道运动(模拟飞盘,子弹运动)

模拟物理弧线运动(模拟飞盘) 介绍实现代码总结 介绍 模拟弧线的运动,并且对象始终朝向运动的方向,模拟飞盘子弹的运动轨迹。这里我是没有加重力这么一个概念的,当然了重力其实比较简单可以参考我之前写的模拟抛物线运动…

2024十大首码地推拉新app平台,一手首码对接平台!

到了2024年,地推新应用的接单平台成为创业者们关注的焦点。对于地推行业的从业人员而言,选择一家拥有一手单资源的平台至关重要,因为这直接关系到他们的利益。 2024年如果想要进行app地推活动,却没有人脉渠道的困扰,建…

ABB机器人控制柜各模块指示灯状态说明

ABB机器人控制柜各模块指示灯状态说明 主计算机模块位于控制柜的正前方,负责机器人的各种运算处理,安全模块主要负责安全相关的信号处理,驱动单元模块用于接收上位机指令,驱动机器人运动,轴计算机模块用于接收主计算机的运动指令和串

VMware的具体使用

📑打牌 : da pai ge的个人主页 🌤️个人专栏 : da pai ge的博客专栏 ☁️宝剑锋从磨砺出,梅花香自苦寒来 目录 一🌤️VMware的安…

直播怎么录制视频?直播视频,3种录制方法

“今晚我最喜欢的游戏博主要进行直播,但我可能还要加班。怎么办,不想错过直播的内容!电脑怎么才能进行直播录制视频啊?谁能教教我?” 在数字化的今天,直播已经成为人们获取信息和娱乐的重要途径。有时&…

无线麦克风推荐哪些品牌,一文揭秘无线麦克风领夹哪个牌子好!

​究竟该如何选择麦克风呢?又该如何挑选无线麦克呢?询问我关于麦克风选择问题的人着实不少。对于那些仅仅是想要简单地自我娱乐的朋友而言,着实没必要去折腾,直接使用手机自带的麦克风便可以了。 但若是处于想要直播、拍摄短视频…

文本分类-RNN-LSTM

1.前言 本节介绍RNN和LSTM,并采用它们在电影评论数据集上实现文本分类,会涉及以下几个知识点。 1. 词表构建:包括数据清洗,词频统计,词频截断,词表构建。 2. 预训练词向量应用:下载并加载Glove的…

端到端图像分类算法开发实战:从 Arm 虚拟硬件到 Grove Vision AI Module V2 物理硬件

端到端图像分类算法开发实战:从 Arm 虚拟硬件到 Grove Vision AI Module V2 物理硬件 文章目录 1. 写在前面2. 产品简介2.1 Arm 虚拟硬件镜像产品简介2.2 Grove - Vision AI V2 产品简介 3. 实验前准备4. 实验步骤4.1 模型训练4.2 Arm 虚拟硬件镜像上的部署测试4.2…

【HarmonyOS NEXT】har 包的构建生成过程

Har模块文件结构 构建HAR 打包规则 开源HAR除了默认不需要打包的文件(build、node_modules、oh_modules、.cxx、.previewer、.hvigor、.gitignore、.ohpmignore)和.gitignore/.ohpmignore中配置的文件,cpp工程的CMakeLists.txt,…

【Python机器学习】自动化特征选择——迭代特征选择

在单变量测试中,没有使用模型;在基于模型的选择中,使用单个模型来选择特征。而在迭代特征选择中,将会构造一系列模型,每个模型都使用不同数量的特征。有两种基本方法: 1、开始时没有特征,然后逐…

【MySQL基础篇】概述及SQL指令:DDL及DML

数据库是一个按照数据结构来组织、存储和管理数据的仓库。以下是对数据库概念的详细解释:定义与基本概念: 数据库是长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。 数据库不仅仅是数据的简单堆积,而是遵循一定的规则…

聚合项目学习

首先建立一个总的工程目录,里边后期会有我们的父工程、基础工程(继承父工程)、业务工程(依赖基础工程)等模块 1、在总工程目录中(open一个空的文件夹),首先建立一个父工程模块(通过spring init…

Unity中模拟抛物线(非Unity物理)

Unity中模拟抛物线非Unity物理 介绍剖析问题以及所需公式重力加速度公式:h 1/2*g*t*t(h 1/2 * g * t ^ 2)速度公式:Vt V初 a * t 主要代码总结 介绍 用Unity物理系统去做的抛物线想要控制速度或者想要细微的控制一些情况是非常困难的。所以想要脱离U…

【Linux系列】Fedora40安装VMware Workstation Pro报错

问题描述 由于Fedora 40使用的Linux内核是6.9,导致安装VMware Workstation Pro 时,安装依赖无法成功,具体报错如下 ..................CC [M] /tmp/modconfig-a8Fcf5/vmnet-only/smac.oCC [M] /tmp/modconfig-a8Fcf5/vmnet-only/vnetEvent.oCC [M] /tmp/modconfig-a8Fcf…

《数据勒索防范手册(1.0版)》

当前,数据勒索攻击已成为全球最严重的数据安全威胁之一攻击方式呈现 APT 化、平台化、多重化、AI驱动化等发展趋势:据统计,近年来针对制造业、公共事业、卫生保健、电力、交通、能源等领域的勒索攻击显著增加。随着云计算、边缘计算等技术的不断发展&…