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