概述
Elmo驱动器 SimplIQ系列可以结合编码器信息,以多种模式控制伺服电机,常用的模式有速度控制模式,力矩控制模式,微步控制模式。实验室使用的场景基本就是速度模式控制伺服电机的旋转,对于四轮独立驱动转向的小车来说,通过改变PWM周期可以达到调速的目的。对于多轴机械臂来说,不仅需要速度控制,还需要以特定的速度模式工作,也就是PVT(position-velocity-time)模式,通过ROS规划的机械臂路径就是包含各轴运动过程的PVT数据。所以我们可以通过将ROS规划的路径经过三次样条插补得到一条更加平滑的路径(https://blog.csdn.net/qq_34935373/article/details/98482706),然后将数据处理成elmo驱动器的PVT模式下的控制指令或者程序(多条指令特定集合),更加精确的控制伺服电机。
首先介绍驱动器速度模式下的指令,如下所示是速度环反馈过程,反馈的参数在电机调试过程中确定,详见之前博客或者参考手册。
速度模式下不可避免要设计到速度和加速度等信息,特别在机械臂的运动过程中,对各轴的加速度是有限制的,ELMO驱动器中有特定的指令可以帮助我们设置最大加速度和减速度的限制,如下所示,JV是设置速度的指令,让电机以特定的速度持续运动,PM和SF后面的PVT控制也需要用到,BG指令是命令开始执行,如果有新的程序或指令上传到了驱动器,那么开始执行程序。
PM上述描述说的很清楚了,推荐使用PM=1;最后一个指令SF是用来平滑加速度的,如下所示,分别使用SF=0;SF=10;SF=50查看速度的曲线可以看出,SF较小的时候,速度是有抖动了,当SF较大的时候,速度非常平滑,但是到达指定速度所用时间更长,响应更慢。
接下来重点说明机械臂所使用的PVT控制模式,当然除了PVT模式,还有Jog持续运动模式,PTP点到点运动模式,PT位置时间模式,可以查看相应手册。此处使用的PVT控制方法是可以通过CAN总线来达到实时性的目的,目前使用的方式是通过串口将路径的PVT数据一次性发送到驱动器,并不具有实时性。使用PV命令来选择PVT模式。
对于PVT模式的运动,要确保第一个点的速度要是0,电机不处于运动状态。下图是驱动器PT和PVT模式的对比,重点关注的就是Motion buffer length 和Time between user data points两个参数,第一个参数说明了PVT最大可以储存的路径点为64,超过64个路径点就会报错,第二个参数说明了每个路径点之间的时间间隔范围为【1-255】毫秒。
路径点最多可以达到64个,规划时间间隔在毫秒级别,每个点的PVT数据描述方式如下:
驱动器执行PVT模式的时候,内部相当于有一个指针依次读取,所以驱动器需要知道一共有多少一个PVT路径点和起始点,通过MP指令确定,如下所示,MP[1]定义开始的inxdex,一般设置为MP[1]=1;MP[2]定义结束的Index,例如有10个点,那就是MP[2]=10;MP[3]是两个bit位控制,我选择的是00,停止运动但是不结束PVT模式,所以MP[3]=0;。
注意上述指令读取之前,需要先设置MO=0;UM=5;RM=0;PX=0;意思就是先停止电机,工作在特定模式,RM=0表示不使用feedback B,PX=0表示清零编码器数据。如下程序使用了八个PVT点,运行的效果是先以10000cnt/s正转到编码器数据为1250脉冲的位置,然后反转会原始点,#@AUTOEXEC表示上电自动执行的程序,将该程序在Elmo Studio里面编译上传,然后点击红色感叹号即可运行程序(或者断电再上电,也会自动执行)。
#@AUTOEXEC
MO=0;UM=5;RM=0;PX=0;
MP[1]=1;MP[2]=8;MP[3]=0;
QP[1]=0; QV[1]=0; QT[1]=250;
QP[2]=1250; QV[2]=10000; QT[2]=250;
QP[3]=3750; QV[3]=10000; QT[3]=250;
QP[4]=5000; QV[4]=0; QT[4]=250;
QP[5]=5000; QV[5]=0; QT[5]=250;
QP[6]=3750; QV[6]=-10000;QT[6]=250;
QP[7]=1250; QV[7]=-10000;QT[7]=250;
QP[8]=0; QV[8]=0;
MO=1;
PV=1;
BG
后面要通过串口发送指令的方式控制程序运行,所以不采用#@AUTOEXEC这种自动执行程序的方式,改用调用函数的方式,将开头写成##Func的形式,然后发送指令XQ##Func;即可调用该函数,不需要通过Elmo Studio点击感叹号执行了,和上面实现的效果是一样的。
通过自带的Elmo Studio 完成的PVT模式的编程和控制,我们的最终目的是通过板子读写串口的方式控制驱动器,现在要解决的问题就是编译问题,在软件里面点击的编译按钮是没有对应的指令(可能有,我没发现),但是之前的手册说了,程序也知识特定的指令按照特定的顺序组合起来的东西,所以尝试通过串口将上面的程序里的指令直接发送看看效果,如下是通过串口调试助手的效果:
通过观察电机的运动,发现果然可以,稍微有点不同的是,将指令按顺序直接发送,因为这里BG;指令就是执行程序的效果,如果想再调用一次,那么可以再发送一个XQ##Func;即可。
接下来通过板子往串口发送指令的方式,简化程序和节约时间空间的角度考虑,将要发送的数据变成如下形式:
MO=0;UM=5;RM=0;PX=0;MP[1]=1;MP[2]=8;MP[3]=0;QP[1]=0;QV[1]=0;QT[1]=250;QP[2]=1250;QV[2]=10000;QT[2]=250;QP[3]=3750;QV[3]=10000;QT[3]=250;QP[4]=5000;QV[4]=0;QT[4]=250;QP[5]=5000;QV[5]=0;QT[5]=250;QP[6]=3750;QV[6]=-10000;QT[6]=250;QP[7]=1250;QV[7]=-10000;QT[7]=250;QP[8]=0;QV[8]=0;MO=1;PV=1;BG;
连接板子,硬件参考https://blog.csdn.net/qq_34935373/article/details/103131748
#include<stdio.h>
#include<fcntl.h>
#include <string.h>
#include<unistd.h>
#include<termios.h> // using the termios.h library
#define SLOTS "/sys/devices/bone_capemgr.9/slots"
int main()
{
int fd, count_r,count_t,i;
struct termios opt; //uart confige structure
// 加载设备树
if ((fd = open(SLOTS, O_RDWR)) < 0)
{
perror("UART: Failed to open the UART device:ttyO1.n");
return -1;
}
write(fd,"BB-UART2",8);
close(fd);
//open the UART1: read&write, No block and doesn't serve as an terminal
if ((fd = open("/dev/ttyO2", O_RDWR | O_NOCTTY | O_NDELAY)) < 0)
{
perror("UART: Failed to open the UART device:ttyO1.n");
return -1;
}
tcgetattr(fd, &opt); // get the configuration of the UART
// config UART
opt.c_cflag = B19200 | CS8 | CREAD | CLOCAL;
// 9600 baud, 8-bit, enable receiver, no modem control lines
opt.c_iflag = IGNPAR | ICRNL;
// ignore partity errors, CR -> newline
opt.c_iflag &= ~(IXON | IXOFF | IXANY);
//turn off software stream control
opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
//关闭回显功能,关闭经典输入 改用原始输入
tcflush(fd,TCIOFLUSH); // 清理输入输出缓冲区
tcsetattr(fd, TCSANOW, &opt); // changes occur immmediately
char str[] = "MO=0;UM=5;RM=0;PX=0;MP[1]=1;MP[2]=8;MP[3]=0;QP[1]=0;QV[1]=0;QT[1]=250;QP[2]=1250;QV[2]=10000;QT[2]=250;QP[3]=3750;QV[3]=10000;QT[3]=250;QP[4]=5000;QV[4]=0;QT[4]=250;QP[5]=5000;QV[5]=0;QT[5]=250;QP[6]=3750;QV[6]=-10000;QT[6]=250;QP[7]=1250;QV[7]=-10000;QT[7]=250;QP[8]=0;QV[8]=0;MO=1;PV=1;BG;";
int len_str = strlen(str);
unsigned char send_buff[] = {0};
for(i=0;i<len_str;i++)
{
send_buff[i] = str[i];
}
if ((count_t = write(fd, send_buff,len_str))<0)
{
perror("ERR:Failed to write to the Device:ttyO2n");
return -1;
}
usleep(5000000); // 延时 5s
close(fd);
return 0;
}
最后
以上就是平常服饰为你收集整理的ELMO驱动器用arm板子控制,并工作在 PVT(position-velocity-time)模式的全部内容,希望文章能够帮你解决ELMO驱动器用arm板子控制,并工作在 PVT(position-velocity-time)模式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复