三轮全向底盘实现绘图功能

1. 功能说明

      本文示例将实现R313a样机三轮全向底盘绘图(三角形、矩形、三叶草、正弦曲线)的功能。三轮全向底盘绘制图形有两种模式:第一种是自主选择模式(即通过按下开关进行模式的选项);第二种是上位机模式(即通过上位机发送坐标来完成绘制)。这里主要介绍下自主选择模式绘制图形。

2. 结构说明

    R313a样机主要是由R313c样机上安装一个 舵机关节模组 组成。

       三轮全向底盘采用全向福来轮作为执行轮,全向福来轮由主轮和副轮组成,主轮和副轮成垂直分布。三个轮成正三角形分布,两两夹角120度,这种结构使得全向底盘运动灵活、可以在平面内任意方向平移。

三轮全向底盘简图

三轮全向底盘的全向移动需要三个轮之间的相互配合,具体运动方向和各个轮的转向如下图所示:

三轮全向底盘运动简图(横线表示该轮不转,箭头方向为轮转动方向)

3. 三轮全向底盘的运动学逆解分析

我们先做一些必要的前提假设:

① 全向底盘质量分布均匀,每个轮子的大小和质量相同;

② 三个全向轮到中心的距离相等,且两两夹角为120度;

③ 全向底盘不会出现打滑。

     首先建立一个世界坐标系X′O′Y′,然后再建立机器人自身的坐标系XOY。设中心到轮子的距离为常数L,移动平台自身的角速度为ω,设顺时针为角速度正方向,各个轮子的速度分别为Va,Vb,Vc。移动平台在自身坐标系下的分速度为Vx,Vy。夹角 θ₁ = π / 3,θ₂ = π / 6 , α是两个坐标系的夹角。

逆解:

所谓逆解,就是给定一个世界坐标系下的速度矢量,需要求出三个轮子分别需要给多少速度才可以使机器人在世界坐标系下达到该速度矢量。通过简单的速度矢量运算我们可以列出以下的线性方程组:

该线性方程组变成矩阵形式就像下面这样:

 这个解是在机器人自身坐标系下的,当运用到实际场景中还需要一步转换。其实很简单,再乘上一个旋转矩阵就可以了。现在假设我们已经知道 α 的大小了,那么求旋转矩阵就没什么难度了,从X′O′Y′到XOY的旋转矩阵为:

 那么从XOY到X′O′Y′的旋转矩阵就是R(α)的逆矩阵:

 所以有:

 将这个关系代入第一个线性方程中得:

化简得:

4. 电子硬件

本实验中采用了以下硬件:

主控板

STM32主控板

扩展板

STM32扩展板

电池7.4v锂电池
传感器触碰传感器
输出模块OLED显示屏

其它

步进电机、标准舵机

 按下图进行电路连接:舵机连接在PD15引脚上。

 

5. 功能实现

编程环境:keil5

功能:当按上边的触碰传感器时,OLED显示屏上会显示出不同的选项(sin/ Triangle/ Rect/ ThreeLeaf);当按下边的触碰传感器时,开始绘制相应的内容(见下表)。

参数

绘制的图案

sin

正弦曲线

Triangle

三角形

Rect

矩形

ThreeLeaf

三叶草

三轮全向底盘绘图的参考例程(USER\test.uvprojx)如下,下面是主程序main.c:

/*------------------------------------------------------------------------------------

  版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved.

           Distributed under MIT license.See file LICENSE for detail or copy at

           https://opensource.org/licenses/MIT

           by 机器谱 2023-03-10 https://www.robotway.com/

  ------------------------------*/

#include "sys.h"

#include "led.h"

#include "usart.h"

#include "delay.h"

#include "math.h"

#include "stdio.h"

#include "string.h"

#include "stdlib.h"

#include "a4988.h"

#include "pwm.h"

#include "key.h"

#include "oled.h"

#include "stdbool.h"


int main(void)

{

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2

delay_init(168);//初始化延时,168为CPU运行频率

usart_init(9600); //串口初始化

usart3_init(9600);

LED_Init();//LED灯初始化

Stepper_Motor_Init(0); //步进电机引脚初始化

KEY_Init();

OLED_Init(1);

delay_ms(1000);

TIM4_PWM_Init(20000-1,84-1);

Put_Up();delay_ms(1500);

  int receive_touch[2] = {0,0};

bool Flags_draw = false;

OLED_Clear();

OLED_ShowString(30,3,(unsigned char*)"Wait...",16);

while(1)

{

if(touch_keys(1) == 1)

{

  delay_ms(350);

receive_touch[0] += 1;

Flags_draw = false;

}

if(touch_keys(2) == 1)

{

if(Flags_draw)

{

receive_touch[1] = 0;

}

else

{

    delay_ms(350);

  receive_touch[1] = 1;

}

}

  if(receive_touch[0]==1)

{

//printf("data:%d",receive_touch[0]);

  OLED_Clear();

  OLED_ShowString(0,0,(unsigned char*)"Sin",16);

if(receive_touch[1] == 1)

{

OLED_Clear();

OLED_ShowString(0,0,(unsigned char*)"Sin",16);

OLED_ShowString(0,4,(unsigned char*)"Start",16);

receive_touch[1]=0;

delay_ms(1000);

    Put_Down();delay_ms(1000);

    drawSin();

    Put_Up();delay_ms(1000);

}

}

if(receive_touch[0]==2)

{

//printf("data:%d",receive_touch[0]);

  OLED_Clear();

  OLED_ShowString(0,0,(unsigned char*)"Triangle",16);

if(receive_touch[1] == 1)

{

OLED_Clear();

OLED_ShowString(0,0,(unsigned char*)"Triangle",16);

OLED_ShowString(0,4,(unsigned char*)"Start",16);

receive_touch[1]=0;

    Put_Down();delay_ms(1000);

    drawTriangle();

    Put_Up();delay_ms(1000);

}

}



  if(receive_touch[0]==3)

{

//printf("data:%d",receive_touch[0]);

  OLED_Clear();

  OLED_ShowString(0,0,(unsigned char*)"Rect",16);

if(receive_touch[1] == 1)

{

//receive_touch[0]=0;

OLED_Clear();

OLED_ShowString(0,0,(unsigned char*)"Rect",16);

OLED_ShowString(0,4,(unsigned char*)"Start",16);

receive_touch[1]=0;

    Put_Down();delay_ms(1000);

    drawRect();

    Put_Up();delay_ms(1000);

}

}



  if(receive_touch[0]==4)

{

  OLED_Clear();

  OLED_ShowString(0,0,(unsigned char*)"ThreeLeaf",16);

if(receive_touch[1] == 1)

{

OLED_Clear();

OLED_ShowString(0,0,(unsigned char*)"ThreeLeaf",16);

OLED_ShowString(0,4,(unsigned char*)"Start",16);

receive_touch[1]=0;

    //Put_Down();delay_ms(1000);

    drawThreeLeaf();

    Put_Up();delay_ms(1000);

}

}


  if(receive_touch[0]==5)

{

  OLED_Clear();

  OLED_ShowString(8,3,(unsigned char*)"Draw Line End",16);

receive_touch[0]=0;

  receive_touch[1]=0;

  Flags_draw = true;

}

  }

}

三轮全向底盘绘制三角形、矩形、三叶草、正弦曲线的详细例程可下载文末资料获取。

6. 资料下载

三轮全向底盘-绘图

①绘图-例程源代码

②绘图-样机3D文件

资料详见:三轮全向底盘-绘图(STM32)

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值