ZeroTorque.cpp
Go to the documentation of this file.
1#include "ZeroTorque.h"
2#include <Ice/Exception.h>
3
4#include <VirtualRobot/Robot.h>
5#include <VirtualRobot/RobotNodeSet.h>
6
13
14#include <RobotAPI/interface/units/RobotUnit/NjointZeroTorqueController.h>
19#include <armarx/control/skills/aron/ZeroTorque.aron.generated.h>
20
22{
23 armarx::skills::SkillDescription
25 {
26 ParamType defaults;
27 defaults.nodeSetName = "RightArm";
28 return ::armarx::skills::SkillDescription{
29 .skillId = {.skillName = "ZeroTorque"},
30 .description = "Enables zero torque mode for the runtime",
31 .rootProfileDefaults = defaults.toAron(),
32 .timeout = ::armarx::Duration::Minutes(10),
33 .parametersType = ParamType::ToAronType(),
34 };
35 }
36
37 ZeroTorque::ZeroTorque(const config::ZeroTorque& r) :
38 ::armarx::skills::SimpleSpecializedSkill<params::ZeroTorque>(GetSkillDescription()),
39 config_(r)
40 {
41 }
42
44 ZeroTorque::main(const SpecializedMainInput& in)
45 {
47 ARMARX_CHECK_NOT_NULL(controller_);
48
49 // Config
50 const armarx::Duration maxDurationPerCleanUpStep = armarx::Duration::Seconds(5);
51
52 // Auxiliary variables to avoid re-computation
53 bool terminate = false;
54 bool isControllerActive = false;
55
56 // Information on history, to distinguish between a not-yet active and a no-longer active
57 // controller, and to distinguish between self-determined and implicit termination
58 bool hasControllerBeenActive = false;
59 bool hasTerminationBeenRequested = false;
60
61 // Request activation of controller
62 ARMARX_INFO << "Requesting to start the zero-torque controller.";
63 try
64 {
65 controller_->activateController();
66 }
67 catch (const Ice::Exception& e)
68 {
69 ARMARX_WARNING << "Failed to request the controller getting activated: " << e.what();
71 }
72
73 // Let the controller run (or complete its start up phase), until it shall terminate
74 /**
75 * Termination conditions:
76 * - Explicit request for the skill to terminate
77 * - The controller is no longer active, e.g., due to having been kicked out by another
78 * controller
79 */
80 do
81 {
82 // Fetch information on current status and conclude whether to terminate
83 hasControllerBeenActive = isControllerActive;
84 isControllerActive = controller_->isControllerActive();
85 hasTerminationBeenRequested = shouldSkillTerminate();
86 terminate =
87 hasTerminationBeenRequested or (hasControllerBeenActive and not isControllerActive);
88
89 // Inform exactly once about the controller having gotten active
90 if (not hasControllerBeenActive and isControllerActive)
91 {
92 ARMARX_INFO << "Controller is now active.";
93 }
94
95 // Avoid waiting and respective logging if termination is about to happen
96 if (not terminate)
97 {
98 ARMARX_VERBOSE << deactivateSpam(10) << "ZeroTorque controller is active. "
99 << "Waiting for termination request or controller getting inactive.";
101 }
102 } while (not terminate);
103 ARMARX_INFO << "Terminating the zero-torque controller. Current state:\n"
104 << "explicit termination request: " << hasTerminationBeenRequested << "\n"
105 << "controller has been active: " << hasControllerBeenActive << "\n"
106 << "controller is (still) active: " << isControllerActive;
107
108 // Clean up, but only as far as it has not already been done
109 if (armarx::NJointZeroTorqueControllerInterfacePrx::uncheckedCast(controller_))
110 {
111 // Controller is still present, at least needs to be deleted
112
113 if (controller_->isControllerActive())
114 {
115 // Controller also needs to be deactivated
116 try
117 {
118 ARMARX_INFO << "About to deactivate the controller";
119 controller_->deactivateController();
120 }
121 catch (const Ice::Exception& e)
122 {
123 ARMARX_WARNING << "Failed to request the controller getting deactivated: "
124 << e.what();
126 }
127
128 armarx::DateTime deactivationStartTime = armarx::DateTime::Now();
129 while (controller_->isControllerActive())
130 {
132 << "Waiting for the controller to get deactivated.";
134
135 if (armarx::DateTime::Now() - deactivationStartTime > maxDurationPerCleanUpStep)
136 {
137 ARMARX_WARNING << "Trying to deactivate the controller timed out: "
138 << armarx::DateTime::Now() - deactivationStartTime;
140 }
141 }
142 }
143
144 // The controller should still be existent. However, skipp its deletion if this is not
145 // the case anymore.
146
147 // if (context_.robotUnitPlugin_->getRobotUnit()->getNJointControllerStatus(controllerName_))
148 // if (context_.robotUnitPlugin_->getRobotUnit()->getNJointController(controllerName_)->isDeletable())
149 // TODO: find a way to check if deletion is still needed; the options above produced
150 // false-positives
151 if (false)
152 {
153 try
154 {
155 ARMARX_INFO << "About to delete the controller";
156 controller_->deleteController();
157 }
158 catch (const Ice::Exception& e)
159 {
160 ARMARX_WARNING << "Failed to request the controller getting deleted: "
161 << e.what();
163 }
164 armarx::DateTime deactivationStartTime = armarx::DateTime::Now();
165 while (armarx::NJointZeroTorqueControllerInterfacePrx::uncheckedCast(controller_))
166 {
168 << "Waiting for the controller to get deleted.";
170
171 if (armarx::DateTime::Now() - deactivationStartTime > maxDurationPerCleanUpStep)
172 {
173 ARMARX_WARNING << "Trying to delete the controller timed out: "
174 << armarx::DateTime::Now() - deactivationStartTime;
176 }
177 }
178 }
179 else
180 {
181 //ARMARX_INFO << "Controller has already been deleted in the meanwhile.";
182 ARMARX_INFO << "Performing an additional explicit deletion of the controller is "
183 "not attempted at the moment.";
184 }
185 }
186
187 // Exit with respective status
188 if (hasTerminationBeenRequested)
189 {
190 if (hasControllerBeenActive)
191 {
193 }
194 else
195 {
196 ARMARX_INFO << "ZeroTorque controller has successfully been cleaned up, "
197 "but has never been active.";
199 }
200 }
201 else
202 {
203 ARMARX_INFO << "ZeroTorque controller has successfully been cleaned up, "
204 "but was terminated due to having gone inactive instead of "
205 "due to an explicit request.";
207 }
208 }
209
210 void
212 {
213 context_ = context;
214 }
215
219 {
221 ARMARX_CHECK_NOT_NULL(context_.virtualRobotReader);
222 auto robot = context_.virtualRobotReader->getRobot(config_.robotName);
223 ARMARX_CHECK_NOT_NULL(robot) << config_.robotName;
224
225 ARMARX_CHECK(context_.virtualRobotReader->synchronizeRobot(*robot, armarx::Clock::Now()));
226
228 NJointZeroTorqueControllerConfigPtr config(new NJointZeroTorqueControllerConfig());
229 config->maxTorque = 0;
230 controllerName_ = "ControlSkills_ZeroTorque_" + in.parameters.nodeSetName;
231
232 ARMARX_CHECK_EXPRESSION(robot->hasRobotNodeSet(in.parameters.nodeSetName))
233 << "RNS " << in.parameters.nodeSetName << " is unknown";
234 auto nodeSet = robot->getRobotNodeSet(in.parameters.nodeSetName);
235 for (auto& name : nodeSet->getNodeNames())
236 {
237 config->jointNames.push_back(name);
238 }
239 ARMARX_CHECK_GREATER(config->jointNames.size(), 0) << "RNS is empty!";
240 controller_ = armarx::NJointZeroTorqueControllerInterfacePrx::checkedCast(
241 context_.robotUnitPlugin_->getRobotUnit()->getNJointController(controllerName_));
242 if (not controller_)
243 {
244 controller_ = armarx::NJointZeroTorqueControllerInterfacePrx::checkedCast(
245 context_.robotUnitPlugin_->createNJointController(
246 armarx::RobotUnitControllerNames::NJointZeroTorqueController,
247 controllerName_,
248 config));
249 }
251 }
252
256 {
258 context_.robotUnitPlugin_->getRobotUnit()->deactivateAndDeleteNJointController(
259 controllerName_);
260 // controller_->deactivateAndDeleteController();
262 }
263
264} // namespace armarx::control::skills::skills
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
static DateTime Now()
Definition DateTime.cpp:51
static Duration Minutes(std::int64_t minutes)
Constructs a duration in minutes.
Definition Duration.cpp:96
static Duration Seconds(std::int64_t seconds)
Constructs a duration in seconds.
Definition Duration.cpp:72
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
Definition Duration.cpp:48
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition Logging.cpp:99
::armarx::skills::SkillDescription GetSkillDescription()
void connectTo(const Context &context)
ZeroTorque(const config::ZeroTorque &)
Represents a point in time.
Definition DateTime.h:25
Represents a duration.
Definition Duration.h:17
virtual InitResult init()
Override this method with the actual implementation.
Definition Skill.cpp:519
bool shouldSkillTerminate() const override
Returns whether the skill should terminate as soon as possible.
Definition Skill.cpp:469
virtual MainResult main()
Override this method with the actual implementation.
Definition Skill.cpp:542
virtual ExitResult exit()
Override this method with the actual implementation.
Definition Skill.cpp:535
#define ARMARX_CHECK_GREATER(lhs, rhs)
This macro evaluates whether lhs is greater (>) than rhs and if it turns out to be false it will thro...
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#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_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
This file offers overloads of toIce() and fromIce() functions for STL container types.
This file is part of ArmarX.
A result struct for skill exit function.
Definition Skill.h:69
A result struct for skill initialization.
Definition Skill.h:50
A result struct for th main method of a skill.
Definition Skill.h:62
#define ARMARX_TRACE
Definition trace.h:77