VirtualRobotReader.cpp
Go to the documentation of this file.
2
3#include <filesystem>
4#include <optional>
5#include <string>
6#include <thread>
7
8#include <VirtualRobot/Robot.h>
9#include <VirtualRobot/VirtualRobot.h>
10#include <VirtualRobot/XML/BaseIO.h>
11#include <VirtualRobot/XML/RobotIO.h>
12
19
21
23{
24
25 bool
26 VirtualRobotReader::synchronizeRobot(VirtualRobot::Robot& robot,
27 const armem::Time& timestamp) const
28 {
29 const auto robotState = queryState(robot.getName(), timestamp);
30 if (not robotState)
31 {
32 ARMARX_VERBOSE << deactivateSpam(5) << "Querying robot state failed for robot `"
33 << robot.getName() << "` " << "(type `" << robot.getType() << "`)!";
34 return false;
35 }
36
37 robot.setJointValues(robotState->jointMap);
38 robot.setGlobalPose(robotState->globalPose.matrix());
39
40 return true;
41 }
42
43 bool
45 const armem::Time& timestamp) const
46 {
47 const auto robotState = queryJointState(robot.getName(), timestamp);
48 if (not robotState)
49 {
50 ARMARX_VERBOSE << deactivateSpam(5) << "Querying robot state failed for robot `"
51 << robot.getName() << "` " << "(type `" << robot.getType() << "`)!";
52 return false;
53 }
54
55 robot.setJointValues(robotState->jointMap);
56
57 return true;
58 }
59
60 bool
62 VirtualRobot::Robot& robot,
63 const Time& timestamp) const
64 {
65 const auto robotState = queryState(robot.getName(), timestamp);
66 if (not robotState)
67 {
68 ARMARX_VERBOSE << deactivateSpam(5) << "Querying robot state failed for robot `"
69 << robot.getName() << "` " << "(type `" << robot.getType() << "`)!";
70 return false;
71 }
72
73 robot.setGlobalPose(robotState->globalPose.matrix());
74
75 return true;
76 }
77
79 VirtualRobotReader::getRobot(const std::string& name,
81 const VirtualRobot::RobotIO::RobotDescription& loadMode)
82 {
83 ARMARX_VERBOSE << deactivateSpam(60) << "Querying robot description for robot '" << name
84 << "'";
85 const auto description = queryDescription(name, timestamp);
86
87 if (not description)
88 {
89 ARMARX_VERBOSE << deactivateSpam(5) << "The description of robot `" << name
90 << "` is not a available!";
91
92 return nullptr;
93 }
94
95 const std::string xmlFilename = description->xml.toSystemPath();
96 ARMARX_CHECK(std::filesystem::exists(xmlFilename)) << xmlFilename;
97
98 ARMARX_VERBOSE << deactivateSpam(5) << "Loading (virtual) robot '" << description->name
99 << "' from XML file '" << xmlFilename << "'";
100
101 auto robot = VirtualRobot::RobotIO::loadRobot(xmlFilename, loadMode);
102 ARMARX_CHECK_NOT_NULL(robot) << "Could not load robot from file `" << xmlFilename << "`";
103
104 robot->setName(name);
105
106 return robot;
107 }
108
110 VirtualRobotReader::getRobotWaiting(const std::string& name,
111 const armem::Time& timestamp,
112 const VirtualRobot::RobotIO::RobotDescription& loadMode)
113 {
114 ARMARX_INFO << "Trying to get robot `" << name << "` ...";
115
116 VirtualRobot::RobotPtr robot = nullptr;
117
118 // while (robot == nullptr)
119 {
120 // might be nullptr if query fails
121 robot = getRobot(name, timestamp, loadMode);
122
123 if (robot == nullptr)
124 {
125 ARMARX_WARNING << deactivateSpam(1) << "Failed to query robot `" << name
126 << "`. At the moment, a blocking behavior is not possible in "
127 "onConnectComponent()."
128 << "Therefore, a nullptr will be returned. This will likely cause "
129 "problems downstream.";
130 // << "`. Will try again ...";
131 }
132 else
133 {
134 ARMARX_INFO << "Got robot `" << name << "`.";
135 }
136 // Clock::WaitFor(Duration::MilliSeconds(200));
137 }
138
139
140 return robot;
141 }
142
144 VirtualRobotReader::getSynchronizedRobot(const std::string& name,
145 const VirtualRobot::BaseIO::RobotDescription& loadMode,
146 bool blocking)
147 {
148 return _getSynchronizedRobot(name, armem::Time::Invalid(), loadMode, blocking);
149 }
150
153 const std::string& name,
154 const armem::Time& timestamp,
155 const VirtualRobot::RobotIO::RobotDescription& loadMode,
156 const bool blocking)
157 {
158 return _getSynchronizedRobot(name, timestamp, loadMode, blocking);
159 }
160
162 VirtualRobotReader::_getSynchronizedRobot(
163 const std::string& name,
164 const Time& timestamp,
165 const VirtualRobot::BaseIO::RobotDescription& loadMode,
166 bool blocking)
167 {
168 // Get robot model
169 VirtualRobot::RobotPtr robot = nullptr;
170
171 while (true)
172 {
173 const auto ts = timestamp.isInvalid() ? armarx::Clock::Now() : timestamp;
174
175 robot = getRobot(name, ts, loadMode);
176 if (robot) // we successfully got the robot
177 {
178 break;
179 }
180
181 // If we are in non-blocking mode, we are done -> failure
182 if (not blocking)
183 {
184 ARMARX_VERBOSE << deactivateSpam(5) << "Failed to get robot `" << name << "`";
185 return nullptr;
186 }
187
188 // If we are in blocking mode, we will retry
189 ARMARX_VERBOSE << deactivateSpam(5) << "Retrying to query robot after failure";
191 };
192
193 // Pedantic check. Should not happen, but just in case.
194 if (robot == nullptr)
195 {
196 ARMARX_VERBOSE << deactivateSpam(5) << "Failed to get robot `" << name << "`";
197 return nullptr;
198 }
199
200 ARMARX_DEBUG << "Got robot model";
201
202 while (true)
203 {
204 const auto ts = timestamp.isInvalid() ? armarx::Clock::Now() : timestamp;
205
206 // Synchronize robot model.
207 // If we can synchronize the robot, we are done -> success
208 if (synchronizeRobot(*robot, ts))
209 {
210 return robot;
211 }
212
213 // If we are in non-blocking mode, we are done -> failure
214 if (not blocking)
215 {
216 ARMARX_VERBOSE << deactivateSpam(5) << "Failed to get synchronized robot `" << name
217 << "`";
218 return nullptr;
219 }
220
221 // If we are in non-blocking mode, we can try again.
222 ARMARX_VERBOSE << deactivateSpam(5) << "Retrying to query robot after failure";
224 }
225
226 ARMARX_VERBOSE << deactivateSpam(5) << "Failed to get synchronized robot `" << name << "`";
227 return nullptr;
228 }
229
230
231} // namespace armarx::armem::robot_state
std::string timestamp()
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
static DateTime Now()
Current time on the virtual clock.
Definition Clock.cpp:93
static void WaitFor(const Duration &duration)
Wait for a certain duration on the virtual clock.
Definition Clock.cpp:99
std::optional< RobotState > queryState(const std::string &robotName, const armem::Time &timestamp) const
std::optional< description::RobotDescription > queryDescription(const std::string &name, const armem::Time &timestamp) const
std::optional< RobotState > queryJointState(const std::string &robotName, const armem::Time &timestamp) const
VirtualRobot::RobotPtr getRobotWaiting(const std::string &name, const armem::Time &timestamp=armem::Time::Invalid(), const VirtualRobot::RobotIO::RobotDescription &loadMode=VirtualRobot::RobotIO::RobotDescription::eStructure)
In contrast to getRobot(), this function will retry to query the robot until it exists.
VirtualRobot::RobotPtr getSynchronizedRobot(const std::string &name, const VirtualRobot::RobotIO::RobotDescription &loadMode=VirtualRobot::RobotIO::RobotDescription::eStructure, bool blocking=true)
VirtualRobot::RobotPtr getRobot(const std::string &name, const armem::Time &timestamp=armem::Time::Invalid(), const VirtualRobot::RobotIO::RobotDescription &loadMode=VirtualRobot::RobotIO::RobotDescription::eStructure)
bool synchronizeRobotPose(VirtualRobot::Robot &robot, const armem::Time &timestamp) const
Synchronize only the platform pose of a virtual robot, according to the robot state memory for a cert...
bool synchronizeRobot(VirtualRobot::Robot &robot, const armem::Time &timestamp) const
Synchronize both the platform pose and the joint values of a virtual robot, according to the robot st...
bool synchronizeRobotJoints(VirtualRobot::Robot &robot, const armem::Time &timestamp) const
Synchronize only the joint values of a virtual robot, according to the robot state memory for a certa...
static DateTime Invalid()
Definition DateTime.cpp:57
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
armarx::core::time::DateTime Time