84int main(
int argc,
char *argv[])
86 bool headless =
false;
87 for (
int i = 1; i < argc; ++i)
88 if (std::string(argv[i]) ==
"--headless") headless =
true;
90 const fs::path root = repo_root();
91 if (!fs::exists(root /
"third_party/menagerie")) {
92 std::cerr <<
"third_party/menagerie/ not found - run:\n"
93 " cmake -B build -DFETCH_MENAGERIE=ON\n";
97 const std::string mjcf = (root /
"third_party/menagerie/kinova_gen3/gen3.xml").
string();
98 const std::string grp_mjcf = (root /
"third_party/menagerie/robotiq_2f85/2f85.xml").
string();
99 const std::string table_mjcf = (root /
"src/examples/assets/table.xml").
string();
102 const double surface_z = 0.7;
108 gs.
pos[2] = -0.061525;
112 r.
path = mjcf.c_str();
113 r.
pos[2] = surface_z;
119 .mjcf_path = table_mjcf,
120 .pos = { 0.0, 0.0, surface_z },
125 make_box(
"red_cube", 0.35, 0.10, 0.03, 0.03, 0.03, 1.0f, 0.2f, 0.2f, surface_z)
128 make_box(
"green_cube", 0.35, -0.10, 0.03, 0.03, 0.03, 0.2f, 1.0f, 0.2f, surface_z)
131 make_box(
"blue_cube", 0.35, 0.30, 0.04, 0.04, 0.04, 0.2f, 0.2f, 1.0f, surface_z)
134 make_sphere(
"orange_sphere", -0.20, 0.20, 0.035, 1.0f, 0.55f, 0.0f, surface_z)
137 make_sphere(
"purple_sphere", -0.20, -0.20, 0.025, 0.7f, 0.0f, 0.9f, surface_z)
144 .pos = { 0.0, -0.6, 1.6 },
145 .euler = { 34.0, 0.0, 0.0 },
150 .pos = { -1.0, 0.0, 1.1 },
151 .euler = { 0.0, -68.0, 0.0 },
155 mjModel *model =
nullptr;
156 mjData *data =
nullptr;
159 std::cerr <<
"build_scene() failed\n";
163 KDL::Frame world_T_table_top;
166 std::cerr <<
"table_top site not found\n";
170 std::cout <<
"table top z = " << world_T_table_top.p.z() <<
"\n";
172 std::cout <<
"cameras:";
174 std::cout <<
" " << name;
180 &robot, model, data,
"base_link",
"bracelet_link",
"", &tool
182 std::cerr <<
"init_robot_from_mjcf() failed\n";
187 unsigned n =
static_cast<unsigned>(robot.
n_joints);
188 KDL::ChainFkSolverPos_recursive fk(robot.
chain);
189 KDL::ChainDynParam dyn(robot.
chain, KDL::Vector(0.0, 0.0, sc.
gravity_z));
191 KDL::JntArray q_home(n);
192 for (
unsigned i = 0; i < n; ++i) q_home(i) = kHomePose[i];
194 int fingers_act = mj_name2id(model, mjOBJ_ACTUATOR,
"g_fingers_actuator");
206 if (fingers_act >= 0) data->ctrl[fingers_act] = 255.0;
211 KDL::JntArray q(n), g(n);
212 auto ctrl_step = [&]() {
214 for (
unsigned i = 0; i < n; ++i) q(i) = robot.
jnt_pos_msr[i];
215 dyn.JntToGravity(q, g);
216 for (
unsigned i = 0; i < n; ++i) robot.
jnt_trq_cmd[i] = g(i);
217 if (fingers_act >= 0)
218 data->ctrl[fingers_act] = (std::fmod(data->time, 6.0) < 3.0) ? 255.0 : 0.0;
223 fk.JntToCart(q_home, ee_start);
225 for (
int step = 0; step < 500; ++step) {
230 KDL::JntArray q_end(n);
231 for (
unsigned i = 0; i < n; ++i) q_end(i) = robot.
jnt_pos_msr[i];
233 fk.JntToCart(q_end, ee_end);
234 double drift = (ee_start.p - ee_end.p).Norm();
235 std::cout <<
"EE drift after 500 steps: " << std::fixed << std::setprecision(3)
236 << drift * 1000.0 <<
" mm\n";
240 std::cerr <<
"init_window_sim() failed\n";
246 double prev_sim_time = data->time;
249 prev_sim_time = data->time;