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;
17 explicit AchdController(admittance_ft::SceneHandles &handles)
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)),
24 qdd(h.robot.n_joints),
26 ff_tau(h.robot.n_joints),
27 constraint_tau(h.robot.n_joints),
28 tau(h.robot.n_joints),
30 f_ext_achd(h.robot.chain.getNrOfSegments(), KDL::Wrench::Zero()),
31 f_ext_rnea(h.robot.chain.getNrOfSegments(), KDL::Wrench::Zero())
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)));
41 const char *name()
const override {
return "ex_admittance_ft_achd"; }
46 err_prev = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
50 void track(
const KDL::Frame &target)
override
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() };
59 for (
unsigned i = 0; i < 6; ++i) err_prev[i] = e[i];
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];
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) {
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];
88 admittance_ft::SceneHandles &h;
89 KDL::ChainFkSolverPos_recursive fk;
90 KDL::ChainHdSolver_Vereshchagin_Fixed_Joint achd;
91 KDL::ChainIdSolver_RNE rnea;
97 KDL::JntArray constraint_tau;
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;
108 return std::make_unique<AchdController>(h);
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)