V-rep Hexapod tutorial(2)

V-rep Hexapod tutorial(2)

1.添加用户参数User Parameters
(1)给hexa_body添加Non-threaded script
V-rep Hexapod tutorial(2)
(2)hexa_body的脚本代码中插如如下代码并运行

	function sysCall_init()
    	Base=sim.getObjectHandle('hexa_body')
    	sim.setUserParameter(Base,'@enable','')
	end

(3)点击运行
运行后在hexa_body获得如下图标,双击可打开用户参数对话框
V-rep Hexapod tutorial(2)
(4)添加用户参数

Name Value Unit
stepVelocity 0.5 1/s
stepAmplitude 0.16 m
stepHeight 0.04 m
movementDirection 0 degrees
rotationMode 0 -1: CCW, 1: CW, 0: no rotation
movementStrength 0 0-1

V-rep Hexapod tutorial(2)
2.打开动力学
V-rep Hexapod tutorial(2)
3.设置参数
(1)设置六条腿的第二个和第三个关节的位置为0,让六个脚能搭在地面上
V-rep Hexapod tutorial(2)
4.代码理解
(1)hexapod的脚本
线程子脚本,只运行一次,运动前机身的“热身动作”

//这个线程脚本(threaded)是六足动物的主控制脚本。它产生身体运动并进行控制
//另一个非线程脚本(non-threaded),负责生成行走运动
//另一个脚本是通过仿真参数控制的:这个脚本写入参数(sim.setScriptSimulationParamete)
//并且另一个脚本读取参数(sim.getScriptSimulationParameter)

//----------------------------函数setStepMode:设置用户参数里的六个值-----------------------//
setStepMode=function(stepVelocity,stepAmplitude,stepHeight,movementDirection,rotationMode,movementStrength)
    sim.setScriptSimulationParameter(sim.handle_tree,'stepVelocity',stepVelocity)
    sim.setScriptSimulationParameter(sim.handle_tree,'stepAmplitude',stepAmplitude)
    sim.setScriptSimulationParameter(sim.handle_tree,'stepHeight',stepHeight)
    sim.setScriptSimulationParameter(sim.handle_tree,'movementDirection',movementDirection)
    sim.setScriptSimulationParameter(sim.handle_tree,'rotationMode',rotationMode)
    sim.setScriptSimulationParameter(sim.handle_tree,'movementStrength',movementStrength)
end
//-------------------------函数moveBody:让机身在原地运动(各个方向旋转)----------------------//
moveBody=function(index)
	//获得当前的目标位置和角度(3个方向)
    local p={initialP[1],initialP[2],initialP[3]}
    local o={initialO[1],initialO[2],initialO[3]}
    //把腿部和机身移动到给定的位置和方向(实际在第一次运行时该行代码不动)
    sim.moveToPosition(legBase,antBase,p,o,vel,accel)
    //输入的索引为0:腿部不动,机身抬起h后下落h
    if (index==0) then
        //机身抬起,速度加倍
        p[3]=p[3]-0.03*sizeFactor
        sim.moveToPosition(legBase,antBase,p,o,vel*2,accel)
        //机身下落,速度加倍
        p[3]=p[3]+0.03*sizeFactor
        sim.moveToPosition(legBase,antBase,p,o,vel*2,accel)
    end
    //输入的索引为1:4次弯曲【twisting】
    if (index==1) then
        o[1]=o[1]+5*math.pi/180
        o[2]=o[2]-05*math.pi/180
        o[3]=o[3]-15*math.pi/180
        p[1]=p[1]-0.03*sizeFactor
        p[2]=p[2]+0.015*sizeFactor
        sim.moveToPosition(legBase,antBase,p,o,vel,accel)
        o[1]=o[1]-10*math.pi/180
        o[3]=o[3]+30*math.pi/180
        p[2]=p[2]-0.04*sizeFactor
        sim.moveToPosition(legBase,antBase,p,o,vel,accel)
        o[1]=o[1]+10*math.pi/180
        o[2]=o[2]+10*math.pi/180
        p[2]=p[2]+0.03*sizeFactor
        p[1]=p[1]+0.06*sizeFactor
        sim.moveToPosition(legBase,antBase,p,o,vel,accel)
        o[1]=o[1]-10*math.pi/180
        o[3]=o[3]-30*math.pi/180
        p[2]=p[2]-0.03*sizeFactor
        sim.moveToPosition(legBase,antBase,p,o,vel,accel)
    end
    //输入的索引为2:绕着x轴旋转三次:17,-34,17【rolling】
    if (index==2) then
        p[3]=p[3]-0.0*sizeFactor
        o[1]=o[1]+17*math.pi/180
        sim.moveToPosition(legBase,antBase,p,o,vel,accel)
        o[1]=o[1]-34*math.pi/180
        sim.moveToPosition(legBase,antBase,p,o,vel,accel)
        o[1]=o[1]+17*math.pi/180
        p[3]=p[3]+0.0*sizeFactor
        sim.moveToPosition(legBase,antBase,p,o,vel,accel)
    end
    //输入的索引为3:绕着y轴旋转三次:15,-30,15【pitching】
    if (index==3) then
        -- pitching
        p[3]=p[3]-0.0*sizeFactor
        o[2]=o[2]+15*math.pi/180
        sim.moveToPosition(legBase,antBase,p,o,vel,accel)
        o[2]=o[2]-30*math.pi/180
        sim.moveToPosition(legBase,antBase,p,o,vel,accel)
        o[2]=o[2]+15*math.pi/180
        p[3]=p[3]+0.0*sizeFactor
        sim.moveToPosition(legBase,antBase,p,o,vel,accel)
    end
    //输入的索引为4:绕着z轴旋转三次:30,-60,30【yawing】
    if (index==4) then
        p[3]=p[3]+0.0*sizeFactor
        o[3]=o[3]+30*math.pi/180
        sim.moveToPosition(legBase,antBase,p,o,vel,accel)
        o[3]=o[3]-60*math.pi/180
        sim.moveToPosition(legBase,antBase,p,o,vel,accel)
        o[3]=o[3]+30*math.pi/180
        sim.moveToPosition(legBase,antBase,p,o,vel,accel)
        p[3]=p[3]-0.0*sizeFactor
        sim.moveToPosition(legBase,antBase,p,o,vel,accel)
    end
end
//---------------------------------------线程子脚本的主要函数----------------------------------//
function sysCall_threadmain()
	//获得机身的目标Dummy
    antBase=sim.getObjectHandle('hexa_base')
    //获得足部的目标Dummy,hexa_legBase下包含六条腿的目标Dummy
    legBase=sim.getObjectHandle('hexa_legBase')
    //检索场景对象的大小因子。尺寸因子与真实物体的大小不同。使用此功能可以对伸缩操作做出反应。
    sizeFactor=sim.getObjectSizeFactor(antBase)
    //物体移动的速度
    vel=0.05
    //物体移动的角速度
    accel=0.05
    //物体移动的目标位置targetPosition
    initialP={0,0,0}
    //物体移动的目标角度targetOrientation
    initialO={0,0,0}
    //设置物体初始先腿不动,机身向上移动,因此只改变targetPosition的z分量(注意,此时sizeFactor为1,initialP[3]为负,机身向上移动,[1]和[2]都是正负和x、y轴的正方形对应)
    initialP[3]=initialP[3]-0.03*sizeFactor
    //将对象移动到给定的位置和方向
    sim.moveToPosition(legBase,antBase,initialP,initialO,vel,accel)
	
    stepHeight=0.02*sizeFactor
    maxWalkingStepSize=0.11*sizeFactor
    walkingVel=0.9

    //原地移动旋转
    //设置六个参数:步速(1/s)、步幅(m)、步距(m)、运动方向(degrees)、转动模式(-1: CCW, 1: CW, 0: no rotation)、运动强度(0-1)
    setStepMode(walkingVel,maxWalkingStepSize,stepHeight,0,0,0)
    moveBody(0)
    moveBody(1)
    moveBody(2)
    moveBody(3)
    moveBody(4)
    
	//保持身体固定的姿势向前走
    setStepMode(walkingVel,maxWalkingStepSize,stepHeight,0,0,1)
    //线程等待
    sim.wait(12)
    for i=1,27,1 do
        setStepMode(walkingVel,maxWalkingStepSize,stepHeight,10*i,0,1)
        sim.wait(0.5)
    end
    //停止
    setStepMode(walkingVel,maxWalkingStepSize,stepHeight,270,0,0)
    sim.wait(2)

    //向前走,同时改变身体姿势
    setStepMode(walkingVel,maxWalkingStepSize*0.5,stepHeight,0,0,1)
    moveBody(0)
    moveBody(1)
    moveBody(2)
    moveBody(3)
    moveBody(4)
    //停止
    setStepMode(walkingVel,maxWalkingStepSize*0.5,stepHeight,0,0,0)
    sim.wait(2)

    //原地旋转
    setStepMode(walkingVel,maxWalkingStepSize*0.5,stepHeight,0,1,1)
    sim.wait(24)
    -- Stop:
    setStepMode(walkingVel,maxWalkingStepSize*0.5,stepHeight,0,0,0)
end

(2)hexa_body的脚本
非线程子脚本,这个脚本负责移动腿来行走
本质上,是通过每次调用线程时,赋予p不同的位置,再赋予给不同的腿来实现

//----------------------------------非线程子脚本的初始化函数----------------------------------//
function sysCall_init() 
	//获得六条腿的目标Dummy的中心
    antBase=sim.getObjectHandle('hexa_legBase')
    //获得六条腿的尖端和目标Dummy
    legTips={-1,-1,-1,-1,-1,-1}
    legTargets={-1,-1,-1,-1,-1,-1}
    for i=1,6,1 do
        legTips[i]=sim.getObjectHandle('hexa_footTip'..i-1)
        legTargets[i]=sim.getObjectHandle('hexa_footTarget'..i-1)
    end
    //获取六条腿的尖端的位置(相对于平面中心)
    //sim.getObjectPosition(objectHandle,relativeToObjectHandle)
    //参数objectHandle:对象的句柄
    //参数relativeToObjectHandle:表示相对于我们想要的参考框架的位置。
   	 	//指定-1来获取绝对位置,指定sim.handle_parent来获取相对于对象父体的位置,或者指定相对于我们想要的参考框架的对象句柄。
    	//如果这个句柄是一个关节的句柄,那么将返回相对于该关节移动框架的位置(除非objectHandle与sim.handleflag_reljointbaseframe相结合,在这种情况下,将返回相对于该关节基本框架的位置)。
    initialPos={nil,nil,nil,nil,nil,nil}
    for i=1,6,1 do
        initialPos[i]=sim.getObjectPosition(legTips[i],antBase)
    end
    //腿部移动顺序
    legMovementIndex={1,4,2,6,3,5}
    //六个用户参数
    stepVelocity=0.5
    stepAmplitude=0.16
    stepHeight=0.04
    movementDirection=0*math.pi/180
    rotation=0
    movementStrength=1
    
    stepProgression=0    
    realMovementStrength=0       
end
//-----------------------------------非线程子脚本的恢复函数-----------------------------------//
function sysCall_cleanup() 
end 
//-----------------------------非线程子脚本的主要函数:驱动函数-----------------------------//
function sysCall_actuation() 
	//检索仿真时间步长(在每个主脚本仿真过程中所经过的仿真时间(即不是实时的))
	//这个值对于一个特定的模拟来说可能不是恒定的。
    dt=sim.getSimulationTimeStep()
    //获得六个用户参数
    stepVelocity=sim.getScriptSimulationParameter(sim.handle_self,'stepVelocity')
    stepAmplitude=sim.getScriptSimulationParameter(sim.handle_self,'stepAmplitude')
    stepHeight=sim.getScriptSimulationParameter(sim.handle_self,'stepHeight')    	
    movementDirection=math.pi*sim.getScriptSimulationParameter(sim.handle_self,'movementDirection')/180
    rotation=sim.getScriptSimulationParameter(sim.handle_self,'rotationMode')
    movementStrength=sim.getScriptSimulationParameter(sim.handle_self,'movementStrength')
	//dt为0.05,dx为目标movementStrength和实际realMovementStrength的差
    dx=movementStrength-realMovementStrength
    //如果差值大于0.05,dx=dt*0.5=0.025
    if (math.abs(dx)>dt*0.1) then
        dx=math.abs(dx)*dt*0.5/dx
    end
    //更新实际realMovementStrength
    realMovementStrength=realMovementStrength+dx
 	//对每条腿执行如下操作  
    for leg=1,6,1 do
        sp=(stepProgression+(legMovementIndex[leg]-1)/6) % 1
        offset={0,0,0}
        if (sp<(1/3)) then
            offset[1]=sp*3*stepAmplitude/2
        else
            if (sp<(1/3+1/6)) then
                s=sp-1/3
                offset[1]=stepAmplitude/2-stepAmplitude*s*6/2
                offset[3]=s*6*stepHeight
            else
                if (sp<(2/3)) then
                    s=sp-1/3-1/6
                    offset[1]=-stepAmplitude*s*6/2
                    offset[3]=(1-s*6)*stepHeight
                else
                    s=sp-2/3
                    offset[1]=-stepAmplitude*(1-s*3)/2
                end
            end
        end
        md=movementDirection+math.abs(rotation)*math.atan2(initialPos[leg][1]*rotation,-initialPos[leg][2]*rotation)
        offset2={offset[1]*math.cos(md)*realMovementStrength,offset[1]*math.sin(md)*realMovementStrength,offset[3]*realMovementStrength}
        p={initialPos[leg][1]+offset2[1],initialPos[leg][2]+offset2[2],initialPos[leg][3]+offset2[3]}
        //我们只是设定了想要的脚的位置。IK在那之后被隐式地处理(在默认的主脚本中)。你也可以用sim.handleIkGroup()来显式处理IK。
        sim.setObjectPosition(legTargets[leg],antBase,p) 
    end
    
    stepProgression=stepProgression+dt*stepVelocity
end 

上一篇:SystemVerilog Tutorial


下一篇:实现tms瓦片转mbtile