四、达尔文机器人开发指南(针对中国机器人比赛、华北五省机器人比赛)-----达尔文官方框架解读
这是我开发过程中,参考的第二个博客,同样为了好理解,这里我在归纳一下。以下是达尔文的各模块图:
一、DARwin 机器人Frame代码简析(一)
1. CM730.cpp
主要定义了一些和控制板CM730(OP2实际使用的控制板是740)相关的函数,在头文件(CM730.h)中主要声明了三个类,BulkReadData、PlatformCM730、CM730。
BulkReadData类主要作用就是读取指定地址中的值int ReadByte(int address);int ReadWord(int address);参数address必须在start_address和start_address + length之间(start_address length均为成员变量)
CM730类主要是用来实现控制板相关的功能,比如:
开启各个电机的电源(DXLPowerOn()),对指定接口进行写操作(CM730::WriteByte())等
PlatformCM730类比较关键,在官方的架构图中也可以看出来这个类主要作用就是用作接口。
也可以发现,这个类中定义的所有成员函数都是虚函数(virtual),而我们可以发现在LinuxCM730.h头文件中(在Linux/include路径下),实际上LinuxCM730继承了(可能这个说法不严谨)PlatformCM730类(实际上从名字也可以看出来,linux属于一种platform),并且将成员函数重写,而LinuxCM730实际上和CM730控制板进行通信(不太确定,个人推测),这样就实现了CM730类中的函数可以直接对控制板进行控制或者读取。
2. MX28.cpp
主要是电机相关的信息,定义大量枚举类型,并根据电机的型号不同(OP2使用的电机分辨率是0.88,但另一种电机型号分辨率是0.293),定义不同的枚举类型值。
3. JointData.cpp
JointData类中定义了一些枚举类型,主要是将各个电机编号命名,除掉手部的电机(OP2原厂不提供),共有20个电机,正好和枚举类型一一对应。
同时也定义了一些枚举类型用来储存PID默认值。
还有一些前缀为SLOPE的枚举类型,个人猜测和路径规划的插值方式相关(逆运动学求解出的运动轨迹),值越大可能表示路径点越少,运动越“僵硬”。
除此之外,还有一些成员函数被定义,可以主要分为以下几个部分:
(1) SetEnable,设定哪一个关节(或者哪一个手臂或腿部)可以进行移动。
(2) GetEnable,获取某个关节是否可以动。
(3) SetValue(Angle、Radian、Slope),设置对某个电机发出的脉冲数量(角度值、弧度值、Slope猜测是和轨迹规划有关,尚不清楚)Get+名字对应相应的get函数,比如获取当前的角度。
(4) PID相关的set和get函数,主要用来设置电机的PID值。
4. Kinematics.cpp
主要用来存贮机器人形状,各个关节之间的位置关系等信息(腿长,脚踝宽等)
————————————————
二、DARwin 机器人Frame代码简析(二)Motion Manager/Status
从官方的结构图中可以看出,而实际上从头文件中可以看出,MotionManager充当的是一个管理器的角色,在MotionManager的类中,定义了一些成员变量,其中就包括一个指向CM730类的指针用来对CM730实例对象进行相应的操作,比如开启电机电源,对相应的控制板接口进行一些读写操作等等。
其次,成员变量中还定义了一个MotionModule指针的列表,MotionModule主要有三个部分,如开始的图片中所示,包含Head、action、walking三个组件,而在成员函数中,也有加载或卸载制定组建的成员函数:
除此之外,MotionManager还有一些其他的成员函数,主要功能有:
(1)初始化MotionManager,初始化必须指定CM730实例对象,初始化中主要进行的工作就是调用我们之前提到过的CM730的成员函数Connect(),开启通信接口,将电机上电。之后将对各个电机进行遍历,使用CM730中的成员函数读取电机的关节信息(角度值),
之后我们会发现如果读取关节角度成功,会将MotionStatus中的JointData(实例对象m_CurrentJoints)的各个关节的信息进行赋值(达到更新关节值的效果),其实在这里我们就已经可以推测出MotionStatus的具体作用了,那就是储存当前的关节值,打开MotionStatus头文件,我们会发现这个类没有定义任何成员函数,只定义了一些整型常量,以及我们刚刚提到的JointData类。
此时,我们再回顾一下JointData类,可能会有更深的理解,JointData类并不是用来直接控制各个关节的角度的,而是用来存贮信息的,因为我们可以看到成员变量中有三个非常重要的变量:
这三个数组实际上是一一对应的,每一位存贮的信息就是相应的电机序号的 Enable(是否激活),脉冲值以及角度值。
再回到MotionManager中,Initialize函数的功能就很清晰了,就是打开电机的电源,更新当前电机或者关节的角度等信息。
(2) 记录信息(StartLogging、Process函数),这个函数主要用来将当前的陀螺仪等传感器信息写入到一个文件中,用来记录数据。
总结来说,MotionManager可以看作是一个容器,其中包含了MotionStatus用来记录关节信息(JointData类),其次还有三个MotionModule(Head,Walk,Action),还有CM730类用来对硬件进行控制,如图所示:
三、DARwin 机器人Frame代码简析(三)MotionModule
MotionModule本身并没有功能的实现,而是作为基类被继承,其中头文件中定义了两个虚函数可以被重写:
其次还定义了一个JointData类用来储存关节信息:
由MotionModule可以衍生出三个模块:Action,Head以及Walking。
(1)Head。Head模块比较简单,主要是对机器人头部的控制,从头文件中就可以大概看出可以实现的功能:
上方的成员函数主要是获取上下左右四个方向角度限值,下部的函数主要用来设置头部移动,比如移动到Home点,按照给定的角度移动等(中间部分暂时清楚功能)
(2)Walking。Walking主要用来控制行走,主要会用到的功能就是Start和Stop,即开始行走,停止,行走过程中的步幅,摆动等细节几乎都可以进行设置。
(3)Action