17#include <gtest/gtest.h>
24static constexpr double kHomePose[7] = { 0.0, 0.2618, 3.1416, -2.2689, 0.0, 0.9599, 1.5708 };
25static constexpr double kTargetPose[7] = { 0.3, 0.5, 2.9, -2.0, 0.3, 1.2, 1.3 };
26static constexpr double kKv = 2.0;
27static constexpr double kMaxVel = 0.6;
28static constexpr double kTol = 0.02;
29static constexpr double kTimeout = 5.0;
31namespace fs = std::filesystem;
44 if (!fs::exists(arm_mjcf)) {
45 GTEST_SKIP() << arm_mjcf <<
" not found";
58 n_ =
static_cast<unsigned>(
s_.n_joints);
60 KDL::JntArray q_home(
n_);
61 for (
unsigned i = 0; i <
n_; ++i) q_home(i) = kHomePose[i];
66 for (
unsigned i = 0; i <
n_; ++i) {
s_.jnt_pos_cmd[i] = kHomePose[i]; }
81 const double dt = model_->opt.timestep;
84 while (data_->time < kTimeout && !arrived) {
88 for (
unsigned i = 0; i < n_; ++i) {
89 double err = kTargetPose[i] - s_.jnt_pos_msr[i];
90 max_err = std::max(max_err, std::abs(err));
91 double vel = std::clamp(kKv * err, -kMaxVel, kMaxVel);
92 s_.jnt_pos_cmd[i] += vel * dt;
98 for (
unsigned i = 0; i < n_; ++i) s_.jnt_pos_cmd[i] = s_.jnt_pos_msr[i];
104 double max_err = 0.0;
105 for (
unsigned i = 0; i < n_; ++i)
106 max_err = std::max(max_err, std::abs(kTargetPose[i] - s_.jnt_pos_msr[i]));
108 EXPECT_TRUE(arrived) <<
"velocity controller did not converge within " << kTimeout <<
" s";
109 EXPECT_LE(max_err, kTol * 2);
112int main(
int argc,
char *argv[])
114 testing::InitGoogleTest(&argc, argv);
115 return RUN_ALL_TESTS();
bool init_robot_from_mjcf(Robot *r, mjModel *model, mjData *data, const char *base_body, const char *tip_body, const char *prefix="", const ToolFrameSpec *tool=nullptr)
void set_joint_pos(Robot *r, const KDL::JntArray &q, bool call_forward=true)
bool build_scene(mjModel **out_model, mjData **out_data, const SceneSpec *spec)
void destroy_scene(mjModel *model, mjData *data)
std::string find_menagerie_model(const fs::path &relative)
std::vector< RobotSpec > robots
int main(int argc, char *argv[])
TEST_F(MjcfVelCtrlTest, Convergence)