Mujoco KDL Wrapper  0.2.2
MuJoCo + KDL bridge for robot kinematics and dynamics
Loading...
Searching...
No Matches
ex_admittance_ft_rnea.cpp
Go to the documentation of this file.
2
3namespace
4{
5
6static constexpr double kKpLin = 11520.0;
7static constexpr double kKdLin = 514.3;
8static constexpr double kKpRot = 7200.0;
9static constexpr double kKdRot = 600.1;
10static constexpr double kBetaLinMax = 7200.0;
11static constexpr double kBetaRotMax = 5040.0;
12static constexpr double kTauMax = 141.6;
13
14class RneaTaskController final : public admittance_ft::Controller
15{
16public:
17 explicit RneaTaskController(admittance_ft::SceneHandles &handles)
18 : h(handles),
19 fk(h.robot.chain),
20 jac_solver(h.robot.chain),
21 ik_acc(h.robot.chain),
22 rnea(h.robot.chain, KDL::Vector(0.0, 0.0, h.scene.gravity_z)),
23 q(h.robot.n_joints),
24 qd(h.robot.n_joints),
25 qdd(h.robot.n_joints),
26 tau(h.robot.n_joints),
27 jac(h.robot.n_joints),
28 f_ext(h.robot.chain.getNrOfSegments(), KDL::Wrench::Zero())
29 {
30 ik_acc.setLambda(0.10);
31 }
32
33 const char *name() const override { return "ex_admittance_ft_rnea"; }
34 mj_kdl::CtrlMode mode() const override { return mj_kdl::CtrlMode::TORQUE; }
35 void reset() override {}
36
37 void track(const KDL::Frame &target) override
38 {
39 fill_state();
40 KDL::Frame current;
41 fk.JntToCart(q, current);
42 const KDL::Twist err = KDL::diff(current, target);
43
44 jac_solver.JntToJac(q, jac);
45 const KDL::Twist tcp_vel = jacobian_twist();
46
47 const KDL::Twist beta(
48 KDL::Vector(
49 admittance_ft::clamp(kKpLin * err.vel.x() - kKdLin * tcp_vel.vel.x(), -kBetaLinMax, kBetaLinMax),
50 admittance_ft::clamp(kKpLin * err.vel.y() - kKdLin * tcp_vel.vel.y(), -kBetaLinMax, kBetaLinMax),
51 admittance_ft::clamp(kKpLin * err.vel.z() - kKdLin * tcp_vel.vel.z(), -kBetaLinMax, kBetaLinMax)
52 ),
53 KDL::Vector(
54 admittance_ft::clamp(kKpRot * err.rot.x() - kKdRot * tcp_vel.rot.x(), -kBetaRotMax, kBetaRotMax),
55 admittance_ft::clamp(kKpRot * err.rot.y() - kKdRot * tcp_vel.rot.y(), -kBetaRotMax, kBetaRotMax),
56 admittance_ft::clamp(kKpRot * err.rot.z() - kKdRot * tcp_vel.rot.z(), -kBetaRotMax, kBetaRotMax)
57 )
58 );
59
60 if (ik_acc.CartToJnt(q, beta, qdd) < 0) return;
61 if (rnea.CartToJnt(q, qd, qdd, f_ext, tau) < 0) return;
62 for (int i = 0; i < h.robot.n_joints; ++i) {
63 h.robot.jnt_trq_cmd[i] = admittance_ft::clamp(tau(i), -kTauMax, kTauMax);
64 }
65 }
66
67private:
68 void fill_state()
69 {
70 for (int i = 0; i < h.robot.n_joints; ++i) {
71 q(i) = h.robot.jnt_pos_msr[i];
72 qd(i) = h.robot.jnt_vel_msr[i];
73 }
74 }
75
76 KDL::Twist jacobian_twist() const
77 {
78 KDL::Twist out = KDL::Twist::Zero();
79 for (unsigned j = 0; j < q.rows(); ++j) {
80 out.vel.x(out.vel.x() + jac(0, j) * qd(j));
81 out.vel.y(out.vel.y() + jac(1, j) * qd(j));
82 out.vel.z(out.vel.z() + jac(2, j) * qd(j));
83 out.rot.x(out.rot.x() + jac(3, j) * qd(j));
84 out.rot.y(out.rot.y() + jac(4, j) * qd(j));
85 out.rot.z(out.rot.z() + jac(5, j) * qd(j));
86 }
87 return out;
88 }
89
90 admittance_ft::SceneHandles &h;
91 KDL::ChainFkSolverPos_recursive fk;
92 KDL::ChainJntToJacSolver jac_solver;
93 KDL::ChainIkSolverVel_wdls ik_acc;
94 KDL::ChainIdSolver_RNE rnea;
95 KDL::JntArray q;
96 KDL::JntArray qd;
97 KDL::JntArray qdd;
98 KDL::JntArray tau;
99 KDL::Jacobian jac;
100 KDL::Wrenches f_ext;
101};
102
103std::unique_ptr<admittance_ft::Controller> make_controller(admittance_ft::SceneHandles &h)
104{
105 return std::make_unique<RneaTaskController>(h);
106}
107
108} // namespace
109
110int main(int argc, char **argv)
111{
112 return admittance_ft::run(argc, argv, make_controller);
113}
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)
list[float] jacobian_twist(kdl.Jacobian jac, kdl.JntArray qdot)