| Directory: | ./ |
|---|---|
| File: | src/visualizers/base-visualizer.cpp |
| Date: | 2025-04-30 16:14:33 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 36 | 69 | 52.2% |
| Branches: | 11 | 60 | 18.3% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // | ||
| 2 | // Copyright (c) 2024-2025 INRIA | ||
| 3 | // | ||
| 4 | #include "pinocchio/visualizers/base-visualizer.hpp" | ||
| 5 | |||
| 6 | #include "pinocchio/algorithm/frames.hpp" | ||
| 7 | #include "pinocchio/algorithm/geometry.hpp" | ||
| 8 | #include "pinocchio/algorithm/model.hpp" | ||
| 9 | |||
| 10 | #include <chrono> | ||
| 11 | #include <thread> | ||
| 12 | |||
| 13 | namespace pinocchio | ||
| 14 | { | ||
| 15 | namespace visualizers | ||
| 16 | { | ||
| 17 | |||
| 18 | 1 | BaseVisualizer::BaseVisualizer( | |
| 19 | const Model & model, | ||
| 20 | const GeometryModel & visual_model, | ||
| 21 | const GeometryModel * collision_model, | ||
| 22 | Data & data, | ||
| 23 | GeometryData & visual_data, | ||
| 24 | 1 | GeometryData * collision_data) | |
| 25 | 1 | : m_model(model) | |
| 26 | 1 | , m_visualModel(&visual_model) | |
| 27 | 1 | , m_collisionModel(collision_model) | |
| 28 | 1 | , m_data(&data) | |
| 29 | 1 | , m_visualData(&visual_data) | |
| 30 | 1 | , m_collisionData(collision_data) | |
| 31 | 1 | , m_ownedData(false) | |
| 32 | { | ||
| 33 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (hasCollisionModel()) |
| 34 | { | ||
| 35 | ✗ | PINOCCHIO_THROW( | |
| 36 | collision_data != nullptr, std::logic_error, | ||
| 37 | "A collision model was provided but no pointer to collision GeometryData to borrow."); | ||
| 38 | } | ||
| 39 | else | ||
| 40 | { | ||
| 41 | 1 | m_collisionData = nullptr; | |
| 42 | } | ||
| 43 | 1 | } | |
| 44 | |||
| 45 | 2 | BaseVisualizer::BaseVisualizer( | |
| 46 | const Model & model, | ||
| 47 | const GeometryModel & visual_model, | ||
| 48 | 2 | const GeometryModel * collision_model) | |
| 49 | 2 | : m_model(model) | |
| 50 | 2 | , m_visualModel(&visual_model) | |
| 51 | 2 | , m_collisionModel(collision_model) | |
| 52 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | , m_data(new Data(model)) |
| 53 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | , m_visualData(new GeometryData(visual_model)) |
| 54 | 2 | , m_collisionData(nullptr) | |
| 55 | 2 | , m_ownedData(true) | |
| 56 | { | ||
| 57 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (hasCollisionModel()) |
| 58 | ✗ | m_collisionData = new GeometryData(*m_collisionModel); | |
| 59 | 2 | } | |
| 60 | |||
| 61 | 6 | BaseVisualizer::~BaseVisualizer() | |
| 62 | { | ||
| 63 | 6 | this->destroyData(); | |
| 64 | } | ||
| 65 | |||
| 66 | 3 | void BaseVisualizer::destroyData() | |
| 67 | { | ||
| 68 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
|
3 | if (m_ownedData) |
| 69 | { | ||
| 70 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | assert(m_data); |
| 71 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | assert(m_visualData); |
| 72 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | delete m_data; |
| 73 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | delete m_visualData; |
| 74 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (m_collisionData) |
| 75 | ✗ | delete m_collisionData; | |
| 76 | } | ||
| 77 | 3 | m_data = nullptr; | |
| 78 | 3 | m_visualData = nullptr; | |
| 79 | 3 | m_collisionData = nullptr; | |
| 80 | 3 | } | |
| 81 | |||
| 82 | ✗ | void BaseVisualizer::rebuildData() | |
| 83 | { | ||
| 84 | ✗ | this->destroyData(); | |
| 85 | ✗ | m_data = new Data(m_model); | |
| 86 | ✗ | m_visualData = new GeometryData(*m_visualModel); | |
| 87 | ✗ | if (hasCollisionModel()) | |
| 88 | ✗ | m_collisionData = new GeometryData(*m_collisionModel); | |
| 89 | // mark as owned, if that was not the case | ||
| 90 | ✗ | m_ownedData = true; | |
| 91 | } | ||
| 92 | |||
| 93 | ✗ | void BaseVisualizer::display(const boost::optional<ConstVectorRef> & q) | |
| 94 | { | ||
| 95 | ✗ | displayPrecall(); | |
| 96 | ✗ | if (q.has_value()) | |
| 97 | { | ||
| 98 | ✗ | forwardKinematics(model(), *m_data, *q); | |
| 99 | } | ||
| 100 | ✗ | updateGeometryPlacements(model(), *m_data, *m_visualModel, *m_visualData); | |
| 101 | ✗ | if (hasCollisionModel()) | |
| 102 | { | ||
| 103 | ✗ | updateGeometryPlacements(model(), *m_data, *m_collisionModel, *m_collisionData); | |
| 104 | } | ||
| 105 | ✗ | displayImpl(); | |
| 106 | } | ||
| 107 | |||
| 108 | ✗ | void BaseVisualizer::play(const std::vector<ConstVectorRef> & qs, Scalar dt) | |
| 109 | { | ||
| 110 | using std::chrono::steady_clock; | ||
| 111 | ✗ | const auto nsteps = qs.size(); | |
| 112 | ✗ | const auto ms = std::chrono::milliseconds(unsigned(dt * 1e3)); | |
| 113 | |||
| 114 | ✗ | for (size_t i = 0; i < nsteps; i++) | |
| 115 | { | ||
| 116 | ✗ | const auto cur = steady_clock::now(); | |
| 117 | ✗ | this->display(qs[i]); | |
| 118 | ✗ | if (!this->forceRedraw()) | |
| 119 | ✗ | return; | |
| 120 | ✗ | std::this_thread::sleep_until(cur + ms); | |
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | ✗ | void BaseVisualizer::play(const ConstMatrixRef & qs, Scalar dt) | |
| 125 | { | ||
| 126 | using Eigen::Index; | ||
| 127 | ✗ | const Index nsteps = qs.rows(); | |
| 128 | ✗ | std::vector<ConstVectorRef> qs_; | |
| 129 | ✗ | for (Index i = 0; i < nsteps; i++) | |
| 130 | { | ||
| 131 | ✗ | qs_.emplace_back(qs.row(i)); | |
| 132 | } | ||
| 133 | // call overload | ||
| 134 | ✗ | this->play(qs_, dt); | |
| 135 | } | ||
| 136 | |||
| 137 | } // namespace visualizers | ||
| 138 | } // namespace pinocchio | ||
| 139 |