Mujoco KDL Wrapper  0.2.2
MuJoCo + KDL bridge for robot kinematics and dynamics
Loading...
Searching...
No Matches
ex_admittance_ft_achd.cpp
Go to the documentation of this file.
2
3namespace
4{
5
6static constexpr double kKpLin = 5760.0;
7static constexpr double kKdLin = 378.0;
8static constexpr double kKpRot = 3600.0;
9static constexpr double kKdRot = 441.0;
10static constexpr double kBetaLinMax = 3600.0;
11static constexpr double kBetaRotMax = 2520.0;
12static constexpr double kTauMax = 212.4;
13
14class AchdController final : public admittance_ft::Controller
15{
16public:
17 explicit AchdController(admittance_ft::SceneHandles &handles)
18 : h(handles),
19 fk(h.robot.chain),
20 achd(h.robot.chain, KDL::Twist(KDL::Vector(0.0, 0.0, -h.scene.gravity_z), KDL::Vector::Zero()), 6),
21 rnea(h.robot.chain, KDL::Vector(0.0, 0.0, h.scene.gravity_z)),
22 q(h.robot.n_joints),
23 qd(h.robot.n_joints),
24 qdd(h.robot.n_joints),
25 beta(6),
26 ff_tau(h.robot.n_joints),
27 constraint_tau(h.robot.n_joints),
28 tau(h.robot.n_joints),
29 alpha(6),
30 f_ext_achd(h.robot.chain.getNrOfSegments(), KDL::Wrench::Zero()),
31 f_ext_rnea(h.robot.chain.getNrOfSegments(), KDL::Wrench::Zero())
32 {
33 alpha.setColumn(0, KDL::Twist(KDL::Vector(1, 0, 0), KDL::Vector(0, 0, 0)));
34 alpha.setColumn(1, KDL::Twist(KDL::Vector(0, 1, 0), KDL::Vector(0, 0, 0)));
35 alpha.setColumn(2, KDL::Twist(KDL::Vector(0, 0, 1), KDL::Vector(0, 0, 0)));
36 alpha.setColumn(3, KDL::Twist(KDL::Vector(0, 0, 0), KDL::Vector(1, 0, 0)));
37 alpha.setColumn(4, KDL::Twist(KDL::Vector(0, 0, 0), KDL::Vector(0, 1, 0)));
38 alpha.setColumn(5, KDL::Twist(KDL::Vector(0, 0, 0), KDL::Vector(0, 0, 1)));
39 }
40
41 const char *name() const override { return "ex_admittance_ft_achd"; }
42 mj_kdl::CtrlMode mode() const override { return mj_kdl::CtrlMode::TORQUE; }
43
44 void reset() override
45 {
46 err_prev = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
47 first_pid = true;
48 }
49
50 void track(const KDL::Frame &target) override
51 {
52 fill_state();
53 KDL::Frame current;
54 fk.JntToCart(q, current);
55 const KDL::Twist err = KDL::diff(current, target);
56 const double dt = h.model ? h.model->opt.timestep : 0.002;
57 const double e[6] = { err.vel.x(), err.vel.y(), err.vel.z(), err.rot.x(), err.rot.y(), err.rot.z() };
58 if (first_pid) {
59 for (unsigned i = 0; i < 6; ++i) err_prev[i] = e[i];
60 first_pid = false;
61 }
62
63 beta(0) = admittance_ft::clamp(kKpLin * e[0] + kKdLin * ((e[0] - err_prev[0]) / dt), -kBetaLinMax, kBetaLinMax);
64 beta(1) = admittance_ft::clamp(kKpLin * e[1] + kKdLin * ((e[1] - err_prev[1]) / dt), -kBetaLinMax, kBetaLinMax);
65 beta(2) = admittance_ft::clamp(kKpLin * e[2] + kKdLin * ((e[2] - err_prev[2]) / dt), -kBetaLinMax, kBetaLinMax);
66 beta(3) = admittance_ft::clamp(kKpRot * e[3] + kKdRot * ((e[3] - err_prev[3]) / dt), -kBetaRotMax, kBetaRotMax);
67 beta(4) = admittance_ft::clamp(kKpRot * e[4] + kKdRot * ((e[4] - err_prev[4]) / dt), -kBetaRotMax, kBetaRotMax);
68 beta(5) = admittance_ft::clamp(kKpRot * e[5] + kKdRot * ((e[5] - err_prev[5]) / dt), -kBetaRotMax, kBetaRotMax);
69 for (unsigned i = 0; i < 6; ++i) err_prev[i] = e[i];
70
71 KDL::SetToZero(ff_tau);
72 if (achd.CartToJnt(q, qd, qdd, alpha, beta, f_ext_achd, ff_tau, constraint_tau) < 0) return;
73 if (rnea.CartToJnt(q, qd, qdd, f_ext_rnea, tau) < 0) return;
74 for (int i = 0; i < h.robot.n_joints; ++i) {
75 h.robot.jnt_trq_cmd[i] = admittance_ft::clamp(tau(i), -kTauMax, kTauMax);
76 }
77 }
78
79private:
80 void fill_state()
81 {
82 for (int i = 0; i < h.robot.n_joints; ++i) {
83 q(i) = h.robot.jnt_pos_msr[i];
84 qd(i) = h.robot.jnt_vel_msr[i];
85 }
86 }
87
88 admittance_ft::SceneHandles &h;
89 KDL::ChainFkSolverPos_recursive fk;
90 KDL::ChainHdSolver_Vereshchagin_Fixed_Joint achd;
91 KDL::ChainIdSolver_RNE rnea;
92 KDL::JntArray q;
93 KDL::JntArray qd;
94 KDL::JntArray qdd;
95 KDL::JntArray beta;
96 KDL::JntArray ff_tau;
97 KDL::JntArray constraint_tau;
98 KDL::JntArray tau;
99 KDL::Jacobian alpha;
100 KDL::Wrenches f_ext_achd;
101 KDL::Wrenches f_ext_rnea;
102 std::array<double, 6> err_prev = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
103 bool first_pid = true;
104};
105
106std::unique_ptr<admittance_ft::Controller> make_controller(admittance_ft::SceneHandles &h)
107{
108 return std::make_unique<AchdController>(h);
109}
110
111} // namespace
112
113int main(int argc, char **argv)
114{
115 return admittance_ft::run(argc, argv, make_controller);
116}
int main(int argc, char **argv)
ResetInfo reset(Env *env, const ResetOptions *options=nullptr)
int run(int argc, char **argv, std::unique_ptr< Controller >(*make_controller)(SceneHandles &))
double clamp(double v, double lo, double hi)