Go to the documentation of this file.
41 return "RobotUnitState::InitializingComponent";
43 return "RobotUnitState::InitializingDevices";
45 return "RobotUnitState::InitializingUnits";
47 return "RobotUnitState::InitializingControlThread";
49 return "RobotUnitState::Running";
51 return "RobotUnitState::Exiting";
53 throw std::invalid_argument{
"Unknown state " +
to_string(
static_cast<std::size_t
>(
s)) +
63 #define cast_to_and_call(Type, fn, rethrow) \
67 dynamic_cast<Type*>(this)->Type::fn; \
69 catch (Ice::Exception & e) \
71 ARMARX_ERROR << "exception in " << #Type "::" #fn << "!\nwhat:\n" \
72 << e.what() << "\n\tid : " << e.ice_id() << "\n\tfile : " << e.ice_file() \
73 << "\n\tline : " << e.ice_line() << "\n\tstack: " << e.ice_stackTrace(); \
79 catch (std::exception & e) \
81 ARMARX_ERROR << "exception in " << #Type "::" #fn << "!\nwhat:\n" << e.what(); \
89 ARMARX_ERROR << "exception in " << #Type "::" #fn << "!"; \
96 #define for_each_module_apply(r, data, elem) data(elem)
97 #define for_each_module(macro) \
98 BOOST_PP_SEQ_FOR_EACH(for_each_module_apply, macro, BOOST_PP_VARIADIC_TO_SEQ(RobotUnitModules))
100 #define check_base(Type) \
101 static_assert(std::is_base_of<ModuleBase, Type>::value, \
102 "The RobotUnitModule '" #Type "' has to derived ModuleBase");
108 #define check_deriving(Type) \
109 ARMARX_CHECK_NOT_NULL(dynamic_cast<const Type*>(this)) \
110 << "This class does not derive from " << GetTypeString<Type>();
112 #undef check_deriving
127 #define call_module_hook(Type) \
128 cast_to_and_call(::armarx::RobotUnitModule::Type, _preOnInitRobotUnit(), true)
130 #undef call_module_hook
134 #define call_module_hook(Type) \
135 cast_to_and_call(::armarx::RobotUnitModule::Type, _postOnInitRobotUnit(), true)
137 #undef call_module_hook
148 #define call_module_hook(Type) \
149 cast_to_and_call(::armarx::RobotUnitModule::Type, _preOnConnectRobotUnit(), true)
151 #undef call_module_hook
155 #define call_module_hook(Type) \
156 cast_to_and_call(::armarx::RobotUnitModule::Type, _postOnConnectRobotUnit(), true)
158 #undef call_module_hook
167 #define call_module_hook(Type) \
168 cast_to_and_call(::armarx::RobotUnitModule::Type, _preOnDisconnectRobotUnit(), true)
170 #undef call_module_hook
174 #define call_module_hook(Type) \
175 cast_to_and_call(::armarx::RobotUnitModule::Type, _postOnDisconnectRobotUnit(), true)
177 #undef call_module_hook
189 #define call_module_hook(Type) \
190 cast_to_and_call(::armarx::RobotUnitModule::Type, _preOnExitRobotUnit(), false)
192 #undef call_module_hook
196 #define call_module_hook(Type) \
197 cast_to_and_call(::armarx::RobotUnitModule::Type, _postOnExitRobotUnit(), false)
199 #undef call_module_hook
207 #define call_module_hook(Type) \
209 ::armarx::RobotUnitModule::Type, _componentPropertiesUpdated(changedProperties), true)
211 #undef call_module_hook
217 #define call_module_hook(Type) \
218 cast_to_and_call(::armarx::RobotUnitModule::Type, _icePropertiesInitialized(), true)
220 #undef call_module_hook
233 #define call_module_hook(Type) \
234 cast_to_and_call(::armarx::RobotUnitModule::Type, _preFinishComponentInitialization(), true)
236 #undef call_module_hook
240 #define call_module_hook(Type) \
241 cast_to_and_call(::armarx::RobotUnitModule::Type, _postFinishComponentInitialization(), true)
243 #undef call_module_hook
254 #define call_module_hook(Type) \
255 cast_to_and_call(::armarx::RobotUnitModule::Type, _preFinishDeviceInitialization(), true)
257 #undef call_module_hook
261 #define call_module_hook(Type) \
262 cast_to_and_call(::armarx::RobotUnitModule::Type, _postFinishDeviceInitialization(), true)
264 #undef call_module_hook
275 #define call_module_hook(Type) \
276 cast_to_and_call(::armarx::RobotUnitModule::Type, _preFinishUnitInitialization(), true)
278 #undef call_module_hook
282 #define call_module_hook(Type) \
283 cast_to_and_call(::armarx::RobotUnitModule::Type, _postFinishUnitInitialization(), true)
285 #undef call_module_hook
296 #define call_module_hook(Type) \
297 cast_to_and_call(::armarx::RobotUnitModule::Type, _preFinishControlThreadInitialization(), true)
299 #undef call_module_hook
303 #define call_module_hook(Type) \
305 ::armarx::RobotUnitModule::Type, _postFinishControlThreadInitialization(), true)
307 #undef call_module_hook
323 #define call_module_hook(Type) \
324 cast_to_and_call(::armarx::RobotUnitModule::Type, _preFinishRunning(), false)
326 #undef call_module_hook
331 #define call_module_hook(Type) \
332 cast_to_and_call(::armarx::RobotUnitModule::Type, _postFinishRunning(), false)
334 #undef call_module_hook
337 #undef for_each_module_apply
338 #undef for_each_module
339 #undef cast_to_and_call
344 const std::set<RobotUnitState> ModuleBase::DevicesReadyStates{
355 const auto transitionErrorMessage = [=,
this](
RobotUnitState expectedFrom)
358 "! The expected source state is " +
to_string(expectedFrom) +
".";
360 const auto transitionErrorThrow = [=,
this](
RobotUnitState expectedFrom)
362 if (state != expectedFrom)
364 const auto msg = transitionErrorMessage(expectedFrom);
366 throw std::invalid_argument{msg};
373 throw std::invalid_argument{
374 "Can't switch to state RobotUnitState::InitializingComponent"};
394 throw std::invalid_argument{
"setRobotUnitState: Unknown target state " +
395 to_string(
static_cast<std::size_t
>(to)) +
405 return DevicesReadyStates.count(state);
412 std::this_thread::get_id() == _module<ControlThread>().getControlThreadId();
421 std::stringstream
str;
422 str <<
"Called function '" << fnc <<
"' in the Control Thread\nStack trace:\n"
425 throw LogicError{
str.str()};
435 throw LogicError{
"Attempted to lock mutex in Control Thread\nStack trace:\n" +
438 GuardType guard{dataMutex, std::defer_lock};
439 if (guard.try_lock())
443 while (!guard.try_lock_for(std::chrono::microseconds{100}))
447 throw LogicError{
"Attempting to lock mutex during shutdown\nStacktrace\n" +
457 const std::string& fnc,
461 if (!stateSet.count(state))
463 std::stringstream ss;
464 ss << fnc <<
": Can't be called if state is not in {";
481 throw LogicError{ss.str()};
494 const std::string& fnc,
498 if (stateSet.count(state))
500 std::stringstream ss;
501 ss << fnc <<
": Can't be called if state is in {";
518 throw LogicError{ss.str()};
535 std::atomic<ModuleBase*> ModuleBase::Instance_{
nullptr};
540 if (Instance_ &&
this != Instance_)
542 ARMARX_FATAL <<
"This class is a Singleton. It was already instantiated. (Instance = "
543 << Instance_ <<
", this = " <<
this <<
")";
bool isShuttingDown() const
Returns whether the RobotUnit is shutting down.
virtual void onConnectRobotUnit()
called in onConnectComponent
void onExitComponent() final override
void throwIfStateIs(const std::set< RobotUnitState > &stateSet, const std::string &fnc, bool onlyWarn=false) const
Throws an exception if the current state is in.
#define call_module_hook(Type)
#define cast_to_and_call(Type, fn, rethrow)
RobotUnitState getRobotUnitState() const
Returns the RobotUnit's State.
virtual void onInitRobotUnit()
called in onInitComponent
void checkDerivedClasses() const
Checks whether the implementing class derives all modules.
virtual void finishUnitInitialization()
Transition RobotUnitState::InitializingUnits -> RobotUnitState::WaitingForRTThreadInitialization.
for_each_module(check_base) void ModuleBase
bool inControlThread() const
Returns whether the current thread is the ControlThread.
void shutDown()
Requests the RobotUnit to shut down.
void onDisconnectComponent() final override
void componentPropertiesUpdated(const std::set< std::string > &changedProperties) override
void terminate(const Process &p)
virtual void finishControlThreadInitialization()
Transition RobotUnitState::InitializingControlThread -> RobotUnitState::Running.
GuardType getGuard() const
Returns a guard to the RobotUnits mutex.
static std::string CreateBackTrace(int linesToSkip=1)
virtual void onExitRobotUnit()
called in onExitComponent before calling finishRunning
virtual void onDisconnectRobotUnit()
called in onDisconnecComponent
virtual void finishRunning()
Transition RobotUnitState::Running -> RobotUnitState::Exiting.
const std::string & to_string(const std::string &s)
virtual void joinControlThread()=0
Implementations have to join their ControlThread in this hook. (used by RobotUnit::finishRunning())
@ InitializingControlThread
#define check_deriving(Type)
bool areDevicesReady() const
Returns whether Devices are ready.
void icePropertiesInitialized() override
std::unique_lock< MutexType > GuardType
void throwIfInControlThread(const std::string &fnc) const
Throws if the current thread is the ControlThread.
RobotUnitState
The current state of the multi step initialization of a RobotUnit.
void throwIfDevicesNotReady(const std::string &fnc) const
Throws if the Devices are not ready.
std::string getName() const
Retrieve name of object.
void throwIfStateIsNot(const std::set< RobotUnitState > &stateSet, const std::string &fnc, bool onlyWarn=false) const
Throws an exception if the current state is not in.
virtual void finishComponentInitialization()
Transition RobotUnitState::InitializingComponent -> RobotUnitState::InitializingDevices.
void onInitComponent() final override
This Module holds all high-level data about the robot.
virtual void finishDeviceInitialization()
Transition RobotUnitState::InitializingDevices -> RobotUnitState::InitializingUnits.
double s(double t, double s0, double v0, double a0, double j)
This file offers overloads of toIce() and fromIce() functions for STL container types.
void onConnectComponent() final override