如何在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节点

#VRML_OBJ R2022a utf8
DEF trail Shape{
 geometry DEF indexLineSet IndexedLineSet{
 coord DEF coord Coordinate{
            point [ 0 0 0
                    0 0 0
                  ]
        }  
                 coordIndex[0
                            0
                            -1
                           ]
    }
}

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

 const int MaxCount=65000;

 std::string mystring_1="DEF trail Shape { \n
    geometry DEF indexLineSet IndexedLineSet {\n \
    coord DEF coord Coordinate {\n \
      point [0 0 0\n";
      
  std::string mystring_2="\
      0 0 0\n \
   ";
   
  for(int i=0;i<MaxCount-2;i++)
  mystring_2=mystring_2+"0 0 0 \n \ ";
  mystring_2 = mystring_2+"]";//添加域结束符
   
  std::string mystring_3=" }\n \
    coordIndex [0 \n ";
  std::string mystring_4="\  
    0\n ";
    
  for(int i=0;i<MaxCount-2;i++)
  mystring_4=mystring_4+"0\n \ ";
  mystring_4 = mystring_4+"]";//添加域结束符
    
  std::string mystring_5="}\n \
}";
  
  std::string mystring=mystring_1+mystring_2+mystring_3+mystring_4+mystring_5;

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

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

几个将要用到的函数:

Node* Supervisor::getRoot();//返回场景树根目录
Node * Supervisor::getFromDef(const std::string &name);//从DEF中得到节点

Field* Node::getField(const std::string &fieldName) const;//获取域

void Field::importMFNodeFromString(int position, const std::string &nodeString);//将string转换成节点导入

const double * Node::getPosition() const;//获取节点的位置坐标

void Field::setMFVec3f(int index, const double values[3]);//设置域值
void Field::setMFInt32(int index, int value);//设置域值




需要用到的头文件

#include <webots/Supervisor.hpp>
#include <webots/Node.hpp>
#include <webots/Field.hpp>
#include <string>
#include <iostream>

主要程序

  Field *root = supervisor->getRoot()->getField("children");
  root->importMFNodeFromString(-1,mystring);
  
  Node *RTARGET=supervisor->getFromDef("RTARGET");
  if(RTARGET!=NULL)std::cout<<"获取RTARGET成功\n";
  
  Field *point=supervisor->getFromDef("coord")\
  ->getField("point");
   Field *coordIndex=supervisor->getFromDef("indexLineSet")\
  ->getField("coordIndex");




  while (supervisor->step(timeStep*3) != -1) {
    //读取连杆2的质心位置
    const double* position = RTARGET->getPosition();
    std::cout<<"x is "<<position[0]<<std::endl;
    std::cout<<"y is "<<position[1]<<std::endl;  
    std::cout<<"z is "<<position[2]<<std::endl;
    std::cout<<"/******************************/ \n";
    point->setMFVec3f(pointIndex,position);
    // if(mark==0)
    // {
      // indexC++;
      // mark = 1;
    // }
    // else mark=0;
    if(pointIndex>1){//代表point Index运行了2次
        coordIndex->setMFInt32((pointIndex-2)*3+0,indexC);
        coordIndex->setMFInt32((pointIndex-2)*3+1,indexC+1);
        coordIndex->setMFInt32((pointIndex-2)*3+2,-1);
        indexC++;
      }
    pointIndex++;
    
  };

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

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要在MATLAB绘制带电粒子在磁场运动轨迹,可以按照以下步骤进行操作: 1. 定义带电粒子的初始位置、速度和电荷量等参数。 2. 设置磁场的大小和方向。可以选择使用静态磁场或随时间变化的磁场。 3. 使用ODE求解器(如ode45)来求解粒子的运动方程。运动方程可以根据洛伦兹力定律来确定。洛伦兹力定律表明带电粒子在磁场受到的力是其速度与磁场之间的叉乘的结果。 4. 在求解得到的位置和速度数据上进行插值,以获得更平滑的轨迹。 5. 利用MATLAB的绘图函数(如plot3)将运动轨迹绘制出来。可以使用三维坐标系来表示粒子的位置。 以下是一个简单的代码示例: ```MATLAB % 定义初始条件 x0 = 0; y0 = 0; z0 = 0; vx0 = 1; vy0 = 0; vz0 = 1; q = 1; % 电荷量 % 定义磁场 Bx = 0; By = 0; Bz = 1; % 定义时间范围和步长 tstart = 0; tend = 10; dt = 0.01; % 定义运动方程 f = @(t, w) [w(4); w(5); w(6); q/M*(w(5)*Bz - w(6)*By); q/M*(w(6)*Bx - w(4)*Bz); q/M*(w(4)*By - w(5)*Bx)]; % 使用ODE求解器求解运动方程 [T, W] = ode45(f, [tstart:dt:tend], [x0; y0; z0; vx0; vy0; vz0]); % 插值处理 Winterp = interp1(T, W, tstart:dt/10:tend); % 绘制轨迹 plot3(Winterp(:,1),Winterp(:,2),Winterp(:,3)); xlabel('X轴'); ylabel('Y轴'); zlabel('Z轴'); title('带电粒子在磁场运动轨迹'); grid on; ``` 运行此代码将在三维坐标系绘制出带电粒子在给定磁场运动轨迹。可以根据需要修改参数和绘图方式来适应实际情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值