120int main(
int argc,
char *argv[])
122 bool headless =
false;
123 for (
int i = 1; i < argc; ++i)
124 if (std::string(argv[i]) ==
"--headless") headless =
true;
126 const fs::path root = repo_root();
127 if (!fs::exists(root /
"third_party/menagerie")) {
128 std::cerr <<
"third_party/menagerie/ not found - run: "
129 "git submodule update --init third_party/menagerie\n";
134 const std::string arm_mjcf = (root /
"third_party/menagerie/kinova_gen3/gen3.xml").
string();
135 const std::string grp_mjcf = (root /
"third_party/menagerie/robotiq_2f85/2f85.xml").
string();
141 gs.
pos[2] = -0.061525;
145 rs.
path = arm_mjcf.c_str();
152 cube.
pos[0] = kCubeX;
153 cube.
pos[1] = kCubeY;
154 cube.
pos[2] = kCubeZ;
169 mjModel *model =
nullptr;
170 mjData *data =
nullptr;
172 std::cerr <<
"build_scene() failed\n";
178 &robot, model, data,
"base_link",
"bracelet_link",
"",
"g_base"
180 std::cerr <<
"init_robot_from_mjcf() failed\n";
185 unsigned n = robot.
chain.getNrOfJoints();
186 int fingers_act = mj_name2id(model, mjOBJ_ACTUATOR,
"g_fingers_actuator");
187 int cube_jnt = mj_name2id(model, mjOBJ_JOINT,
"cube_joint");
188 int key_id = mj_name2id(model, mjOBJ_KEY,
"home");
190 KDL::ChainDynParam dyn(robot.
chain, KDL::Vector(0.0, 0.0, -9.81));
193 KDL::ChainFkSolverPos_recursive fk(robot.
chain);
194 KDL::JntArray q_min(n), q_max(n);
195 for (
unsigned i = 0; i < n; ++i) {
197 if (model->jnt_limited[jid]) {
198 q_min(i) = model->jnt_range[2 * jid];
199 q_max(i) = model->jnt_range[2 * jid + 1];
201 q_min(i) = -2 * M_PI;
205 KDL::ChainIkSolverVel_pinv ik_vel(robot.
chain);
206 KDL::ChainIkSolverPos_NR_JL ik(robot.
chain, q_min, q_max, fk, ik_vel, 500, 1e-5);
208 const double kGraspZ = kCubeZ + kGripperReach + 0.02;
209 const double kPreGraspZ = kGraspZ + 0.20;
210 const double kLiftZ = kGraspZ + 0.30;
211 const KDL::Rotation kDownRot = KDL::Rotation::Identity();
213 KDL::JntArray q_home(n), q_pregrasp(n), q_grasp(n), q_lift(n);
214 for (
unsigned i = 0; i < n; ++i) q_home(i) = kHomePose[i];
220 const KDL::JntArray *seed;
223 { kPreGraspZ, &q_pregrasp, &q_home },
224 { kGraspZ, &q_grasp, &q_pregrasp },
225 { kLiftZ, &q_lift, &q_grasp },
227 for (
auto &wp : wps) {
228 KDL::Frame tgt(kDownRot, KDL::Vector(kCubeX, kCubeY, wp.z));
229 if (ik.CartToJnt(*wp.seed, tgt, *wp.out) < 0)
230 std::cerr <<
"IK warning: did not converge for z=" << wp.z <<
"\n";
238 const double kHoldDuration = headless ? 1.0 : 1e9;
247 { kHoldDuration, kHoldDuration, -1.0, &q_lift, 255.0,
PickState::DONE },
255 auto reset_cube = [&](mjData *d) {
256 int qadr = model->jnt_qposadr[cube_jnt];
257 d->qpos[qadr + 0] = kCubeX;
258 d->qpos[qadr + 1] = kCubeY;
259 d->qpos[qadr + 2] = kCubeZ;
260 d->qpos[qadr + 3] = 1.0;
261 d->qpos[qadr + 4] = d->qpos[qadr + 5] = d->qpos[qadr + 6] = 0.0;
266 auto seed_reset_state = [&](mjData *d) {
267 for (
unsigned i = 0; i < n; ++i) {
273 if (fingers_act >= 0) d->ctrl[fingers_act] = 0.0;
276 auto reset_scene = [&](mjData *d) {
278 mj_resetDataKeyframe(model, d, key_id);
280 mj_resetData(model, d);
284 mj_forward(model, d);
294 std::cerr <<
"init_window_sim() failed\n";
304 KDL::JntArray q_des(n);
309 snapshot_q(robot, n, sm.
q_enter);
314 double prev_sim_time = data->time;
321 if (data->time < prev_sim_time - 1e-6) {
324 prev_sim_time = data->time;
327 prev_sim_time = data->time;
330 double alpha = (state.
duration > 0.0)
336 impedance_ctrl(robot, q_des, n, dyn);
338 if (fingers_act >= 0) data->ctrl[fingers_act] = state.
gripper_cmd;
340 double t_rel = data->time - sm.
t_enter;
341 double pose_err = max_abs_joint_err(robot, *state.
q_target, n);
342 bool done_time = t_rel >= state.
duration;
344 bool done_timeout = (state.
timeout > 0.0) && (t_rel >= state.
timeout);
345 if ((done_time && done_pose) || done_timeout) {
346 begin_state(state.
next);
362 if (data->time < prev_sim_time - 1e-6) {
365 prev_sim_time = data->time;
368 prev_sim_time = data->time;
371 double alpha = (state.
duration > 0.0)
377 impedance_ctrl(robot, q_des, n, dyn);
379 if (fingers_act >= 0) data->ctrl[fingers_act] = state.
gripper_cmd;
381 double t_rel = data->time - sm.
t_enter;
382 double pose_err = max_abs_joint_err(robot, *state.
q_target, n);
383 bool done_time = t_rel >= state.
duration;
385 bool done_timeout = (state.
timeout > 0.0) && (t_rel >= state.
timeout);
386 if ((done_time && done_pose) || done_timeout) {
387 begin_state(state.
next);
403 if (data->time < prev_sim_time - 1e-6) {
406 prev_sim_time = data->time;
409 prev_sim_time = data->time;
412 double alpha = (state.
duration > 0.0)
418 impedance_ctrl(robot, q_des, n, dyn);
420 if (fingers_act >= 0) data->ctrl[fingers_act] = state.
gripper_cmd;
422 double t_rel = data->time - sm.
t_enter;
423 double pose_err = max_abs_joint_err(robot, *state.
q_target, n);
424 bool done_time = t_rel >= state.
duration;
426 bool done_timeout = (state.
timeout > 0.0) && (t_rel >= state.
timeout);
427 if ((done_time && done_pose) || done_timeout) {
428 begin_state(state.
next);
444 if (data->time < prev_sim_time - 1e-6) {
447 prev_sim_time = data->time;
450 prev_sim_time = data->time;
453 double alpha = (state.
duration > 0.0)
459 impedance_ctrl(robot, q_des, n, dyn);
461 if (fingers_act >= 0) data->ctrl[fingers_act] = state.
gripper_cmd;
463 double t_rel = data->time - sm.
t_enter;
464 double pose_err = max_abs_joint_err(robot, *state.
q_target, n);
465 bool done_time = t_rel >= state.
duration;
467 bool done_timeout = (state.
timeout > 0.0) && (t_rel >= state.
timeout);
468 if ((done_time && done_pose) || done_timeout) {
469 begin_state(state.
next);
485 if (data->time < prev_sim_time - 1e-6) {
488 prev_sim_time = data->time;
491 prev_sim_time = data->time;
494 double alpha = (state.
duration > 0.0)
500 impedance_ctrl(robot, q_des, n, dyn);
502 if (fingers_act >= 0) data->ctrl[fingers_act] = state.
gripper_cmd;
504 double t_rel = data->time - sm.
t_enter;
505 double pose_err = max_abs_joint_err(robot, *state.
q_target, n);
506 bool done_time = t_rel >= state.
duration;
508 bool done_timeout = (state.
timeout > 0.0) && (t_rel >= state.
timeout);
509 if ((done_time && done_pose) || done_timeout) {
510 begin_state(state.
next);
526 if (data->time < prev_sim_time - 1e-6) {
529 prev_sim_time = data->time;
532 prev_sim_time = data->time;
535 double alpha = (state.
duration > 0.0)
541 impedance_ctrl(robot, q_des, n, dyn);
543 if (fingers_act >= 0) data->ctrl[fingers_act] = state.
gripper_cmd;
545 double t_rel = data->time - sm.
t_enter;
546 double pose_err = max_abs_joint_err(robot, *state.
q_target, n);
547 bool done_time = t_rel >= state.
duration;
549 bool done_timeout = (state.
timeout > 0.0) && (t_rel >= state.
timeout);
550 if ((done_time && done_pose) || done_timeout) {
551 begin_state(state.
next);
570 int qadr = model->jnt_qposadr[cube_jnt];
571 double cube_z = data->qpos[qadr + 2];
572 std::cout <<
"cube Z after pick: " << std::fixed << std::setprecision(3) << cube_z