webots自學筆記(五)使用物理插件ODE建立鉸鏈


原創文章,來自博客園,_阿龍clliu http://www.cnblogs.com/clliu/,轉載請注明原文章出處。

 

      在一些三維制圖軟件或仿真軟件里,都有運動副的概念,webots的節點里好像沒有,不要擔心,在物理插件里可以做到,不過要學習有關於ODE(開源動力學引擎的)一些內容。在webots中,怎樣建立一個鉸鏈呢,我做了一個簡單的例子,小區門口的那種可以控制的欄桿,效果圖如下。

      那每一個桿件,它們的關系在怎么定義呢?其實關系是在ODE中定義的,我們只需要建立一些沒有約束關系的桿件就行。場景樹貼出在下面,雖然這些節點是以servo定義的,但是在不需要約束關系的桿件,例如連桿3,將type改成none,那么,桿件3與gan Robot的關系就不是servo關系了,在仿真中可以看成兩個零件。模型就不介紹怎么建立了,后面會給出整個仿真的文件。

         

 

     建立完模型之后,點擊菜單欄的  向導 —>新物理插件,代碼如下:

  1 //來自“博客園,_阿龍clliu” http://www.cnblogs.com/clliu/
  2 #include <ode/ode.h>
  3 #include <plugins/physics.h>
  4 
  5 
  6 
  7 dBodyID getBody(const char *def) {
  8   dBodyID body = dWebotsGetBodyFromDEF(def);
  9   if (! body) dWebotsConsolePrintf("Warning: did not find body with DEF name: %s", def);
 10   return body;
 11 }
 12 
 13 
 14 void webots_physics_init(dWorldID world, dSpaceID space, dJointGroupID contactJointGroup) {
 15 
 16    //得到桿件的ID
 17    dBodyID link1 = getBody("link1");
 18    dBodyID link2 = getBody("link2");
 19    dBodyID link3 = getBody("link3");
 20    dBodyID link4 = getBody("link4");
 21    dBodyID link5 = getBody("link5");
 22    dBodyID link6 = getBody("link6");
 23    
 24    //創建一個鉸鏈副
 25    dJointID hingeJoint = dJointCreateHinge(world, 0);
 26    //定義鉸鏈副約束的兩個零件,link1和link3
 27    dJointAttach(hingeJoint, link1, link3);
 28    
 29    //定義鉸鏈的作用點
 30    dVector3 hinge_interface;
 31    //將link1零件自身坐標系的(0,0,0)點轉為全局坐標系坐標,賦給hinge_interface
 32    dBodyGetRelPointPos(link1, 0, 0, 0, hinge_interface);
 33    
 34    //設置鉸鏈作用點
 35    dJointSetHingeAnchor(hingeJoint, hinge_interface[0], hinge_interface[1], hinge_interface[2]);
 36    //設置鉸鏈作用軸(作用方向)
 37    dJointSetHingeAxis(hingeJoint, 0, 0, 1);
 38    
 39    //link4?link3??
 40    hingeJoint = dJointCreateHinge(world, 0);
 41    dJointAttach(hingeJoint, link4, link3);
 42    
 43    dBodyGetRelPointPos(link4, 0, -0.05, 0, hinge_interface);
 44    
 45    dJointSetHingeAnchor(hingeJoint, hinge_interface[0], hinge_interface[1], hinge_interface[2]);
 46    dJointSetHingeAxis(hingeJoint, 0, 0, 1);
 47    
 48    //link5?link3??
 49    hingeJoint = dJointCreateHinge(world, 0);
 50    dJointAttach(hingeJoint, link5, link3);
 51    
 52    dBodyGetRelPointPos(link5, 0, -0.05, 0, hinge_interface);
 53    
 54    dJointSetHingeAnchor(hingeJoint, hinge_interface[0], hinge_interface[1], hinge_interface[2]);
 55    dJointSetHingeAxis(hingeJoint, 0, 0, 1);
 56    
 57    //link6?link3??
 58    hingeJoint = dJointCreateHinge(world, 0);
 59    dJointAttach(hingeJoint, link6, link3);
 60    
 61    dBodyGetRelPointPos(link6, 0, -0.05, 0, hinge_interface);
 62    
 63    dJointSetHingeAnchor(hingeJoint, hinge_interface[0], hinge_interface[1], hinge_interface[2]);
 64    dJointSetHingeAxis(hingeJoint, 0, 0, 1);
 65    
 66    //link4?link2??
 67    hingeJoint = dJointCreateHinge(world, 0);
 68    dJointAttach(hingeJoint, link4, link2);
 69    
 70    dBodyGetRelPointPos(link4, 0, 0.05, 0, hinge_interface);
 71    
 72    dJointSetHingeAnchor(hingeJoint, hinge_interface[0], hinge_interface[1], hinge_interface[2]);
 73    dJointSetHingeAxis(hingeJoint, 0, 0, 1);
 74    
 75    //link5?link2??
 76    hingeJoint = dJointCreateHinge(world, 0);
 77    dJointAttach(hingeJoint, link5, link2);
 78    
 79    dBodyGetRelPointPos(link5, 0, 0.05, 0, hinge_interface);
 80    
 81    dJointSetHingeAnchor(hingeJoint, hinge_interface[0], hinge_interface[1], hinge_interface[2]);
 82    dJointSetHingeAxis(hingeJoint, 0, 0, 1);
 83    
 84    //link6?link2??
 85    hingeJoint = dJointCreateHinge(world, 0);
 86    dJointAttach(hingeJoint, link6, link2);
 87    
 88    dBodyGetRelPointPos(link6, 0, 0.05, 0, hinge_interface);
 89    
 90    dJointSetHingeAnchor(hingeJoint, hinge_interface[0], hinge_interface[1], hinge_interface[2]);
 91    dJointSetHingeAxis(hingeJoint, 0, 0, 1);
 92 }
 93 
 94 void webots_physics_step() {
 95 
 96 }
 97 
 98 void webots_physics_draw() {
 99   
100 }
101 
102 int webots_physics_collide(dGeomID g1, dGeomID g2) {
103 
104   return 0;
105 }
106 
107 void webots_physics_cleanup() {
108 
109 }

     設置完成物理引擎,在worldInfo節點下physics節點下選擇該物理插件。控制器代碼如下:

 1 //來自“博客園,_阿龍clliu” http://www.cnblogs.com/clliu/
 2 #include <webots/robot.h>
 3 #include <webots/servo.h>
 4 #include <assert.h>
 5 #include <math.h>
 6 
 7 #define TIME_STEP 32
 8 #define rad_2_deg(X) ( X / pi * 180.0 )
 9 #define deg_2_rad(X) ( X / 180.0 * pi )
10 #define pi 3.1415926
11 #define frep 1
12 
13 int main(int argc, char **argv)
14 {
15 
16   double t = 0;
17   double servo_pos;
18   
19   
20   wb_robot_init();
21   
22   WbDeviceTag servo;
23   servo = wb_robot_get_device("link2");
24   assert(servo);
25   
26   while (wb_robot_step(TIME_STEP) != -1) {
27   
28     
29     servo_pos = 45 + 45 * sin(frep * t + pi);
30     wb_servo_set_position(servo,deg_2_rad(servo_pos));
31     
32     t += (double)TIME_STEP / 1000.0;
33   };
34   
35 
36   wb_robot_cleanup();
37   
38   return 0;
39 }

      如果沒有什么錯誤,就能實現之前GIF的效果了,如果沒做出來,也沒關系,給出原文件,仿真文件下載地址

     如果有什么疑問,歡迎再下方提問。

 


免責聲明!

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



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