show

1.如何更新场景和视图,以便我可以模拟机器人移动?

为了在解决方案路径的每个配置中可视化机器人,您必须计算每个点的前向运动学并同步机器人的运动学和几何模型。通过获取和设置每个机器人身体的框架来完成。这两个方法在rl::plan::Model ,rl::plan中进行了组合和更新,在rlPlanDemo应用中也用到了。

1
2
3
4
5
6
7
8
9
10
this->mdl->forwardPosition(); 

if (doUpdateModel)
{
for (::std::size_t i = 0; i < this->model->getNumBodies(); ++i)
{
this->model->getBody(i)->setFrame(this->mdl->getBodyFrame(i));
}
}

关于如何设置动画的示例代码也可以在 rlPlanDemo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 rl::plan::VectorList::iterator i = path.begin(); 
rl::plan::VectorList::iterator j = ++path.begin();

if (i != path.end() && j != path.end())
{
this->drawConfiguration(*i);
QThread::usleep(static_cast<std::size_t>(0.01 * 1000.0 * 1000.0));
}

rl::math::Real delta = MainWindow::instance()->viewer->delta;

for (; i != path.end() && j != path.end(); ++i, ++j)
{
rl::math::Real steps = std::ceil(MainWindow::instance()->model->distance(*i, *j) / delta);

for (std::size_t k = 1; k < steps + 1; ++k)
{
if (!this->running) break;

MainWindow::instance()->model->interpolate(*i, *j, k / steps, inter);
this->drawConfiguration(inter);
QThread::usleep(static_cast<std::size_t>(0.01 * 1000.0 * 1000.0));
}
}

为了在 Qt 中制作动画,同时仍然能够与您的 GUI 交互,您通常必须使用单独的线程。由于带有 3D 模型的小部件是Qt 主线程的一部分,因此您必须使用Qt 信号和插槽在它们之间进行通信。这也用于rlPlanDemo.

2.对机器人模型进行自定义更改,向我们从 URDF 导入的机器人模型添加更多链接和框架.(目前不支持std::make_shared)

1
2
3
4
5
6
7
8
rl::mdl::Frame* new_frame = new rl::mdl::Frame();
new_frame->setName("new_frame");
model_->add(new_frame);

rl::mdl::Fixed* new_frame_fixed_link_ = new rl::mdl::Fixed();
model_->add(new_frame_fixed_link_, eef_frame, new_frame);
new_frame_fixed_link_->setName("eef_to_new_link");
model_->update();

3.移动机器人碰撞检测

移动机械手的一个很好的例子是 UMan(参见运动学和几何模型),它结合了 Nomad XR4000 底座和 Barrett WAM 机械手。为了使用运动学模型和给定的配置q更新几何模型,您首先必须使用基于空间向量代数的 rl::mdl API 或(不推荐使用的) rl::kin API 计算前向位置运动学基于经典的 Denavit-Hartenberg 符号:

1
2
3
4
5
rl::mdl::XmlFactory factory;
std::shared_ptr<rl::mdl::Model> model(factory.create("model.xml"));
rl::mdl::Kinematic* kinematic = dynamic_cast<rl::mdl::Kinematic*>(model.get());
kinematic->setPosition(q);
kinematic->forwardPosition();

然后,您可以根据计算出的框架更新几何模型各个主体的世界框架

1
2
3
4
5
6
7
rl::sg::Model* model = scene.getModel(0);

for (std::size_t i = 0; i < model->getNumBodies(); ++i)
{
model->getBody(i)->setFrame(kinematic->getBodyFrame(i)); // for current master branch
// model->getBody(i)->setFrame(kinematic->getFrame(i)); // for 0.7 branch
}

4.如何通过坐标求逆解

该演示rlInversePositionDemo首先使用正向运动学来确保为以下 IK 计算提供有效的末端执行器框架。为了使用您自己的目标框架,请将第 100 行正向运动学计算的框架替换为您自己rl::math::Transform的运动学模型可达的框架。以下是 Mitsubishi RV-6SL 运动学模型的示例mitsubishi-rv6sl.xml,其中旋转指定为 Euler-ZYX ( z = 0°, y = 90°, x = 0°) 并且平移设置为 ( x = 0.595 m, y = 0.0 米,z = 0.83 米):

1
2
3
4
5
6
7
8

rl::math::Transform goal;
goal.linear() = rl::math::AngleAxis(0.0 * rl::math::DEG2RAD, rl::math::Vector3::UnitZ()) *
rl::math::AngleAxis(90.0 * rl::math::DEG2RAD, rl::math::Vector3::UnitY()) *
rl::math::AngleAxis(0.0 * rl::math::DEG2RAD, rl::math::Vector3::UnitX()).toRotationMatrix();
goal.translation() = rl::math::Vector3(0.595, 0.0, 0.83);
ik.addGoal(goal, 0);

为了你自己的IK计算,你可以跳过的正运动学计算line:77-89,并在随机初始化line:102-110。

5.使用场景加载和 SimpleScene 检查碰撞

为了使用 rl::sg::SimpleScene 执行碰撞检查,请确保使用从此类派生的引擎。rl::sg::so::Scene(Open Inventor/Coin3D 抽象)仅支持 3D 可视化,不实现rl::sg::SimpleScene。.为此,请使用 Bullet、FCL、ODE、PQP 或 SOLID 引擎:

1
2
3
4
5
6
7
8
rl::sg::solid::Scene scene;
rl::sg::XmlFactory factory;
factory.load("scene.xml", &scene);
bool isColliding = scene.isColliding();
//-- bool areColliding = dynamic_cast<rl::sg::SimpleScene*>(&scene)->areColliding(
//-- scene.getModel(0), scene.getModel(1)
//-- );
bool areColliding = scene.areColliding(scene.getModel( 0 ),scene.getModel( 1 ));