- [连载 0]Vrep入门介绍
- [连载 1]Vrep小车建模——前进和转向
- [连载 2]Vrep小车建模——内嵌脚本
- [连载 3]Vrep小车建模——matlab控制
- [连载 4]Vrep导入三维模型——PUMA560机械臂
- [连载 5]Vrep--Matlab Robitic Toolbox--PUMA560机械臂控制
- [番外1]Vrep小车机械臂抓取
- 知乎专栏:Vrep机器人动力学建模仿真
恭喜大家完成上一节[连载 2]Vrep小车建模——内嵌脚本的教程,上一节教程简单介绍了使用lua中的内嵌脚本进行开发,通过很小的代码量就可以实现一些基本功能。但是毕竟lua是一种比较小众的语言,而且大家跟顺手的语言可能是matlab、python和C++等,还有一些算法包可能也是基于这些语言开发的,在发出前几节教程后,很多同学都问我和matlab的连接,所以本节就以matlab连接讲述一下如何和vrep进行远程连接。
前言-关于盗版
Matlab是一个功能齐全的科学计算开发包,在高校里推广的非常好,但是大家要注意正版的Matlab授权是非常昂贵的,而且每一个包都非常贵,幸运的是很多高校都会有教育版的,不幸的是大家适应了matlab可以干任何事情的时候,而慢慢丧失了采用其他软件解决问题的能力。比如那我来举例子,我发现使用lua脚本就可以完成的事情,绝对不会偷懒使用matlab,甚至如果可以用python,我也要用python,一方面考虑速度问题(使用lua),另一方面是支持正版。在国内大家都认为知识是廉价品,尤其是收费软件,大家第一反应都是百度一个盗版的,这里我想和大家废话谈一下感受,尤其是你以后即将从事机器人这个行业。
做机器人控制,有次有人问我你这个代码量多少,我回答了一句“3000行左右吧”,然后被深深的鄙视了……但是你要知道一个运动学正解用矩阵实现的话只有一行……一个解析逆解可能10行之内就能解决,但是你自己去推导一个逆解花了多少时间?同样你在享受matlab这种一句话就能实现很多功能的软件时,背后都是很多人花了非常多精力实现的!包括为了制作这个教程,我也专门买了绘声绘影X9的正版去做一些视频的处理(后续会添加一些视频讲解)。总之就是告诉大家如果你要别人珍惜你的科研结果的话,请先珍惜别人的。
本节介绍
前面的废话比较多,现在正式介绍本节的内容。vrep已经提供了和matlab的接口,通过Remote API进行连接,通过含有Get
的函数从Vrep端读取数据,通过含有Set
的函数将matlab的数据传输到vrep。数据可以是vrep中提供的一些类型数据,比如Postion,Velocity等等这些;当然也可以设置一些用户自定义的数据,比如你要通过matlab调节pid,可以通过matlab打包(pack)这些数据,然后在vrep中进行解包(unpack)。这一节仍然是基于vrep小车,完成以下几方面内容:
- matlab控制小车运动和停止;
- matlab控制小车运动到某个固定位置;
- 添加视觉传感器,并将传感器图像传输到matlab中;
完整例程模型请点击购买
Step1 准备工作
matlab和vrep连接需要一些基本文件。首先要注意你的系统是32位的还是64位的,还有你安装的vrep的版本。
如果你安装的是3.4.0版本,那么你的vrep是装在C:\Program Files\V-REP3
这个目录下,如果你的是3.3.2版本,那么你的vrep是装在C:\Program Files (x86)\V-REP3
这个目录下,下面以3.3.2版本为例,如果你用3.4版本的话就直接替换前面的路径即可。
先新建一个matlab的工作路径,比如我这里建立一个E:\monkey\Vrep Tutorial\3vrep_car_Matlab
的路径。打开C:\Program Files (x86)\V-REP3\V-REP_PRO_EDU\programming\remoteApiBindings\lib\lib
,根据你的系统选择合适的文件夹,将下面的remoteApi.dll
文件拷贝到你的matlab工作路径中;然后打开C:\Program Files (x86)\V-REP3\V-REP_PRO_EDU\programming\remoteApiBindings\matlab\matlab
,将此文件夹下的所有文件都拷贝到你的工作路径下。看文字太麻烦的请看下面的动图,是不是要高喊666!!(感谢GifCam这款软件,太棒了!)
Step1 Matlab控制小车运动和停止
前两节教程我们制作了一个双轮驱动的小车,有同学和我反应说是万向轮有点丑,用球体来抽象实在是太难看了,并且修改了一些小bug(比如轮子速度与直观感觉相反),这里我修改了一下,看下图。是不是看起来自然了一点?
万向轮处理完了之后,我们在车轮中间添加一个标志点,名称为dummy。这个dummy的功能非常多,可以单独使用,也可以成对使用,下面就简单列举几种功能:
- 单独使用
- 用于做坐标系转换的中间参考,比如机械臂的安装位置和小车的转动中心有一定的偏差,可以中间加一个参考坐标dummy
- 做一些显示,比如显示机械臂末端的位置
- 做为一些非dynamic的的父节点。比如环境中的floor的父节点就是dummy。
- 成对使用
- 用于逆运动学解算,IK
- 动力学约束。比如你要让连杆结构的两个点始终固连到一起(这种情况一般常见于闭运动链)
- 当你搞不清坐标转换关系时,用一堆dummy去求相对位置和角度
大家刚开始用,要慢慢体会dummy的妙处,我这里先抛砖引玉。这里我们要在两个车轮的中心位置添加一个dummy,作为车辆的回转中心,同时添加一个目标位置,一会我们通过移动目标位置(黄色区域),控制小车能够准确驶入目标区域。我们使用这个状态作为起始状态,文件名为Vrep3_car_code_Step1.ttt
,获取文件请点击购买。
在讲述控制小车之前,先了解一下 欠驱动系统。大部分轮式小车均是欠驱动系统,以本教程的小车为例,它的位形空间为3,包括(x,y,theta),代表小车的位置和朝向;但是小车的任务空间为2,因为小车驱动机构为2,只能完成前进和转向两个动作,如果需要侧向移动的话,需要经过一系列的操作才能完成。(任务空间并不等于驱动机构数量,比如四轮驱动的小轿车仍然是一个欠驱动系统,因为仍然无法单独完成侧向移动的功能)。这个现象下面会给出一个动图暂时出来。
理解了上述的内容之后,我们先用matlab将小车控制运动起来。在matlab新建一个文件,将下面的代码贴入进去。
vrep=remApi('remoteApi'); % using the prototype file (remoteApiProto.m)
vrep.simxFinish(-1); % just in case, close all opened connections
clientID=vrep.simxStart('127.0.0.1',19997,true,true,5000,5);
if (clientID<0)
disp('Failed connecting to remote API server');
else
vrep.simxStartSimulation(clientID,vrep.simx_opmode_oneshot);
[res,MotorHandle_Left] = vrep.simxGetObjectHandle(clientID,'LeftMotor',vrep.simx_opmode_blocking);
[res,MotorHandle_Right] = vrep.simxGetObjectHandle(clientID,'RightMotor',vrep.simx_opmode_blocking);
tic;
Left_vel = 20;
Right_vel = -20;
while toc<15
vrep.simxSetJointTargetVelocity(clientID,MotorHandle_Left,Left_vel,vrep.simx_opmode_oneshot );
vrep.simxSetJointTargetVelocity(clientID,MotorHandle_Right,Right_vel,vrep.simx_opmode_oneshot );
pause(0.1);
end
end
vrep.simxStopSimulation(clientID,vrep.simx_opmode_oneshot_wait);
vrep.simxFinish(clientID);
vrep.delete(); % call the destructor!
从下图中可以看出,直接运行matlab程序,即可远程启动vrep的仿真。下面讲解一下这个程序的结构。
vrep=remApi('remoteApi'); % using the prototype file (remoteApiProto.m)
vrep.simxFinish(-1); % just in case, close all opened connections
clientID=vrep.simxStart('127.0.0.1',19997,true,true,5000,5);
这三句里一般都不需要更改,唯一需要注意的19997这个参数,vrep默认启动的时候会打开一个19997的端口,只有使用这个端口,你的程序才能直接远程启动vrep仿真,你可以试试其他的端口比如19998,看看程序还能正常运行吗?
if (clientID<0)
disp('Failed connecting to remote API server');
else
要执行的内容
end
这个也是常用的结构,至于为什么要判断clientID<0,请大家看simxStart
的帮助文档。
如果学习了内嵌脚本的教程,看到simxGetObjectHandle这个函数比lua多了一个参数,就是操作模式(operationMode),这里用到了simx_opmode_blocking
、simx_opmode_oneshot
和simx_opmode_oneshot_wait
这三种。simx_opmode_blocking
和simx_opmode_oneshot_wait
是一个意思,可以理解为这个操作执行一次,但是没有执行完就要等,所以速度慢,但是会保证通信完成(和通信协议里的握手很像)。simx_opmode_oneshot
表示我把数据发出去之后就开始执行后面的语句,不管你发完了没。比如simxGetObjectHandle
这个函数使用的是simx_opmode_blocking
,因为需要确保这句话执行完,然后再去执行后面的“给关节速度赋值”的操作,如果没有执行完就去执行后面的操作就可能会报错;simxSetJointTargetVelocity这条指令采用的是simx_opmode_oneshot
,表示我把这个速度发出去就不管了,如果你是控制机械臂的话,而采用的simx_opmode_blocking
模式的话,你会发现机械臂所有关节各个轴时差会比较大!
vrep.simxStopSimulation(clientID,vrep.simx_opmode_oneshot_wait);
vrep.simxFinish(clientID);
vrep.delete(); % call the destructor!
处理一些收尾工作,这个一般大家套用这个格式就可以了。
代码的详细中文注释请点击购买
Step2 Matlab控制小车运动到某个固定位置
根据上图,简要分解一下控制过程。(在 [番外2]Vrep小车机械臂抓取的教程中更新了小车的控制算法,避免了欠驱动一些问题)
Step2_1 移动到目标点
首先我们要测量车身和目标点的相对位置,得到的是直角坐标系(x,y),我们将其转换为极坐标系(d,theta)。根据上一节介绍小车为欠驱动系统,不能直接实现y方向的移动,因此我们需要将车头对准目标点(也就是调整theta为0),然后根据与目标点的距离d做一个简单的比例控制器,实现小车运动到目标点。具体过程如下图。具体代码及中文注释见Vrep3_car_code_Step2_1_matlab.m
。
Step2_2 对齐方向
刚才的动图可以看到采用一个简单的比例控制器既可以控制小车移动到目标位置(有兴趣的读着可以使用PI控制,响应会更快一些,但是注意积分饱和),但是小车并没有按照我们的预期将三个轮子停入到目标的蓝色区域内,因此我们需要再增加一个操作——运动到目标点之后,调整小车姿态,效果如下图。代码具体代码及中文注释见Vrep3_car_code_Step2_2_matlab.m
。
注意采用
simx_opmode_buffer
的时候第一次调用的时候先用simx_opmode_streaming
,然后才能调用simx_opmode_buffer
。
至此,小车的控制已经讲完了。但是上面用极坐标去做的控制,其实也可以用直角坐标做;上面用的是比例控制器,可以看到当误差较小的时候控制量也非常小。针对这两个问题,我用lua写了一个直角坐标的PI控制器,大家可以参考参考,文件名为Vrep3_car_code_Step2_luaPID.ttt
,点击购买。
Step3 增加视觉传感器
有同学问我说是怎么将图像传回到matlab里,我们这里增加介绍两个强大功能:
- 利用vrep自带的工具进行图像识别
-
将视觉传感器的数据传输到matlab中
图像识别效果如下(虚线框表示蓝色区域位置):
图像传感器的配置请查看
Vrep3_car_code_Step3视觉传感器配置.png
,代码和仿真环境请看Step3相关的文件。
购买链接
结语
matlab是一个强大的工具,加上petercorke的Robotics Toolbox,更是如虎添翼,可以完成非常多的功能。后面的更新我就重点集中在一些技巧的使用上,给大家分享一下如何玩转Vrep,哈哈哈
感谢大家能够读完本教程,希望对你有所收获,我留一个微信,大家可以加我,欢迎多多交流~~