@Pigmon
2017-12-20T09:40:10.000000Z
字数 4516
阅读 2179
实习
Matlab 脚本向 V-Rep 中的挖掘机发送控制信号的简单上手指南。
Model Browser -> Vehicles -> excavator.ttm

将其拖放至场景中的地板上。
在 Scene Hierarchy 中找到 Excavator,右键点击其右侧的脚本标志。
在弹出菜单中选择 Edit -> Remove -> Associate Child Script

在 Scene Hierarchy 中找到 Excavator,右键点击。
在弹出菜单中选择 Add -> Associate Child Script -> Non Threaded

新添加的 Lua 脚本中,预先放好了几个 if 语句块,代表不同的系统回调。
其中:
if (sim_call_type==sim_childscriptcall_initialization) thenend
是初始化过程,只会在场景启动的时候执行一次。
if (sim_call_type==sim_childscriptcall_actuation) thenend
是相当于主循环过程中的控制部分,是每帧都执行的程序。
其他2部分分别是 Scensing 和 Cleanup,暂时不用。
这里我们只示例控制铲斗的过程,其他的挖机臂是类似的情况。
程序主要参考了其自带的UI控制程序(已经删除的脚本)。
if (sim_call_type==sim_childscriptcall_initialization) thenexcavatorHandle=simGetObjectAssociatedWithScript(sim_handle_self)-- 得到控制铲斗的液压缸 Objectpiston4=simGetObjectHandle('Piston4')-- 得到铲斗液压缸的运程范围-- piston4Range是含有2个元素的数组-- 范围从 piston4Range[1] 到 piston4Range[2]c,piston4Range=simGetJointInterval(piston4)-- 得到初始状态下,铲斗液压缸位置在运程中的百分比current_piston4 = (simGetJointPosition(piston4)-piston4Range[1])/piston4Range[2]-- 建立铲斗液压缸移动目标变量target_piston4 = current_piston4-- 定义跟 Matlab 端的通信接口simExtRemoteApiStart(19999)end
-- 一次执行只是一帧中的运算,因此这里是根据(上一帧位置,最终目标位置,速度)等这些参数-- 计算出这一帧里,delta 位移的大小,进而设置下一帧的位置。if (sim_call_type==sim_childscriptcall_actuation) then-- 当前帧时间ts=simGetSimulationTimeStep()-- 模型基本缩放(?)s=simGetObjectSizeFactor(excavatorHandle)-- Joint 的速度限制maxPiston4Vel=0.1*s-- Piston 4:-- 目标位置pistonTargetPos=s*(piston4Range[1]+piston4Range[2]*target_piston4)-- 当前位置current_piston4=simGetJointPosition(piston4)-- Delta 位置dx=(pistonTargetPos-current_piston4)if math.abs(dx)>maxPiston4Vel*ts thendx=maxPiston4Vel*ts*dx/math.abs(dx)end-- 设置当前帧铲斗液压缸的位置simSetJointPosition(piston4,current_piston4+dx)end
这是给Matlab端调用的自定义函数
参考 V-Rep 自带文档的 《Extending the Remote API》
这里我们需要Matlab指定一个浮点数(液压缸目标位置百分比),将其赋值给target_piston4
在脚本最末尾添加如下函数定义:
remoteSetPiston4=function(inInts,inFloats,inStrings,inBuffer)target_piston4 = inFloats[1]return {},{},{},''end
新建一个目录当作【工程目录】。
将 V-Rep 安装目录下,比如:
C:\Program Files\V-REP3\V-REP_PRO_EDU\programming\remoteApiBindings\matlab
中的
remApi.mremoteApiProto.mremoteApi.dll
拷贝到新的工作目录中。
注意这个 dll,32位或64位,必须跟 Matlab 的位数对应。
打开 Matlab,新建脚本,保存在【工程目录】中。
脚本内容:
function myTest1()vrep = remApi('remoteApi');vrep.simxFinish(-1);% 这里的端口号必须和 V-Rep 端声明的相同(比如 19999)clientID = vrep.simxStart('127.0.0.1',19999,true,true,5000,5);if (clientID > -1)disp('Test1 connected to V-Rep');pause(2);% 调用远程控制接口 'remoteSetPiston4'% @clientID, simxStart 返回的通信句柄% @'Excavator': V-Rep 场景中,脚本挂载的 Object (挖掘机)% @vrep.sim_scripttype_childscript:函数的载体是 child script% @'remoteSetPiston4': 远程函数名,在 V-Rep 脚本中定义% @[],[1],[],[]: 4 个输入参数,分别是int数组,float数组... 这里我们用 float 数组% @vrep.simx_opmode_blocking: 阻塞模式通信vrep.simxCallScriptFunction(clientID,'Excavator',vrep.sim_scripttype_childscript,'remoteSetPiston4',[],[1],[],[],vrep.simx_opmode_blocking);elsedisp('Failed connecting to remote API server');endvrep.delete();disp('Ended.');end
V-Rep 中启动新建场景。
Matlab 中运行脚本。
看 V-Rep.
铲斗应该会从这个姿势:

运动到(液压缸位置百分比位1的位置):

-- DO NOT WRITE CODE OUTSIDE OF THE if-then-end SECTIONS BELOW!! (unless the code is a function definition)if (sim_call_type==sim_childscriptcall_initialization) thenexcavatorHandle=simGetObjectAssociatedWithScript(sim_handle_self)piston4=simGetObjectHandle('Piston4')c,piston4Range=simGetJointInterval(piston4)current_piston4 = (simGetJointPosition(piston4)-piston4Range[1])/piston4Range[2]target_piston4 = current_piston4simExtRemoteApiStart(19999)endif (sim_call_type==sim_childscriptcall_actuation) thents=simGetSimulationTimeStep()s=simGetObjectSizeFactor(excavatorHandle)maxPiston4Vel=0.1*s-- Piston 4:pistonTargetPos=s*(piston4Range[1]+piston4Range[2]*target_piston4)current_piston4=simGetJointPosition(piston4)dx=(pistonTargetPos-current_piston4)if math.abs(dx)>maxPiston4Vel*ts thendx=maxPiston4Vel*ts*dx/math.abs(dx)endsimSetJointPosition(piston4,current_piston4+dx)endif (sim_call_type==sim_childscriptcall_sensing) then-- Put your main SENSING code hereendif (sim_call_type==sim_childscriptcall_cleanup) then-- Put some restoration code hereendremoteSetPiston4=function(inInts,inFloats,inStrings,inBuffer)target_piston4 = inFloats[1]return {},{},{},''end
function myTest1()vrep = remApi('remoteApi');vrep.simxFinish(-1);clientID = vrep.simxStart('127.0.0.1',19999,true,true,5000,5);if (clientID > -1)disp('Test1 connected to V-Rep');pause(2);vrep.simxCallScriptFunction(clientID,'Excavator',vrep.sim_scripttype_childscript,'remoteSetPiston4',[],[1],[],[],vrep.simx_opmode_blocking);elsedisp('Failed connecting to remote API server');endvrep.delete();disp('Ended.');end