V-rep學習筆記:轉動關節2


  Torque or force mode: in this mode, the joint is simulated by the dynamics module, if and only if it is dynamically enabled. When dynamically enabled, a joint can be free or controlled in Force/torque, in velocity or in position.

  The differentiation comes from the fact that a joint that operates in force/torque mode will be handled by the physics engine. And the physics engine will perform by default 10 times more calculation steps than the simulation loop: the simulation loop runs at 20Hz (in simulation time), while the physics engine runs at 200Hz (also in simulation time). That default behaviour can entirely be configured if required。If the joint is not in force/torque mode: if the joint is not in force/torque mode, then you can directly (and instantaneously) set its position via the simSetJointPosition API function. 

  建立如下圖所示的旋轉模型:

  在轉動關節的Joint Dynamic Properties對話框中勾選Control loop enable選項可以進行關節的位置控制(默認使用內置的PID控制器)。Target position為設定的目標位置(角度),Upper velocity limit為關節運動過程中允許的最大角速度,如果超過這個角速度則被限制為該值。

  PID控制器將比例、積分、微分通過線性組合構成控制量,動態方程為:

  PID控制器的離散化表達式為:

$$u(k)=K_pe(k)+K_iTe(k)+\frac{K_d}{T}[e(k)-e(k-1)]$$

  式中,T為采樣周期,k為采樣序號,Kp為比例系數,Ki為積分系數,Kd為微分系數

  比例控制能提高系統的動態響應速度,迅速反應誤差,從而減小誤差,但比例控制不能消除穩態誤差。$K_p$的加大,會引起系統的不穩定;積分控制的作用是消除穩態誤差,因為系統只要存在誤差,積分作用就不斷地積累,輸出控制量,直到偏差為零,積分作用才會停止。但積分作用太強會使系統超調加大,甚至使系統出現振盪。微分作用可以在產生誤差之前一發現有產生誤差的趨勢就開始調節,提前進行控制,所以及時性更好,可以最大限度地減少動態誤差。但微分作用只能作為比例和積分控制的一種補充,不能起主導作用,微分作用太強也會使系統出現不穩定,微分作用只能在P和I調好后再由小往大調,一點一點試着加上去。

   下面設10°為期望位置,PID參數設為0.1, 2, 0,仿真1s關節角度曲線如下圖所示:

  可以試着改變參數看看不同的效果,下圖是使用默認參數0.1,0,0,即只使用比例控制的結果。可以看出增大積分項確實會引起超調

  將比例系數設為1后結果如下圖,可以看出到達目標位置的時間比Kp=0.1時要快很多,可以看出增大比例系數可以加快響應速度。


  如果勾選Custom control選項,關節就會按照joint control callback script中用戶編寫的控制規律進行控制。This allows the user to write very specific joint controllers, that will be executed at each physics engine simulation step.

  callback script腳本通常用於一些底層控制,VREP中分為3種:

  • the contact callback script: the contact callback script lets you handle in a customized way each dynamic contact generated by the physics engine when two respondable objects collide.
  • joint control callback scripts: a joint control callback script lets you write customized low-level controllers for joints that are dynamically enabled.
  • the general callback script: each scene can have a general callback script that will be in charge of handling multi-purpose callback calls.

  這些腳本有如下特點:

  • a callback script always runs non-threaded.
  • a callback script might be called more than once for each simulation step.
  • a callback script handles low-level control items that the user wishes to customize. They should execute as quickly as possible, to avoid slowing down a simulation (this is particularly true for the contact callback script).

  Joint control callback scripts, which are simulation scripts, can be enabled via the joint dynamics properties dialog. When enabled for a given joint (that must be dynamically enabled), then the physics engine will call the callback script with appropriate arguments, allowing the user to customize the control loop of the related joint in order to write low-level control algorithms for specific joints. The joint control callback script might be called quite often, normally 10 times per simulation step for a given joint (remember that the physics engine time step, by default, is 10 times smaller that the simulation time step). For that reason, keep things simple, in order to avoid slowing down the simulation. Following represents a simple PID joint control callback script:

  打開關節控制腳本,默認進行PID控制,我們可以根據需要進行修改。代碼中pidCumulativeErrorForIntegralParam變量用於存儲積分項的累加值,如果是第一次調用控制腳本(init值為true)則將其初始化為0;dynStepSize與上面公式中的采樣周期T意義相同;用於計算控制量的誤差errorValue=targetPos-currentPos,那么與PID參數相乘后得到的控制量ctrl為位置量,如果要控制速度來使關節達到目標位置,則應施加的速度控制量為:velocityToApply=ctrl/dynStepSize

-- This example script performs a PID control
-- Be very careful when calling V-REP API functions from here:
-- 1. This routine gets called often, so it might slow down simulation (this is called at each dynamic simulation step, by default 10x more often than a child script)
-- 2. Some API functions are not meant to be called from here

-- Following data is handed over from V-REP:
init,revolute,cyclic,jointHandle,passCnt,totalPasses,currentPos,targetPos,errorValue,effort,dynStepSize,lowLimit,highLimit,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)
-- 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
-- dynStepSize: the step size used for the dynamics calculations (by default 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
-- 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:
velocityToApply=ctrl/dynStepSize
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.

  注意Lua函數可以接受可變數目的參數,在函數參數列表中使用三點(...)表示函數有可變的參數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM