8 #include <dynamic-graph/all-commands.h>
9 #include <dynamic-graph/factory.h>
13 #include <pinocchio/algorithm/joint-configuration.hpp>
14 #include <sot/core/debug.hh>
15 #include <tsid/math/constraint-base.hpp>
16 #include <tsid/math/utils.hpp>
20 using namespace sot::torque_control;
22 using namespace tsid::tasks;
27 const double DeviceTorqueCtrl::TIMESTEP_DEFAULT = 0.001;
28 const double DeviceTorqueCtrl::FORCE_SENSOR_NOISE_STD_DEV = 1e-10;
32 DeviceTorqueCtrl::DeviceTorqueCtrl(std::string RobotName)
33 :
dgsot::Device(RobotName),
34 timestep_(TIMESTEP_DEFAULT),
35 m_initSucceeded(false),
36 accelerometerSOUT_(
"DeviceTorqueCtrl(" + RobotName +
37 ")::output(vector)::accelerometer"),
38 gyrometerSOUT_(
"DeviceTorqueCtrl(" + RobotName +
39 ")::output(vector)::gyrometer"),
40 robotStateSOUT_(
"DeviceTorqueCtrl(" + RobotName +
41 ")::output(vector)::robotState"),
42 jointsVelocitiesSOUT_(
"DeviceTorqueCtrl(" + RobotName +
43 ")::output(vector)::jointsVelocities"),
44 jointsAccelerationsSOUT_(
"DeviceTorqueCtrl(" + RobotName +
45 ")::output(vector)::jointsAccelerations"),
46 currentSOUT_(
"DeviceTorqueCtrl(" + RobotName +
47 ")::output(vector)::currents"),
48 p_gainsSOUT_(
"DeviceTorqueCtrl(" + RobotName +
49 ")::output(vector)::p_gains"),
50 d_gainsSOUT_(
"DeviceTorqueCtrl(" + RobotName +
51 ")::output(vector)::d_gains"),
52 CONSTRUCT_SIGNAL_IN(kp_constraints,
dynamicgraph::Vector),
53 CONSTRUCT_SIGNAL_IN(kd_constraints,
dynamicgraph::Vector),
54 CONSTRUCT_SIGNAL_IN(rotor_inertias,
dynamicgraph::Vector),
58 m_isTorqueControlled(true),
59 m_numericalDamping(1e-8),
60 normalDistribution_(0.0, FORCE_SENSOR_NOISE_STD_DEV),
61 normalRandomNumberGenerator_(randomNumberGenerator_,
62 normalDistribution_) {
63 forcesSIN_[0] =
new SignalPtr<dynamicgraph::Vector, int>(
64 NULL,
"DeviceTorqueCtrl::input(vector6)::inputForceRLEG");
65 forcesSIN_[1] =
new SignalPtr<dynamicgraph::Vector, int>(
66 NULL,
"DeviceTorqueCtrl::input(vector6)::inputForceLLEG");
67 forcesSIN_[2] =
new SignalPtr<dynamicgraph::Vector, int>(
68 NULL,
"DeviceTorqueCtrl::input(vector6)::inputForceRARM");
69 forcesSIN_[3] =
new SignalPtr<dynamicgraph::Vector, int>(
70 NULL,
"DeviceTorqueCtrl::input(vector6)::inputForceLARM");
77 << m_kd_constraintsSIN << m_rotor_inertiasSIN
83 controlInputType_ = CONTROL_INPUT_TWO_INTEGRATION;
86 dynamicgraph::Vector data(3);
93 for (
int i = 0; i < 4; ++i) {
94 withForceSignals[i] =
true;
97 if (i == FORCE_SIGNAL_RLEG || i == FORCE_SIGNAL_LLEG)
105 using namespace dynamicgraph::command;
106 std::string docstring;
109 "\n Integrate dynamics for time step provided as input\n"
110 "\n take one floating point number as input\n\n";
111 addCommand(
"increment",
112 makeCommandVoid1((Device&)*
this, &Device::increment, docstring));
115 docCommandVoid2(
"Initialize the entity.",
116 "Time period in seconds (double)",
117 "Robot reference (string)")));
124 return SEND_MSG(
"Init failed: Timestep must be positive", MSG_TYPE_ERROR);
127 std::string localName(robotRef);
128 if (isNameInRobotUtil(localName))
131 SEND_MSG(
"You should first initialize the entity control-manager",
138 const dynamicgraph::sot::Vector6d& kp_contact = m_kp_constraintsSIN(0);
139 const dynamicgraph::sot::Vector6d& kd_contact = m_kd_constraintsSIN(0);
140 const Vector rotor_inertias = m_rotor_inertiasSIN(0);
141 const Vector gear_ratios = m_gear_ratiosSIN(0);
142 const std::string& urdfFile =
m_robot_util->m_urdf_filename;
145 vector<string> package_dirs;
146 m_robot =
new robots::RobotWrapper(urdfFile, package_dirs,
147 pinocchio::JointModelFreeFlyer());
149 m_robot->rotor_inertias(rotor_inertias);
150 m_robot->gear_ratios(gear_ratios);
169 new TaskSE3Equality(
"contact_rfoot", *
m_robot,
175 new TaskSE3Equality(
"contact_lfoot", *
m_robot,
179 }
catch (
const std::exception& e) {
180 std::cout << e.what();
181 return SEND_MSG(
"Init failed: Could load URDF :" + urdfFile,
190 assert(size ==
static_cast<unsigned int>(
m_nj + 6));
191 Device::setStateSize(size);
205 assert(q.size() ==
m_nj + 6);
207 SEND_WARNING_STREAM_MSG(
"Cannot setState before initialization!");
215 pinocchio::SE3 H_lf =
m_robot->position(
218 tsid::trajectories::TrajectorySample s(12, 6);
219 tsid::math::SE3ToVector(H_lf, s.pos);
221 SEND_MSG(
"Setting left foot reference to " + toString(H_lf), MSG_TYPE_DEBUG);
223 pinocchio::SE3 H_rf =
m_robot->position(
226 tsid::math::SE3ToVector(H_rf, s.pos);
228 SEND_MSG(
"Setting right foot reference to " + toString(H_rf), MSG_TYPE_DEBUG);
233 assert(v.size() ==
m_nj + 6);
235 SEND_WARNING_STREAM_MSG(
"Cannot setVelocity before initialization!");
238 Device::setVelocity(v);
244 if (cit ==
"torque") {
249 return Device::setControlInputType(cit);
253 const Vector& tauDes = controlSIN.accessCopy();
254 assert(tauDes.size() ==
m_nj);
261 assert(constrRF.matrix().rows() == 6 && constrRF.matrix().cols() ==
m_nj + 6);
262 assert(constrLF.matrix().rows() == 6 && constrLF.matrix().cols() ==
m_nj + 6);
263 assert(constrRF.vector().size() == 6 && constrLF.vector().size() == 6);
265 assert(
m_K.rows() ==
m_nj + 6 + 12 &&
m_K.cols() ==
m_nj + 6 + 12);
266 m_Jc.topRows<6>() = constrRF.matrix();
267 m_Jc.bottomRows<6>() = constrLF.matrix();
268 Matrix JcT =
m_Jc.transpose();
269 m_dJcv.head<6>() = constrRF.vector();
270 m_dJcv.tail<6>() = constrLF.vector();
273 m_Jc_svd.compute(
m_Jc, Eigen::ComputeThinU | Eigen::ComputeFullV);
278 Eigen::VectorXd::Index r = (
m_Jc_svd.singularValues().array() > 1e-8).count();
294 SEND_MSG(
"ZMZ*dv - ZT*(tau-h-Mdv_bar) = " +
318 if ((JcT *
m_f - b).norm() > 1e-10)
319 SEND_MSG(
"M*dv +h - JT*f - tau = " + toString((JcT *
m_f - b).norm()),
322 SEND_MSG(
"Jc*dv - dJc*v = " + toString((
m_Jc *
m_dv -
m_dJcv).norm()),
328 SEND_WARNING_STREAM_MSG(
"Cannot integrate before initialization!");
346 Device::integrate(dt);
347 if (controlInputType_ == CONTROL_INPUT_TWO_INTEGRATION)
363 for (
int i = 0; i < 4; i++) {
369 for (
int j = 0; j < 6; j++)
372 forcesSOUT[i]->setConstant(
temp6_);
380 for (
int i = 0; i < 4; ++i) forcesSOUT[i]->setTime(time);