V-REP教程(六) Script Style

脚本格式

Non-theraded child script
Non-theraded和Theraded script的格式区别在于前者是if then end四段,
后者是顺序式

-- DO NOT WRITE CODE OUTSIDE OF THE if-then-end SECTIONS BELOW!! (unless the code is a function definition)
//不要在这里书写代码,除非是定义一个函数(或者全局变量,xml串)
//你在这里写一个print(“hello world”)是不对的
if (sim_call_type==sim_childscriptcall_initialization) then
//如果脚本初始化
    -- Put some initialization code here
    //初始化
    -- Make sure you read the section on "Accessing general-type objects programmatically"
    -- For instance, if you wish to retrieve the handle of a scene object, use following instruction:
    //举例,如果你想得到一个目标的handle(句柄),使用如下代码
    -- handle=simGetObjectHandle('sceneObjectName')
    //看函数意思就能理解
    -- Above instruction retrieves the handle of 'sceneObjectName' if this script's name has no '#' in it
    //上面的指令会检索'sceneObjectName'
    -- If this script's name contains a '#' (e.g. 'someName#4'), then above instruction retrieves the handle of object 'sceneObjectName#4'
    //如果脚本名字没有#……,复制场景的时候会默认把名字后面加上#N,N表示数字
    -- This mechanism of handle retrieval is very convenient, since you don't need to adjust any code when a model is duplicated!
    //处理handle非常方便,你复制模型的时候不用调整代码
    -- So if the script's name (or rather the name of the object associated with this script) is:
    --
    -- 'someName', then the handle of 'sceneObjectName' is retrieved
    -- 'someName#0', then the handle of 'sceneObjectName#0' is retrieved
    -- 'someName#1', then the handle of 'sceneObjectName#1' is retrieved
    -- ...
    //看看……理解
    -- If you always want to retrieve the same object's handle, no matter what, specify its full name, including a '#':

    -- handle=simGetObjectHandle('sceneObjectName#') always retrieves the handle of object 'sceneObjectName' 
    -- handle=simGetObjectHandle('sceneObjectName#0') always retrieves the handle of object 'sceneObjectName#0' 
    -- handle=simGetObjectHandle('sceneObjectName#1') always retrieves the handle of object 'sceneObjectName#1'
    -- ...
    --
    -- Refer also to simGetCollisionhandle, simGetDistanceHandle, simGetIkGroupHandle, etc.
    //其他gethandle相关的函数也是如此
    -- Following 2 instructions might also be useful: simGetNameSuffix and simSetNameSuffix
    //这两个函数的作用查询参考手册

end


if (sim_call_type==sim_childscriptcall_actuation) then
//如果主函数调用执行此脚本
    -- Put your main ACTUATION code here
//写上你的主执行代码
    -- For example:
    --
    -- local position=simGetObjectPosition(handle,-1)
    -- position[1]=position[1]+0.001
    -- simSetObjectPosition(handle,-1,position)
    //脚本调用一次,物体的移动0.001
end


if (sim_call_type==sim_childscriptcall_sensing) then
//调用传感器
    -- Put your main SENSING code here

end


if (sim_call_type==sim_childscriptcall_cleanup) then
//恢复
    -- Put some restoration code here

end

Theraded child script

-- Put some initialization code here

//初始化代码
//这里可以写hello world
-- Put your main loop here, e.g.:
//写你的主要循环代码
-- while simGetSimulationState()~=sim_simulation_advancing_abouttostop do
--     local p=simGetObjectPosition(objHandle,-1)
--     p[1]=p[1]+0.001
--     simSetObjectPosition(objHandle,-1,p)
--     simSwitchThread() -- resume in next simulation step
//下一次仿真step从这继续
-- end


-- Put some clean-up code here

//写一些清除代码

-- ADDITIONAL DETAILS:
//其它细节
-- -------------------------------------------------------------------------
-- If you wish to synchronize a threaded loop with each simulation pass,
//如果你想将线程和仿真过程同步
-- enable the explicit thread switching with 
--//显式声明线程转换
-- simSetThreadAutomaticSwitch(false)
--
-- then use
--
-- simSwitchThread()
--
-- When you want to resume execution in next simulation step (i.e. at t=t+dt)
//当你希望在下一个仿真step中继续时
-- simSwitchThread() can also be used normally, in order to not waste too much
//simSwitchThread()  不会浪费太多计算时间
-- computation time in a given simulation step
-- -------------------------------------------------------------------------

Jonit ctrl callback script
关节控制回调脚本

-- 1. PID parameter def:
if not PID_P then
    PID_P=0.1
    PID_I=0
    PID_D=0
end
//PID控制参数
-- 2. Clear some values when the dynamic joint calls this the first time (this can happen several times, if the joint is reset dynamically):
//当电机第一次调用这个脚本时,清除一些值(如果关节动力学复位,这可能会发生几次)
if init then
    pidCumulativeErrorForIntegralParam=0
end
//如果初始化设置累计误差为0
-- 3. Proportional part:
//积分部分
ctrl=errorValue*PID_P
-- 4. Integral part:
//比例部分
if PID_I~=0 then
    pidCumulativeErrorForIntegralParam=pidCumulativeErrorForIntegralParam+errorValue*dynStepSize
else
    pidCumulativeErrorForIntegralParam=0
end
ctrl=ctrl+pidCumulativeErrorForIntegralParam*PID_I
-- 5. Derivative part:
//微分部分
if not init then
    ctrl=ctrl+(errorValue-pidLastErrorForDerivativeParam)*PID_D/dynStepSize
end
pidLastErrorForDerivativeParam=errorValue
-- 6. Calculate the velocity needed to reach the position in one dynamic time step:
//在一个时间步长中计算到达该位置所需的速度
maxVelocity=ctrl/dynStepSize
if (maxVelocity>velUpperLimit) then
    maxVelocity=velUpperLimit
end
if (maxVelocity<-velUpperLimit) then
    maxVelocity=-velUpperLimit
end
forceOrTorqueToApply=maxForceTorque


-- Following data must be returned to V-REP:
//必须返回的值
return forceOrTorqueToApply,maxVelocity
//力矩和允许的最大速度
-- forceOrTorqueToApply: the maximum force/torque that the joint will be able to exert
-- maxVelocity: max. velocity allowed.

Main Script

-- This is the main script. The main script is not supposed to be modified,
//除非你够牛逼,否则不要手贱去修改
-- unless there is a very good reason to do it.
-- The main script is called at each simulation pass. Without main script,
-- there is no real simulation (child scripts are not called either in that case).
//每一个仿真过程中,主脚本都被调用,没有主脚本,其他都是虚的
-- A main script marked as "default" (this is the default case) will use the
-- content of following file: system/dltmscpt.txt. This allows your old simulation
-- scenes to be automatically also using newer features, without explicitely coding
-- them. If you modify the main script, it will be marked as "customized", and you
-- won't benefit of that automatic forward compatibility mechanism. 
//这允许您的旧模拟场景自动地使用更新的特征,而不显式地编码它们。
//如果修改主脚本,它将被标记为“自定义”,并且不会受益于自动前向兼容机制。
//上面读不懂很正常
-- DO NOT WRITE CODE OUTSIDE OF THE if-then-end SECTIONS BELOW!! (unless the code is a function definition)
//还是那句话
-- Initialization part (executed just once, at simulation start) ---------
if (sim_call_type==sim_mainscriptcall_initialization) then
    simHandleSimulationStart()
    simOpenModule(sim_handle_all)
    simHandleGraph(sim_handle_all_except_explicit,0)
end
---------------------------------------------------------------

-- Regular part (executed at each simulation step) -----------------------
if (sim_call_type==sim_mainscriptcall_regular) then
    -- "Actuation"-part --
    simResumeThreads(sim_scriptthreadresume_default)


    -- "Sensing"-part --
    simHandleSensingStart()

    simHandleGraph(sim_handle_all_except_explicit,simGetSimulationTime()+simGetSimulationTimeStep())
end
--------------------------------------------------------------------------

-- Clean-up part (executed just once, before simulation ends) ------------
if (sim_call_type==sim_mainscriptcall_cleanup) then
    simResetMilling(sim_handle_all)
   ……
end
--------------------------------------------------------------------------

-- By default threaded child scripts switch back to the main thread after 2 ms. The main
-- thread switches back to a threaded child script at one of above's "simResumeThreads"
-- location
//默认,线程子脚本在2毫秒后切换回主线程,
//主线程通过上面的函数又切到子脚本

手册例子

//看格式知道这是non-threaded的
if (sim_call_type==sim_childscriptcall_initialization) then
    sensorHandleFront=simGetObjectHandle("DoorSensorFront")
    sensorHandleBack=simGetObjectHandle("DoorSensorBack")
    //DoorSensorFront是距离传感器的名字,设置两个传感器的handle
    motorHandle=simGetObjectHandle("DoorMotor")
    //设置控制门的电机的handle
    //add了一个joint叫DoorMotor,想要在脚本中对它操作,必须先获得handle,
//可以理解为指针或者引用
end

if (sim_call_type==sim_childscriptcall_actuation) then
    resF=simReadProximitySensor(sensorHandleFront) 
    resB=simReadProximitySensor(sensorHandleBack)
    if ((resF>0)or(resB>0)) then
        simSetJointTargetVelocity(motorHandle,-0.2)
    else
        simSetJointTargetVelocity(motorHandle,0.2)
    end
end
//如果传感器检测到了,那么设置电机速度
if (sim_call_type==sim_childscriptcall_sensing) then

end

if (sim_call_type==sim_childscriptcall_cleanup) then
    -- Put some restoration code here
end

下面是Joint control callback scripts

-- Following data is handed over from V-REP:
//下面的变量由Vrep传递
init,revolute,cyclic,jointHandle,passCnt,totalPasses,currentPos,targetPos,errorValue,
effort,dynStepSize,lowLimit,hightLimit,targetVel,maxForceTorque,velUpperLimit=...

-- init: true when this callback is called for the first time (if the joint is
--     dynamically reset during the simulation, this might be true more often)
//第一次调用时为真,关节被复位会多次设置为真,也就是重新call它
-- revolute: true if the joint is revolute
-- cyclic: true if the joint is revolute and cyclic (i.e. no lower/upper limits)
//关节类型
-- passCnt: the current dynamics calculation pass. 0-9 by default. See next
--     item for details.
//动力学计算间隔
-- totalPasses: the number of dynamics calculation passes for each "regular"
--     simulation pass. 10 by default (i.e. 10*5ms=50ms which is the default
--     simulation time step)
//每一步仿真中它会被调用十次
-- currentPos: the current position of the joint
//关节现在的位置
-- targetPos: the desired position of the joint
//关节目标位置
-- errorValue: targetPos-currentPos (with revolute cyclic joints we take the
--     shortest cyclic distance)
//差值:即目标位置和当前位置的相差距离
-- effort: the last force or torque that acted on this joint along/around its axis.
--     With Bullet, torques from joint limits are not taken into account
//最终绕转动轴的力矩,在Bullet中不考虑极限
-- dynStepSize: the step size used for the dynamics calculations (by default 5ms)
//动力学仿真计算步长,默认是5ms
-- lowLimit: the joint lower limit
-- highLimit: the joint upper limit
//关节位置上下限度
-- targetVel: the joint target velocity (as set in the user interface)
//目标速度
-- maxForceTorque: the joint maximum force/torque (as set in the user interface)
//最大力矩
-- velUpperLimit: the joint velocity upper limit (as set in the user interface)
//速度上限
-- The control happens here:
-- 1. PID parameter def:
if not PID_P then
    PID_P=0.1
    PID_I=0
    PID_D=0
end
//采用比例控制
-- 2. Clear some values when the dynamic joint calls this the first time
(this can happen several times, if the joint is reset dynamically):
if init then
    pidCumulativeErrorForIntegralParam=0
end
//累计误差归0
-- 3. Proportional part:
ctrl=errorValue*PID_P
//根据位置差值设置ctrl
-- 4. Integral part:
if PID_I~=0 then
    pidCumulativeErrorForIntegralParam=pidCumulativeErrorForIntegralParam+errorValue*dynStepSize
    //累计误差
else
    pidCumulativeErrorForIntegralParam=0
end
ctrl=ctrl+pidCumulativeErrorForIntegralParam*PID_I
-- 5. Derivative part:
if not init then
    ctrl=ctrl+(errorValue-pidLastErrorForDerivativeParam)*PID_D/dynStepSize
end
pidLastErrorForDerivativeParam=errorValue
-- 6. Calculate the velocity needed to reach the position in one dynamic time step:
velocityToApply=ctrl/dynStepSize
//关节速度根据ctrl调整
if (velocityToApply > velUpperLimit) then
    velocityToApply=velUpperLimit
end
if (velocityToApply < -velUpperLimit) then
    velocityToApply=-velUpperLimit
end
forceOrTorqueToApply=maxForceTorque
//同上面的原始代码
-- Following data must be returned to V-REP:
return forceOrTorqueToApply,velocityToApply

-- forceOrTorqueToApply: the maximum force/torque that the joint will be able to exert
-- velocityToApply: the velocity to apply to the joint.

猜你喜欢

转载自blog.csdn.net/danieldingshengli/article/details/80601889
今日推荐