原创文章,来自博客园,_阿龙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. dBodyID getBody(const char *def) {
  6. dBodyID body = dWebotsGetBodyFromDEF(def);
  7. if (! body) dWebotsConsolePrintf("Warning: did not find body with DEF name: %s", def);
  8. return body;
  9. }
  10.  
  11. void webots_physics_init(dWorldID world, dSpaceID space, dJointGroupID contactJointGroup) {
  12.  
  13. //得到杆件的ID
  14. dBodyID link1 = getBody("link1");
  15. dBodyID link2 = getBody("link2");
  16. dBodyID link3 = getBody("link3");
  17. dBodyID link4 = getBody("link4");
  18. dBodyID link5 = getBody("link5");
  19. dBodyID link6 = getBody("link6");
  20.  
  21. //创建一个铰链副
  22. dJointID hingeJoint = dJointCreateHinge(world, );
  23. //定义铰链副约束的两个零件,link1和link3
  24. dJointAttach(hingeJoint, link1, link3);
  25.  
  26. //定义铰链的作用点
  27. dVector3 hinge_interface;
  28. //将link1零件自身坐标系的(0,0,0)点转为全局坐标系坐标,赋给hinge_interface
  29. dBodyGetRelPointPos(link1, , , , hinge_interface);
  30.  
  31. //设置铰链作用点
  32. dJointSetHingeAnchor(hingeJoint, hinge_interface[], hinge_interface[], hinge_interface[]);
  33. //设置铰链作用轴(作用方向)
  34. dJointSetHingeAxis(hingeJoint, , , );
  35.  
  36. //link4?link3??
  37. hingeJoint = dJointCreateHinge(world, );
  38. dJointAttach(hingeJoint, link4, link3);
  39.  
  40. dBodyGetRelPointPos(link4, , -0.05, , hinge_interface);
  41.  
  42. dJointSetHingeAnchor(hingeJoint, hinge_interface[], hinge_interface[], hinge_interface[]);
  43. dJointSetHingeAxis(hingeJoint, , , );
  44.  
  45. //link5?link3??
  46. hingeJoint = dJointCreateHinge(world, );
  47. dJointAttach(hingeJoint, link5, link3);
  48.  
  49. dBodyGetRelPointPos(link5, , -0.05, , hinge_interface);
  50.  
  51. dJointSetHingeAnchor(hingeJoint, hinge_interface[], hinge_interface[], hinge_interface[]);
  52. dJointSetHingeAxis(hingeJoint, , , );
  53.  
  54. //link6?link3??
  55. hingeJoint = dJointCreateHinge(world, );
  56. dJointAttach(hingeJoint, link6, link3);
  57.  
  58. dBodyGetRelPointPos(link6, , -0.05, , hinge_interface);
  59.  
  60. dJointSetHingeAnchor(hingeJoint, hinge_interface[], hinge_interface[], hinge_interface[]);
  61. dJointSetHingeAxis(hingeJoint, , , );
  62.  
  63. //link4?link2??
  64. hingeJoint = dJointCreateHinge(world, );
  65. dJointAttach(hingeJoint, link4, link2);
  66.  
  67. dBodyGetRelPointPos(link4, , 0.05, , hinge_interface);
  68.  
  69. dJointSetHingeAnchor(hingeJoint, hinge_interface[], hinge_interface[], hinge_interface[]);
  70. dJointSetHingeAxis(hingeJoint, , , );
  71.  
  72. //link5?link2??
  73. hingeJoint = dJointCreateHinge(world, );
  74. dJointAttach(hingeJoint, link5, link2);
  75.  
  76. dBodyGetRelPointPos(link5, , 0.05, , hinge_interface);
  77.  
  78. dJointSetHingeAnchor(hingeJoint, hinge_interface[], hinge_interface[], hinge_interface[]);
  79. dJointSetHingeAxis(hingeJoint, , , );
  80.  
  81. //link6?link2??
  82. hingeJoint = dJointCreateHinge(world, );
  83. dJointAttach(hingeJoint, link6, link2);
  84.  
  85. dBodyGetRelPointPos(link6, , 0.05, , hinge_interface);
  86.  
  87. dJointSetHingeAnchor(hingeJoint, hinge_interface[], hinge_interface[], hinge_interface[]);
  88. dJointSetHingeAxis(hingeJoint, , , );
  89. }
  90.  
  91. void webots_physics_step() {
  92.  
  93. }
  94.  
  95. void webots_physics_draw() {
  96.  
  97. }
  98.  
  99. int webots_physics_collide(dGeomID g1, dGeomID g2) {
  100.  
  101. return ;
  102. }
  103.  
  104. void webots_physics_cleanup() {
  105.  
  106. }

设置完成物理引擎,在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 = ;
  17. double servo_pos;
  18.  
  19. wb_robot_init();
  20.  
  21. WbDeviceTag servo;
  22. servo = wb_robot_get_device("link2");
  23. assert(servo);
  24.  
  25. while (wb_robot_step(TIME_STEP) != -) {
  26.  
  27. servo_pos = + * sin(frep * t + pi);
  28. wb_servo_set_position(servo,deg_2_rad(servo_pos));
  29.  
  30. t += (double)TIME_STEP / 1000.0;
  31. };
  32.  
  33. wb_robot_cleanup();
  34.  
  35. return ;
  36. }

如果没有什么错误,就能实现之前GIF的效果了,如果没做出来,也没关系,给出原文件,仿真文件下载地址

如果有什么疑问,欢迎再下方提问。

webots自学笔记(五)使用物理插件ODE建立铰链的更多相关文章

  1. webots自学笔记(一)软件界面和简单模型仿真

    本人是某非理工类某高校大四狗,由于毕设研究需要使用webots软件,在学习使用webots的过程花费了很多时间.由于这个软件基本没有什么中文资料,所以想把自己所学到的一些东西写下来,如有什么错误的地方 ...

  2. webots自学笔记(二)节点与机器人建模

    原创文章,出自"博客园, _阿龙clliu" :http://www.cnblogs.com/clliu/ 上一次介绍了界面和一个简单的自由落体,然而在实际运用中,机器人的结构都是 ...

  3. webots自学笔记(三)控制器与电机控制

    原创文章,来自“博客园,_阿龙clliu” http://www.cnblogs.com/clliu/,装载请注明原文章出处. 上一次建了四足机器人的模型,模型文件在上一篇有下载地址,这一次用控制器让 ...

  4. webots自学笔记(四)传感器API使用、查看官方文档

           原创文章,来自“博客园,_阿龙clliu” http://www.cnblogs.com/clliu/,转载请注明原文章出处.           不能说webots的学习资料少,只能说 ...

  5. webots自学笔记(六)实用控制器函数补充

    原创文章,来自"博客园,_阿龙clliu" http://www.cnblogs.com/clliu/,转载请注明原文章出处.       用Webots软件做机器人仿真时,可以编 ...

  6. webpack4 自学笔记五(tree-shaking)

    全部的代码及笔记都可以在我的github上查看, 欢迎star: https://github.com/Jasonwang911/webpackStudyInit/tree/master/ThreeS ...

  7. JDK源码阅读-------自学笔记(五)(浅析数组)

    一.数组基础 1.定义和特点 数组也可以看做是对象,数组变量属于引用类型,数组中每个元素相当于该队形的成员变量,数组对象存储在堆中. 2.初始化数组 常用类初始化 // 整型初始化 int[] int ...

  8. vue 自学笔记记录

    vue 自学笔记(一): 知识内容:  安装vue ,创建vue实例,安装第一个组件,单项数据流 https://www.cnblogs.com/baili-luoyun/p/10763163.htm ...

  9. python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍

    python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍 IDLE默认不能显示行号,使用ALT+G 跳到对应行号,在右下角有显示光标所在行.列.pycharm免费社区版.Su ...

随机推荐

  1. Microsoft IoT Starter Kit 开发初体验-反馈控制与数据存储

    在上一篇文章<Microsoft IoT Starter Kit 开发初体验>中,讲述了微软中国发布的Microsoft IoT Starter Kit所包含的硬件介绍.开发环境搭建.硬件 ...

  2. IE6浏览器常见的bug及其修复方法

    IE6不支持min-height,解决办法使用css hack: .target { min-height: 100px; height: auto !important; height: 100px ...

  3. 图论——Dijkstra算法

    图论其实是比较难的一种题型,但是一些模板题,是没有什么太大难度的! 这里给大家带来的是迪杰斯特拉(Dijkstra)算法. 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄 ...

  4. java_JDBC字段对应

    地址: http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/java.102/B19275-03/datacc.htm ...

  5. mybatis入门-动态sql

    什么是动态sql 判断的动态sql mybatis核心就是对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装. 现有需求如下:需要查询用户,输入的是用户类,如果用户的性别类不为空 ...

  6. jenkins全局安全设置

    如何进入安全设置界面          在Jenkins的主界面,点击 configure Global Security 选项,进入Jenkins的系统安全设置界面.安全界面如下图.在这里我们分别介 ...

  7. matlab for循环的三种类型

    学习了一半了,发现一个好网站,就是我想写这篇博客用的,网络真是个好东西!纪念下国庆啦 网址:http://www.yiibai.com/matlab/matlab_for_loop.html ---- ...

  8. java 非缓冲与缓冲数据读取比较

    首先不适用缓存技术,读取数据: //非缓冲计时 package com.swust; import java.io.*; /* *功能:创建一个程序,写10000个随机双精度的数到一个文件中,同时测试 ...

  9. JS判断客户端、浏览器、操作系统

    一.JS判断客户端是否是iOS或者Android手机移动端 通过判断浏览器的userAgent,用正则来判断手机是否是ios和Android客户端. 方法一: var u = navigator.us ...

  10. UE4中的单映射:TMap容器

    一.TMap<T>是么 TMap<T>是UE4中的一种关联容器,每个键都关联着一个值,形成了单映射关系.因此你可以通过键名来快速查找到值.此外,单映射要求每个键都是唯一的.类似 ...