17 #include <dynamic-graph/all-commands.h>
18 #include <dynamic-graph/factory.h>
20 #include <sot/core/debug.hh>
21 #include <sot/core/stop-watch.hh>
27 namespace talos_balance {
31 using namespace dynamicgraph::command;
33 using namespace dg::sot::talos_balance;
36 #define PROFILE_PWM_DESIRED_COMPUTATION \
38 #define PROFILE_DYNAMIC_GRAPH_PERIOD \
41 #define INPUT_SIGNALS m_u_maxSIN
42 #define OUTPUT_SIGNALS m_uSOUT << m_u_safeSOUT
59 m_robot_util(RefVoidRobotUtil()),
60 m_initSucceeded(false),
61 m_emergency_stop_triggered(false),
62 m_is_first_iter(true),
70 docCommandVoid2(
"Initialize the entity.",
71 "Time period in seconds (double)",
72 "Robot reference (string)")));
73 addCommand(
"addCtrlMode",
76 docCommandVoid1(
"Create an input signal with name 'ctrl_x' "
77 "where x is the specified name.",
84 docCommandVoid0(
"Get a list of all the available control modes.")));
90 docCommandVoid2(
"Set the control mode for a joint.",
91 "(string) joint name",
"(string) control mode")));
96 docCommandVoid1(
"Get the control mode of a joint.",
97 "(string) joint name")));
99 addCommand(
"resetProfiler",
102 docCommandVoid0(
"Reset the statistics computed by the "
103 "profiler (print this entity to see them).")));
106 "addEmergencyStopSIN",
109 docCommandVoid1(
"Add emergency signal input from another entity that "
110 "can stop the control if necessary.",
111 "(string) signal name : 'emergencyStop_' + name")));
113 addCommand(
"isEmergencyStopTriggered",
116 docDirectGetter(
"Check whether emergency stop is triggered",
121 if (
dt <= 0.0)
return SEND_MSG(
"Timestep must be positive", MSG_TYPE_ERROR);
125 vector<string> package_dirs;
126 std::string localName(robotRef);
127 if (!isNameInRobotUtil(localName)) {
128 SEND_MSG(
"You should have a robotUtil pointer initialized before",
147 if (!m_initSucceeded) {
148 SEND_MSG(
"Cannot compute signal u before initialization!",
153 if (m_is_first_iter) m_is_first_iter =
false;
159 for (
unsigned int i = 0; i < m_ctrlInputsSIN.size(); i++)
160 (*m_ctrlInputsSIN[i])(iter);
162 int cm_id, cm_id_prev;
163 for (
unsigned int i = 0; i < m_numDofs; i++) {
164 cm_id = m_jointCtrlModes_current[i].id;
166 SEND_MSG(
"You forgot to set the control mode of joint " + toString(i),
167 MSG_TYPE_ERROR_STREAM);
172 assert(ctrl.size() == m_numDofs);
174 if (m_jointCtrlModesCountDown[i] == 0)
177 cm_id_prev = m_jointCtrlModes_previous[i].id;
179 (*m_ctrlInputsSIN[cm_id_prev])(iter);
180 assert(ctrl_prev.size() == m_numDofs);
188 s(i) = alpha * ctrl_prev(i) + (1 - alpha) * ctrl(i);
189 m_jointCtrlModesCountDown[i]--;
191 if (m_jointCtrlModesCountDown[i] == 0) {
192 SEND_MSG(
"Joint " + toString(i) +
" changed ctrl mode from " +
193 toString(cm_id_prev) +
" to " + toString(cm_id),
195 updateJointCtrlModesOutputSignal();
216 if (!m_initSucceeded) {
217 SEND_WARNING_STREAM_MSG(
218 "Cannot compute signal u_safe before initialization!");
226 for (
size_t i = 0; i < m_emergencyStopVector.size(); i++) {
227 if ((*m_emergencyStopVector[i]).isPlugged() &&
228 (*m_emergencyStopVector[i])(iter)) {
229 m_emergency_stop_triggered =
true;
231 "t = " + toString(iter) +
232 ": Emergency Stop has been triggered by an external entity: " +
233 (*m_emergencyStopVector[i]).getName(),
238 if (!m_emergency_stop_triggered) {
239 for (
unsigned int i = 0; i < m_numDofs; i++) {
240 if (fabs(u(i)) > ctrl_max(i)) {
241 m_emergency_stop_triggered =
true;
242 SEND_MSG(
"t = " + toString(iter) +
": Joint " + toString(i) +
243 " desired control is too large: " + toString(u(i)) +
244 " > " + toString(ctrl_max(i)),
245 MSG_TYPE_ERROR_STREAM);
253 if (m_emergency_stop_triggered) s.setZero();
262 for (
unsigned int i = 0; i <
m_ctrlModes.size(); i++)
264 return SEND_MSG(
"It already exists a control mode with name " +
name,
269 NULL, getClassName() +
"(" + getName() +
270 ")::input(dynamicgraph::Vector)::ctrl_" +
name));
275 getClassName() +
"(" + getName() +
276 ")::output(dynamicgraph::Vector)::joints_ctrl_mode_" +
name));
295 const string& ctrlMode) {
299 if (jointName ==
"all") {
303 std::stringstream ss(jointName);
305 std::list<int> jIdList;
307 while (std::getline(ss, item,
'-')) {
308 SEND_MSG(
"parsed joint : " + item, MSG_TYPE_INFO);
311 for (std::list<int>::iterator it = jIdList.begin(); it != jIdList.end();
320 return SEND_MSG(
"Cannot change control mode of joint " + toString(jid) +
321 " because its previous ctrl mode transition has not "
327 return SEND_MSG(
"Cannot change control mode of joint " + toString(jid) +
328 " because it has already the specified ctrl mode",
343 if (jointName ==
"all") {
345 for (
unsigned int i = 0; i <
m_numDofs; i++)
347 SEND_MSG(ss.str(), MSG_TYPE_INFO);
353 SEND_MSG(
"The control mode of joint " + jointName +
" is " +
359 getProfiler().reset_all();
370 return SEND_MSG(
"Sleep time cannot be negative!", MSG_TYPE_ERROR);
375 SEND_MSG(
"New emergency signal input emergencyStop_" +
name +
" created",
379 NULL, getClassName() +
"(" + getName() +
380 ")::input(bool)::emergencyStop_" +
name));
393 SEND_MSG(
"You should call init first. The size of the vector is unknown.",
400 for (
unsigned int j = 0; j <
m_numDofs; j++) {
416 for (
unsigned int i = 0; i <
m_ctrlModes.size(); i++)
421 SEND_MSG(
"The specified control mode does not exist", MSG_TYPE_ERROR);
422 SEND_MSG(
"Possible control modes are: " + toString(
m_ctrlModes),
434 SEND_MSG(
"The specified joint name does not exist: " +
name,
436 std::stringstream ss;
437 for (
size_t it = 0; it <
m_numDofs; it++) ss << toString(it) <<
", ";
438 SEND_MSG(
"Possible joint names are: " + ss.str(), MSG_TYPE_INFO);
441 id = (
unsigned int)jid;
472 os <<
"TalosControlManager " << getName();
474 getProfiler().report_all(3, os);
475 }
catch (ExceptionSignal e) {