当前位置:   article > 正文

如何在webots中绘制运动轨迹_webots 绘制曲线

webots 绘制曲线

我们希望在webots里仿真时,机器人的运动轨迹能够在3维仿真环境中显示出来。解决办法如下:

  1. 添加一个Robot节点,并将其“supervisor”域设为“true”;
  2. 使用VRML语言撰写一个Shape节点,该Shape节点的几何体是IndexedLineSet,IndexedLineSet可以看作是点;
  3. 在1中Robot的控制器文件中,利用supervisor获取机器人质心的坐标,并将该点的坐标添加至2中的Shape节点中,然后将Shape中的点连接起来,便得到机器人质心的运动轨迹。

1 添加Robot节点

添加一个Robot节点,将其“supervisor”域设置为true后,才能够使用在编写Robot的控制器时使用supervisor类。

2 VRML撰写一个Shape节点

  1. #VRML_OBJ R2022a utf8
  2. DEF trail Shape{
  3. geometry DEF indexLineSet IndexedLineSet{
  4. coord DEF coord Coordinate{
  5. point [ 0 0 0
  6. 0 0 0
  7. ]
  8. }
  9. coordIndex[0
  10. 0
  11. -1
  12. ]
  13. }
  14. }

用C++来写一个VRML文本,用于生成Shape节点。首先确定Shape中点的数目,此处设MaxCount=65000;域coordIndex的作用是将点连接起来,假设coordIndex是[0 1 -1 1 2],其作用就是将Point域中索引为0和1的点连接起来,然后-1是分割符号,之后再将索引为1和2的点再连接起来,在仿真环境中就显示出了一条线。下面是一个用于生成Shape节点的字符串:

  1. const int MaxCount=65000;
  2. std::string mystring_1="DEF trail Shape { \n
  3. geometry DEF indexLineSet IndexedLineSet {\n \
  4. coord DEF coord Coordinate {\n \
  5. point [0 0 0\n";
  6. std::string mystring_2="\
  7. 0 0 0\n \
  8. ";
  9. for(int i=0;i<MaxCount-2;i++)
  10. mystring_2=mystring_2+"0 0 0 \n \ ";
  11. mystring_2 = mystring_2+"]";//添加域结束符
  12. std::string mystring_3=" }\n \
  13. coordIndex [0 \n ";
  14. std::string mystring_4="\
  15. 0\n ";
  16. for(int i=0;i<MaxCount-2;i++)
  17. mystring_4=mystring_4+"0\n \ ";
  18. mystring_4 = mystring_4+"]";//添加域结束符
  19. std::string mystring_5="}\n \
  20. }";
  21. std::string mystring=mystring_1+mystring_2+mystring_3+mystring_4+mystring_5;

3 编写用来绘制运动轨迹的Robot控制器

注意这里的Robot控制器是专门用来生成运动轨迹的,而不是控制机器人运动的那个控制器,也就是说,为了生成运动轨迹,额外地添加了一个Robot节点,此时左边的场景树下至少有2个Robot节点。

几个将要用到的函数:

  1. Node* Supervisor::getRoot();//返回场景树根目录
  2. Node * Supervisor::getFromDef(const std::string &name);//从DEF中得到节点
  3. Field* Node::getField(const std::string &fieldName) const;//获取域
  4. void Field::importMFNodeFromString(int position, const std::string &nodeString);//将string转换成节点导入
  5. const double * Node::getPosition() const;//获取节点的位置坐标
  6. void Field::setMFVec3f(int index, const double values[3]);//设置域值
  7. void Field::setMFInt32(int index, int value);//设置域值

需要用到的头文件

  1. #include <webots/Supervisor.hpp>
  2. #include <webots/Node.hpp>
  3. #include <webots/Field.hpp>
  4. #include <string>
  5. #include <iostream>

主要程序

  1. Field *root = supervisor->getRoot()->getField("children");
  2. root->importMFNodeFromString(-1,mystring);
  3. Node *RTARGET=supervisor->getFromDef("RTARGET");
  4. if(RTARGET!=NULL)std::cout<<"获取RTARGET成功\n";
  5. Field *point=supervisor->getFromDef("coord")\
  6. ->getField("point");
  7. Field *coordIndex=supervisor->getFromDef("indexLineSet")\
  8. ->getField("coordIndex");
  9. while (supervisor->step(timeStep*3) != -1) {
  10. //读取连杆2的质心位置
  11. const double* position = RTARGET->getPosition();
  12. std::cout<<"x is "<<position[0]<<std::endl;
  13. std::cout<<"y is "<<position[1]<<std::endl;
  14. std::cout<<"z is "<<position[2]<<std::endl;
  15. std::cout<<"/******************************/ \n";
  16. point->setMFVec3f(pointIndex,position);
  17. // if(mark==0)
  18. // {
  19. // indexC++;
  20. // mark = 1;
  21. // }
  22. // else mark=0;
  23. if(pointIndex>1){//代表point Index运行了2次
  24. coordIndex->setMFInt32((pointIndex-2)*3+0,indexC);
  25. coordIndex->setMFInt32((pointIndex-2)*3+1,indexC+1);
  26. coordIndex->setMFInt32((pointIndex-2)*3+2,-1);
  27. indexC++;
  28. }
  29. pointIndex++;
  30. };

 时间比较匆忙,写得不清楚,后面有时间详细说说

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/1008176
推荐阅读
相关标签
  

闽ICP备14008679号