1.前言
在前一篇中,已经基本确认了整个的硬件架构。
接下来先搞定机械臂的Solidworks建模以及导出urdf文件,以及PCA9685对舵机的测试。
2.机械手Solidworks建模及其URDF文件导出
2.1.机械手建模
等了几天,购买的舵机机械手配件都已经到了。粗略组装了一下。
然后根据商家提供的一些配件图纸,利用solidworks基本建立了模型。但是由于提供的图像缺失了一些尺寸,以及某些尺寸的标注得奇奇怪怪的,因此绘制出来的模型与实际并不完全相符,另外有些地方我也做了简化(比如爪子)处理、懒得绘制复杂的外形(底座),因此绘制的模型仅供参考。不过,对于本次“科研项目”,只要不影响moveit使用就行。几百块,只能将就将就了😄。
solidworks里面的模型的底座和实际的底座不一样,但是都是起到支撑作用,且提供了绕Z轴转动的功能,在一定范围内不影响轨迹的计算。
2.2.urdf文件导出
这里需要用到一个插件,可以参考这里【Solidworks导出URDF总结(Noetic)】
注意导出之前,先把模型的各个关节摆弄到0度位置,否则后面控制需要反复核对角度。
我用的是Solidworks2020_sp0,然后导出时选择保存mesh,这样我们就得到可以用在ros的模型了。
但是该插件导出的演示工程是适用于ROS1的,我们的ROS2用不了,所以我们只要urdf、meshes这两个文件夹就行了。
假如导出的模型在导入moveit时出现零件错位,可以看看这里,主要是坐标旋转问题(将3.1416改成0)。
但是我的是要将某个角度从0改成3.1416,这个可能要实际问题,实际分析吧。
2.3.moveit导入urdf测试
参考前面的【在ROS2中,通过MoveIt2控制Gazebo中的自定义机械手】,将urdf文件经过moveit-setup-assistant配置好之后,应该就可以在rviz中摆弄了。
这次只是简单测试一下solidwork导出的urdf模型是否能够在moveit中使用,其他的(节点通讯、轨迹规划等)等下次再搞。
3.PCA9685通讯及舵机调试
3.1.PCA9685通讯
一般来说,舵机的控制周期为20ms,也就是频率为50Hz。然后有些舵机的0-180/0-360度分辨对应0.5ms-2.5ms的脉宽。360度舵机、180度舵机可能不一样,具体要自己试一下,不过好像都是以1.5ms为基准位置,然后向左右偏移0.5ms或者1.0ms。具体信息可以参考【PCA9685:I2C转16路PWM,助力你的系统】,以及【舵机的控制原理】。我目前用的DS3115的角度范围是0-180度,对应脉宽是0.5ms-2.5ms。
因此,需要将PCA9685设置为50HZ,然后在一定范围内调节脉冲宽度。具体的设置流程可以参考【SG90模拟舵机控制及PCA9685模块的使用】,以及【pca9685使用教程以及proteus仿真】
本次我使用与PCA9685进行IIC通信的芯片为STM32F103C8T6,关于stm32的开发,可以查看我之前的一篇博客【stm32cubeIDE的使用】,只要手动点击几下就可以将IIC通讯配置好了。
与PCA9685通讯的主要代码如下:
pca9685.h
#ifndef INC_PCA9685_H_
#define INC_PCA9685_H_
typedef unsigned char u8;
typedef unsigned short u16;
#define pca9685Addr 0x40
#define PCA9685_MODE1 0x00
#define PCA9685_PRESCALE 0xFE
u8 IIC_Write_Len(u8 addr, u8 reg, u8 len, u8 *buf);
u8 IIC_Read_Len(u8 addr, u8 reg, u8 len, u8 *buf);
u8 pca9685_Read_Reg(u8 reg);
void pca9685_Write_Reg(u8 reg, u8 dat);
void Set_Duty(u8 num, u16 off);
void pca9685_setPWMFreq(float freq);
void pca9685_Init(float Hz);
int set_angle(u8 channel, float angle);
#endif
pca9685.c
#include "pca9685.h"
#include "i2c.h"
#include "usart.h"
#include <math.h>
u8 IIC_Write_Len(u8 addr, u8 reg, u8 len, u8 *buf)
{
addr = (addr << 1) | 0;
u8 data[10] = {0};
data[0] = reg;
for(int i = 0; i < len; i++)
{
data[1 + i] = buf[i];
}
if(HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)addr, (uint8_t*)data, len + 1, 10000)!= HAL_OK)
{
printf("++write len byte fail\r\n");
return 1;
}
return 0;
}
u8 IIC_Read_Len(u8 addr, u8 reg, u8 len, u8 *buf)
{
u8 tmp = (addr << 1) | 0;
if(HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)tmp, (uint8_t*)®, 1, 10000)!= HAL_OK)
{
printf("++write byte fail\r\n");
return 1;
}
tmp = (addr << 1) | 1;
if(HAL_I2C_Master_Receive(&hi2c1, (uint16_t)tmp, (uint8_t *)buf, len, 10000) != HAL_OK)
{
printf("--read byte fail\r\n");
return 2;
}
return 0;
}
unsigned char pca9685_Read_Reg(u8 reg)
{
unsigned char dat;
IIC_Read_Len(pca9685Addr, reg, 1, &dat);
return dat;
}
void pca9685_Write_Reg(u8 reg, u8 dat)
{
IIC_Write_Len(pca9685Addr, reg, 1, &dat);
}
void pca9685_setPWMFreq(float freq)
{
u8 prescale, oldmode, newmode;
float prescaleval;
freq *= 0.92;
prescaleval = 25000000;
prescaleval /= 4096;
prescaleval /= freq;
prescaleval -= 1;
prescale = floor(prescaleval + 0.5);
oldmode = pca9685_Read_Reg(PCA9685_MODE1);
newmode = (oldmode & 0xEF) | 0x10;
pca9685_Write_Reg(PCA9685_MODE1, newmode);
pca9685_Write_Reg(PCA9685_PRESCALE, prescale);
pca9685_Write_Reg(PCA9685_MODE1, oldmode);
HAL_Delay(2);
pca9685_Write_Reg(PCA9685_MODE1, oldmode | 0xa1);
}
void pca9685_Init(float Hz)
{
pca9685_setPWMFreq(Hz);
HAL_Delay(1);
}
void Set_Duty(u8 num, u16 off)
{
pca9685_Write_Reg(num*4+6, 0);
pca9685_Write_Reg(num*4+7, 0);
pca9685_Write_Reg(num*4+8, off&0xff);
pca9685_Write_Reg(num*4+9, off>>=8);
}
int set_angle(u8 channel, float angle)
{
if(angle < -90 || angle > 90)
{
return -1;
}
float ratio = 2.0 / 180.0;
float pulseWidth = 0.5 + (angle + 90) * ratio;
Set_Duty(channel, (pulseWidth / 20.0) * 4096);
}
main.c
...
int main(void)
{
...
pca9685_Init(50.0);
...
while (1)
{
...
static float angle = -90.0;
if(angle <= 90)
{
angle += 1.0;
}
else
{
angle = -90.0;
}
set_angle(0, angle);
HAL_Delay(50);
...
}
}
3.2.舵机调试及安装
针对每个舵机都给到0度的pwm信号,然后按照此处位置安装到机械臂上。机械臂安装完成后,理应和solidworks中的模型的0度位置一致。
可以在调试好舵机后,在舵机上用记号笔做一些标记,表明舵机转动的起点、终点、方向等,方便整体机械手的安装。
我这里人为规定舵机的转动范围为[-90, 90],然后安转时,以0度安装。
另外,DS3115电机据说支持50-330HZ的脉冲,本来以为脉冲上去,转动速度会快一些,但是经过测试,速度还是一样的。
但是由于电机的控制还是通过脉宽范围【0.5ms-2.5ms】来控制的,而对于pca9685而已,pwm周期可以进行4096等分,在脉宽范围不变的前提下,脉宽范围覆盖到了更多的等分区域,因此可以进行了更精细的控制。比如在50HZ的脉冲中,从【PCA9685:I2C转16路PWM,助力你的系统】可以知道舵机的步进角度为0.438度,而把频率改为100HZ后,步进角度就可以达到原来的一半:0.219度,提高了控制精度。
4.总结
经过上面的操作,舵机就基本在我们的掌控之中了。
下一步就可以通过串口建立电脑与stm32的通讯,从而实现电脑上发送相应的指令控制任意舵机的转动角度。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)