Impl.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package RobotAPI::ArmarXObjects::RobotStatePredictionClientExample
17 * @author Rainer Kartmann ( rainer dot kartmann at kit dot edu )
18 * @date 2022
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
23
24#include "Impl.h"
25
29
34#include <RobotAPI/libraries/armem_robot_state/aron/Proprioception.aron.generated.h>
35#include <RobotAPI/libraries/armem_robot_state/aron/Transform.aron.generated.h>
39
40namespace simox::alg
41{
42 template <class... Args>
43 std::vector<Args...>
44 concatenate(const std::vector<Args...>& lhs, const std::vector<Args...>& rhs)
45 {
46 std::vector<Args...> conc = lhs;
47 std::copy(rhs.begin(), rhs.end(), std::back_inserter(conc));
48 return conc;
49 }
50
51 template <class KeyT, class ValueT>
52 std::map<KeyT, ValueT>
53 map_from_key_value_pairs(const std::vector<KeyT>& lhs, const std::vector<ValueT>& rhs)
54 {
55 const size_t size = std::min(lhs.size(), rhs.size());
56
57 std::map<KeyT, ValueT> map;
58 for (size_t i = 0; i < size; ++i)
59 {
60 map.emplace(lhs[i], rhs[i]);
61 }
62 return map;
63 }
64
65 template <class KeyT, class ValueT>
66 std::vector<ValueT>
67 multi_at(const std::map<KeyT, ValueT>& map,
68 const std::vector<KeyT>& keys,
69 bool skipMissing = false)
70 {
71 std::vector<ValueT> values;
72 values.reserve(keys.size());
73
74 for (const KeyT& key : keys)
75 {
76 if (skipMissing)
77 {
78 if (auto it = map.find(key); it != map.end())
79 {
80 values.push_back(it->second);
81 }
82 }
83 else
84 {
85 // Throw an exception if missing.
86 values.push_back(map.at(key));
87 }
88 }
89
90 return values;
91 }
92
93 template <class... Args>
94 std::vector<Args...>
95 slice(const std::vector<Args...>& vector,
96 size_t start = 0,
97 std::optional<size_t> end = std::nullopt)
98 {
99 std::vector<Args...> result;
100 auto beginIt = vector.begin() + start;
101 auto endIt = end ? vector.begin() + *end : vector.end();
102 std::copy(beginIt, endIt, std::back_inserter(result));
103 return result;
104 }
105
106} // namespace simox::alg
107
109{
110
112 {
113 client.remote.robotReader.emplace();
114 }
115
116 Impl::~Impl() = default;
117
118 void
120 const std::string& prefix)
121 {
122 defs->optional(properties.robotName, prefix + "robotName", "Name of the robot.");
123
124 defs->optional(properties.predictAheadSeconds,
125 prefix + "predictAheadSeconds",
126 "How far into the future to predict [s].");
127
128 client.remote.robotReader->registerPropertyDefinitions(defs);
129 }
130
131 void
133 {
134 try
135 {
136 client.remote.reader =
138 ARMARX_IMPORTANT << "got reader";
139 }
141 {
142 ARMARX_WARNING << e.what();
143 }
144
145 client.remote.robotReader->connect(mns);
146
147 this->remote.arviz = arviz;
148 }
149
150 void
152 {
153 task = new armarx::SimpleRunningTask<>([this]() { this->run(); });
154 task->start();
155 }
156
157 void
159 {
160 task->stop();
161 }
162
163 void
165 {
166 Metronome metronome(Frequency::Hertz(properties.updateFrequencyHz));
167
168 while (task and not task->isStopped())
169 {
170 metronome.waitForNextTick();
171
172 runOnce();
173 }
174 }
175
176 void
178 {
179 ARMARX_CHECK(client.remote.reader);
180
181 const DateTime now = Clock::Now();
182 const DateTime predictedTime =
183 now + Duration::SecondsDouble(properties.predictAheadSeconds);
184
185 if (not robotViz)
186 {
187 auto desc = client.remote.robotReader->queryDescription(properties.robotName, now);
188 if (desc.has_value())
189 {
190 PackagePath& pp = desc->xml;
191 robotViz = viz::Robot(properties.robotName)
192 .file(pp.serialize().package, pp.serialize().path)
193 .overrideColor(simox::Color::cyan(255, 64));
194 }
195 else
196 {
197 ARMARX_INFO << "Failed to get robot description.";
198 }
199 }
200 if (not robotViz)
201 {
202 return;
203 }
204
205 // Which entities to predict?
206
207 const std::vector<armem::MemoryID> locEntityIDs = this->localizationEntityIDs.has_value()
208 ? this->localizationEntityIDs.value()
209 : client.queryLocalizationEntityIDs();
210 const std::vector<armem::MemoryID> propEntityIDs =
211 this->propioceptionEntityIDs.has_value() ? this->propioceptionEntityIDs.value()
212 : client.queryProprioceptionEntityIDs();
213
214 // Predict.
215
216 auto prediction = client.predictWholeBody(
217 locEntityIDs, propEntityIDs, predictedTime, properties.robotName, "Linear");
218
219 // Gather results.
220
221 if (prediction.globalPose.has_value())
222 {
223 // ARMARX_INFO << "Predicted global pose: \n" << globalPose->matrix();
224 robotViz->pose(prediction.globalPose->matrix());
225
226 if (not localizationEntityIDs)
227 {
228 // Store entity IDs for successful lookup.
229 this->localizationEntityIDs = locEntityIDs;
230 }
231 }
232 if (prediction.jointPositions.has_value())
233 {
234 robotViz->joints(prediction.jointPositions.value());
235
237 {
238 this->propioceptionEntityIDs = propEntityIDs;
239 }
240 }
241
242 // Visualize.
243 {
244 viz::Layer layer = remote.arviz.layer(properties.robotName + " Prediction");
245 layer.add(robotViz.value());
246 remote.arviz.commit(layer);
247 }
248 }
249
250
251} // namespace armarx::robot_state_prediction_client_example
static DateTime Now()
Current time on the virtual clock.
Definition Clock.cpp:93
static Duration SecondsDouble(double seconds)
Constructs a duration in seconds.
Definition Duration.cpp:78
static Frequency Hertz(std::int64_t hertz)
Definition Frequency.cpp:20
data::PackagePath serialize() const
The memory name system (MNS) client.
Indicates that a query to the Memory Name System failed.
Definition mns.h:25
Represents a point in time.
Definition DateTime.h:25
Simple rate limiter for use in loops to maintain a certain frequency given a clock.
Definition Metronome.h:57
Duration waitForNextTick() const
Wait and block until the target period is met.
Definition Metronome.cpp:27
void connect(armem::client::MemoryNameSystem &mns, viz::Client arviz)
Definition Impl.cpp:132
armem::robot_state::RobotStatePredictionClient client
Definition Impl.h:79
std::optional< std::vector< armem::MemoryID > > localizationEntityIDs
Definition Impl.h:81
std::optional< viz::Robot > robotViz
Definition Impl.h:83
std::optional< std::vector< armem::MemoryID > > propioceptionEntityIDs
Definition Impl.h:82
armarx::SimpleRunningTask ::pointer_type task
Definition Impl.h:76
void defineProperties(IceUtil::Handle< armarx::PropertyDefinitionContainer > &defs, const std::string &prefix)
Definition Impl.cpp:119
Robot & file(std::string const &project, std::string const &filename)
Definition Robot.h:16
Robot & overrideColor(Color c)
Definition Robot.h:50
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
SimpleRunningTask(Ts...) -> SimpleRunningTask< std::function< void(void)> >
std::vector< ValueT > multi_at(const std::map< KeyT, ValueT > &map, const std::vector< KeyT > &keys, bool skipMissing=false)
Definition Impl.cpp:67
std::vector< Args... > concatenate(const std::vector< Args... > &lhs, const std::vector< Args... > &rhs)
Definition Impl.cpp:44
std::vector< Args... > slice(const std::vector< Args... > &vector, size_t start=0, std::optional< size_t > end=std::nullopt)
Definition Impl.cpp:95
std::map< KeyT, ValueT > map_from_key_value_pairs(const std::vector< KeyT > &lhs, const std::vector< ValueT > &rhs)
Definition Impl.cpp:53
void add(ElementT const &element)
Definition Layer.h:31