vrep的bubbeRob模擬機器人制作教程
1. 構造基礎模型
-
新增bubbleRob的主體。點選 Menu bar --> Add --> Primititive shape --> Sphere,新增一個球體(以下稱為bubbleRob),並將X-size設定為0.2。
-
設定bubbleRob的動態屬性。雙擊bubbleRob,開啟動態屬性設定對話方塊,勾選Body is respondable和Body is dynamic。bubbleRob將對外界的碰撞作出動作和迴應。同時在Common選項卡中,勾選Collidable, Measurable, Detecable, Renderable。
-
移動bubbleRob位置。將bubbleRob沿Z軸上移動2cm(因為後面要安裝輪子),開啟position
-
加入距離感測器。點選Menu bar --> Add --> Proximity sensor --> Cone type,開啟orientation對話方塊,在Around Y和Around Z上輸入90。開啟position對話方塊,選擇position選項卡,在X-coord和Z-coord上輸入0.1和0.12。
-
設定距離感測器的探測距離。雙擊新增的Proximity sensor(以下稱為bubbleRob_sencingNose),點選Show volume parameters
-
將bubbleRob_sencingNose安裝到bubbleRob上。先在Scene hierachy上點選bubbleRob_sencingNose,然後按住Ctrl,再點選bubbleRob,最後點選Menu bar --> Edit --> Make last selected object parent 。
-
構建輪子。可以新開一個介面,Menu bar --> File --> New Scene,在這個介面上構建好輪子模型後,再複製回去。新增一個圓柱體(cylinder),設定尺寸為(0.08, 0.08, 0.02)。同時將輪子設定為Collidable
-
安裝輪子。需要先給左(右)輪子安裝傳動軸(電機)。點選Menu bar --> Add --> Joint --> Revolute。需要將傳動軸安轉在輪子的中心點。首先選中輪子,然後按住Ctrl,再選中傳動軸。 (電機),開啟position對話方塊,在position選項卡中,點選Apply to selection;在orientation對話方塊的orientation選項卡中,也點選Apply to selection。然後在Scene hierarchy中,雙擊傳動軸,點選Show dynamic parameters,選中enable the motor和Lock motor when target velocity is zero。同樣對另外一個輪子做同樣的工作。最後就是將輪子固定在傳動軸上,然後將兩個傳動軸固定到bubbleRob上。
-
構建後輪。如果沒有後輪,執行模擬的時候,機器人是往後倒的。同樣在新建場景中,新增一個球體(以下稱為bubbleRob_slider),設定半徑為0.05,動態屬性設定為Collidable, Measurable, Renderable, Detecable。然後將bubbleRob_silder的材料摩擦力設定為0。
-
固定後輪。為了將bubbleRob_silder固定在bubbleRob上,需要新增一個力感測器,點選Menu bar --> Add --> Force sencor,新增一個力感測器(以下稱為bubbleRob_connection)。設定position為(-0.07, 0, 0.05),將bubbleRob_silder繫結在bubbleRob_connection上,然後複製回前一個場景,將bubbleRob_connection繫結在bubbleRob上。如果這時開啟模擬,就會發現後輪迅速彈開,這是因為bubbleRob_silder和bubbleRob之間存在接觸,模擬軟體vrep認為它們之間存在碰撞。解決辦法是在它們的動態屬性對話方塊中,設定響應掩碼。將bubbleRob_silder的掩碼(local respondable mask)設定為00001111,將bubbleRob的掩碼設定為11110000。這時再執行模擬就不會出現後輪彈開的現象了。但是還會有小幅度的滑動現象,這是由於模擬引擎和質量慣性的原因。在動態屬性框中將三個輪子的質量和慣性因子設定成8倍,即點選三次M=M * 2(for selection)和I=I * 2(for selection)。
-
執行模擬。設定兩個傳動軸的速度為50。
2.建立距離感測器、視覺感測器
- 建立集合(collection)。為了將整個bubbleRob機器人當成一個整體,需要將bubbleRob全部零件設定為一個集合。點選 Menu bar --> Tools --> Collections開啟對話方塊。或者單擊下列圖示:
- 將bubbleRob設定為集合。點選Add new collection,然後在左側列表中選中bubbleRob,點選Add。點選Visualize selected collection可以檢視集合中的元素。
- 新增距離感測器。點選 Menu bar --> Tools --> Calculation module properties,也可以點選下列圖示: 在對話方塊中,點選Add new distance object,然後選擇檢測目標(bubbleRob_collection是上面的colleciton,已改名)和被檢查目標(其他所有物體)。點選OK後,將這個物件重新命名為bubbleRob_distance,對於後面的繪圖有幫助。
- 新增繪圖物件。點選Menu bar --> Add --> Graph,然後將繪圖物件重新命名為bubbleRob_graph。將繪圖物件繫結在bubbleRob上。 接著調整graph的座標為(0, 0, 0.005),雙擊graph設定屬性,取消Display XYZ-planes,然後點選 Add new data stream to record,Data stream type選擇Object absolute x-position,Object / items to record選擇bubbleRob_graph。這樣我們便可以記錄bubbleRob實時的x座標值。同理也對Y軸和Z軸進行同樣的設定。另外,為了顯示bubbleRob到其他物體的距離,點選 Add new data stream to record,Data stream type選擇Distance: segment length,Object / items to record選擇bubbleRob_distance。最後重新命名這些資料流(雙擊重新命名)。如下圖。 可以在Time graph properties屬性框中改變資料流線條的顏色和是否顯示(取消勾選Visible則不顯示)。
- 設定bubbleRob的3D運動軌跡。同樣在graph的屬性框中,點選Edit 3D curves,開啟軌跡對話方塊,點選Add new curve,XYZ值分別對應bubbleRob_x_pos, bubbleRob_y_pos, bubbleRob_z_pos,勾選Relative to world,設定參考系為世界座標系,然後輸入Curve width為4。
- 新增障礙物。加入半徑為0.1m, 高度為0.2m的圓柱體,然後可以使用Ctrl+C和Ctrl+V進行批量複製。可以按住Shift,再按住滑鼠左鍵進行多選。先按住滑鼠左鍵,再按住Shift可以進行微小調整。先按住滑鼠左鍵,再按住Ctrl可以在Z軸進行調整。
- 定義模組。如果我們想點選某個零件時,選中的是整個bubbleRob,或者是複製bubbleRob主體時,粘貼出來的bubbleRob也包含全部零件,或者防止不小心拖動某個零件導致錯位,可以將bubbleRob的整體定義為一個模組。首先開啟bubbleRob主體的屬性框,在common屬性項中,勾選Object is model base和Object/model can transfer or accept DNA。 第一項的作用是儲存或複製某個物件時,會同時儲存或複製它的所有子物件。第二項的作用是修改某個物件時,可以通過DNA transfer toolbar button將所有修改複製到該物件的所有副本。該按鈕如下所示。 然後將兩個轉動軸(關節)和距離感測器還有繪圖物件不要顯示在模組的框框中。同樣是在屬性框的common屬性項中,勾選Ignored by model bounding box,對比圖如下所示,左側是沒有勾選之前的,右側是勾選之後的。 為了隱藏在轉動軸和聯結器這些小零件,可以兩個轉動軸和聯結器的camera visibility layer勾選第10層,取消第2層。預設情況下第9-16層是不顯示的,因此設定之後它們會在場景中隱藏起來。 為了單擊小零件時,自動選中bubbleRob主體,將兩個輪子、滑塊、感測器和繪圖物件勾選上Select base of model instead。如果確實想只選中小零件,可以按住Ctrl+Shift,再點選小零件。也可以在左側列表中選中。
- 增加視覺感測器。點選 Menu bar --> Add --> Vision sensor --> Perspective type,然後將視覺感測器繫結在距離感測器上,將位置座標為relative(0,0,0),同理將旋轉角度也設定為relative(0, 0, 0)。同時隱藏視覺感測器,通過勾選Select base of model instead和Ignored by model bounding box。最後,在視覺感測器的屬性框中,將Far clipping plane設定為1,Resolution x和Resolution y都設定為256。前者是設定最遠檢測距離,後者是設定解析度。
- 新增濾波器。開啟Show filter dialog,在下拉框中選擇Edge detection on work image,然後點選Add filter。成功新增Edge detection on work imagel濾波器後,點選上移圖示,將濾波器移動至第二個位置。最後雙擊濾波器將閾值修改為0.2。
建立指令碼控制bubbleRob
- 只有在編寫指令碼後,bubbleRob才等於有了生命。在左側列表中右鍵bubbleRob,點選Menu bar --> Add --> Associated child script --> Non threaded,建立一個指令碼,這是bubbleRob圖示的旁邊會出現一個“小紙張”的圖案, 雙擊進去即可編寫Lua指令碼。下面是一個例項指令碼:
function speedChange_callback(ui,id,newVal)
speed=minMaxSpeed[1]+(minMaxSpeed[2]-minMaxSpeed[1])*newVal/100
end
function sysCall_init()
-- This is executed exactly once, the first time this script is executed
bubbleRobBase=sim.getObjectAssociatedWithScript(sim.handle_self) -- this is bubbleRob's handle
leftMotor=sim.getObjectHandle("bubbleRob_leftMotor") -- Handle of the left motor
rightMotor=sim.getObjectHandle("bubbleRob_rightMotor") -- Handle of the right motor
noseSensor=sim.getObjectHandle("bubbleRob_sensingNose") -- Handle of the proximity sensor
minMaxSpeed={50*math.pi/180,300*math.pi/180} -- Min and max speeds for each motor
backUntilTime=-1 -- Tells whether bubbleRob is in forward or backward mode
-- Create the custom UI:
xml = '<ui title="'..sim.getObjectName(bubbleRobBase)..' speed" closeable="false" resizeable="false" activate="false">'..[[
<hslider minimum="0" maximum="100" onchange="speedChange_callback" id="1"/>
<label text="" style="* {margin-left: 300px;}"/>
</ui>
]]
ui=simUI.create(xml)
speed=(minMaxSpeed[1]+minMaxSpeed[2])*0.5
simUI.setSliderValue(ui,1,100*(speed-minMaxSpeed[1])/(minMaxSpeed[2]-minMaxSpeed[1]))
end
function sysCall_actuation()
result=sim.readProximitySensor(noseSensor) -- Read the proximity sensor
-- If we detected something, we set the backward mode:
if (result>0) then backUntilTime=sim.getSimulationTime()+4 end
if (backUntilTime<sim.getSimulationTime()) then
-- When in forward mode, we simply move forward at the desired speed
sim.setJointTargetVelocity(leftMotor,speed)
sim.setJointTargetVelocity(rightMotor,speed)
else
-- When in backward mode, we simply backup in a curve at reduced speed
sim.setJointTargetVelocity(leftMotor,-speed/2)
sim.setJointTargetVelocity(rightMotor,-speed/8)
end
end
function sysCall_cleanup()
simUI.destroy(ui)
end
最後可以通過點選 Menu bar --> Tools --> Scripts或者下面的圖示來對當前場景全部指令碼進行管理。