Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable Fixed Complexity Slip MPC #332

Draft
wants to merge 81 commits into
base: adaptive_mpc
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
82bcb3a
Code sort of works, but bounces
Oct 14, 2022
e4151e7
Changed how costs work, but getting some strange solutions
Oct 18, 2022
f07ffe0
Cleaned up code
Oct 19, 2022
db4f37a
Merge remote-tracking branch 'upstream/adaptive_mpc' into srozenlevy/…
Oct 20, 2022
d8e7101
Updated saving of trajectories
Oct 20, 2022
094e0b6
Switched to trapazoidal collocation
Oct 19, 2022
c0da82c
Setup timing
Oct 19, 2022
0b8130d
Doing an alright job stepping in place
Oct 20, 2022
ac506c0
Dropped down gain and reduced knot points
Oct 20, 2022
0315fe0
Fixed bazel run
Oct 20, 2022
c2c91e2
Added reference generator script
Oct 20, 2022
91c16cf
Created cassie specific optimization class
Oct 21, 2022
0763b3e
Added gains yaml
Oct 21, 2022
563e1a1
Removed extra function calls
Oct 21, 2022
b1a9abf
Wrote the code necessary to generate references that may or may not work
Oct 23, 2022
d9aee32
Looks like a walk
Oct 24, 2022
a544240
Walk is looking even better
Oct 24, 2022
fdc7f96
Still working well
Oct 24, 2022
2f74771
Working alright. Added guess from reference
Oct 24, 2022
b9e2cc4
Cleaned up gains
Oct 25, 2022
c2f5823
Added trapazoidal integration to cost
Oct 25, 2022
541995b
Removed over constrained system
Oct 25, 2022
ddcade0
Fixed reference bug
Oct 26, 2022
2cb002a
Fixed reference bug
Oct 26, 2022
2d5fb27
Experimenting with ipopt
Oct 27, 2022
acb489d
First pass of transitioning over to object reference creation
Oct 27, 2022
61de344
Cleaning up code for eventual push
Oct 31, 2022
7923824
Added more comments
Oct 31, 2022
bd78dd3
Added tons of comments
Nov 1, 2022
39f7413
Switched ik to com based and add minimum swing foot height to gains
Nov 2, 2022
e82efcb
Cleaning up code for PR
Nov 4, 2022
dbee5cb
Switched to yaml for gaits
Nov 4, 2022
e7f0843
Switched to reletive path to file and try catch
Nov 4, 2022
a3380c7
Responded to more PR feedback
Nov 7, 2022
d441195
Started owrk on defining a lifting and reduction function
Nov 9, 2022
ef4a4f0
Having weird com velocity error
Nov 10, 2022
8cfb6c9
Happy with planar slip lifting function test
Nov 10, 2022
609df41
Added Lifting function
Nov 10, 2022
a0545eb
Added nonlinear cost
Nov 10, 2022
1c742fb
Added nonlinear cost for real this time
Nov 10, 2022
48cdd83
Merge branch 'adaptive_mpc' into srozenlevy/planar_slip_mpc
Nov 10, 2022
aedcedb
Merge branch 'adaptive_mpc' into srozenlevy/planar_slip_mpc
Nov 10, 2022
8f943ce
Back to walking
Nov 10, 2022
793d0d3
Slowly putting adpative complexity mpc together
Nov 10, 2022
cb1a29c
Started to work on fixed complexity
Nov 14, 2022
ad3a232
Committing some code
Nov 15, 2022
8d84367
Added momentum reference and cost
Nov 15, 2022
1731e6f
Fixed bug in lifting function
Nov 15, 2022
da2d982
Sort of works, gonna switch slip foot to just the toe
Nov 15, 2022
a4f2b95
Planar slip struggling with fixed timing
Nov 17, 2022
d69b61f
Switched to non planar slip
Dec 1, 2022
4cabeac
Slip is standing finally
Dec 6, 2022
eb04535
Robot is able to stand
Dec 7, 2022
8c51d74
Making some progress on walking
Dec 8, 2022
40b7171
Walking is working somewhat well
Dec 8, 2022
39b9e54
Properly setting r0
Dec 9, 2022
e717381
Fixed lifting function toe velocity
Dec 9, 2022
ac577d9
Added damping, but realized com velocity is broken
Dec 9, 2022
8b7bd24
Fixed reduction function
Dec 9, 2022
9bd3407
Fixed grf reduction constraint slip velocity
Dec 9, 2022
50ad6bc
Still strugging with grf constraint
Dec 9, 2022
73c7b10
fixed bunch of reduction function bugs
Dec 9, 2022
8448c54
Cleaning up code
Dec 13, 2022
4b3685b
Merge branch 'adaptive_mpc' into srozenlevy/planar_slip_mpc
Dec 13, 2022
334fb22
Working on reducing diff to adaptive_mpc before merge
Dec 13, 2022
820ee8d
Cleaning up code for merge, code runs, but ipopt crashes
Dec 13, 2022
454e6e3
Working on resolving bouncing
Dec 13, 2022
891c522
Solving much better after some tuning
Dec 13, 2022
f54f8da
Fixed dynamics bug
Dec 14, 2022
acec98c
Experimenting with autoformatter
Dec 14, 2022
83c4c4b
Ran autoformatter
Dec 14, 2022
7301283
Cleaning up code for pr
Dec 14, 2022
e19ce86
Something seems broken
Dec 15, 2022
0491e00
Couldn't even tell when the swap happened
Dec 15, 2022
d71aef7
Getting some alright performance
Dec 15, 2022
f08e1b0
Added gains to yaml
Dec 15, 2022
99e90da
Moved magic number to traj params
Dec 15, 2022
655ded6
Documented code and fixed unit test
Dec 16, 2022
a3846db
Merge branch 'adaptive_mpc' into srozenlevy/planar_slip_mpc
Dec 16, 2022
1c28a18
Fixing merge mistakes
Dec 16, 2022
f7b89c2
Responding to pr comments
Jan 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ visualize_mode: 2
realtime_rate: 1.0
num_poses: 10
use_transparency: 1
use_springs: 1
use_springs: 1
10 changes: 6 additions & 4 deletions examples/Cassie/kinematic_centroidal_planner/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ cc_binary(
"//solvers:optimization_utils",
"//systems/primitives",
"//examples/Cassie/kinematic_centroidal_planner:cassie_kinematic_centroidal_mpc",
"//examples/Cassie/kinematic_centroidal_planner:cassie_reference_utils",
"//examples/Cassie/kinematic_centroidal_planner:cassie_kc_utils",
"@drake//:drake_shared_library",
"@gflags",
],
Expand Down Expand Up @@ -76,14 +76,15 @@ cc_library(
)

cc_library(
name = "cassie_reference_utils",
srcs = ["cassie_reference_utils.cc"],
hdrs = ["cassie_reference_utils.h"],
name = "cassie_kc_utils",
srcs = ["cassie_kc_utils.cc"],
hdrs = ["cassie_kc_utils.h"],
deps = [
"//examples/Cassie:cassie_utils",
"//common",
"//systems/trajectory_optimization/kinematic_centroidal_planner:kinematic_centroidal_planner",
"//multibody:visualization_utils",
":cassie_kinematic_centroidal_mpc",
"@drake//:drake_shared_library",
],
)
Expand All @@ -97,6 +98,7 @@ cc_library(
"//common",
"//systems/trajectory_optimization/kinematic_centroidal_planner",
"//multibody:visualization_utils",
"//examples/Cassie/kinematic_centroidal_planner/simple_models:slip",
"@drake//:drake_shared_library",
],
)
Original file line number Diff line number Diff line change
@@ -1,30 +1,34 @@
#include "cassie_reference_utils.h"
#include <drake/systems/framework/diagram_builder.h>
#include "cassie_kc_utils.h"

#include <iostream>
#include <regex>

#include <drake/geometry/scene_graph.h>
#include <drake/multibody/inverse_kinematics/com_position_constraint.h>
#include <drake/multibody/inverse_kinematics/inverse_kinematics.h>
#include <drake/multibody/parsing/parser.h>
#include <drake/multibody/plant/multibody_plant.h>
#include <iostream>
#include <drake/systems/analysis/simulator.h>
#include <drake/multibody/inverse_kinematics/inverse_kinematics.h>
#include <drake/solvers/solve.h>
#include <drake/systems/analysis/simulator.h>
#include <drake/systems/framework/diagram_builder.h>

#include "examples/Cassie/cassie_utils.h"
#include "multibody/visualization_utils.h"
#include <drake/multibody/inverse_kinematics/com_position_constraint.h>

using drake::geometry::SceneGraph;
using drake::multibody::MultibodyPlant;
using drake::multibody::Parser;

Eigen::VectorXd GenerateNominalStand(const drake::multibody::MultibodyPlant<double> &plant,
double com_height,
double stance_width,
bool visualize) {
using Eigen::VectorXd;
Eigen::VectorXd GenerateNominalStand(
const drake::multibody::MultibodyPlant<double>& plant, double com_height,
double stance_width, bool visualize) {
using Eigen::Vector3d;
using Eigen::VectorXd;
int n_q = plant.num_positions();
int n_v = plant.num_velocities();
int n_x = n_q + n_v;
std::map<std::string, int> positions_map = dairlib::multibody::MakeNameToPositionsMap(plant);
std::map<std::string, int> positions_map =
dairlib::multibody::MakeNameToPositionsMap(plant);

Eigen::VectorXd q_ik_guess = Eigen::VectorXd::Zero(n_q);

Expand Down Expand Up @@ -58,12 +62,11 @@ Eigen::VectorXd GenerateNominalStand(const drake::multibody::MultibodyPlant<doub
Eigen::Vector3d heel_rt_toe = {.122, 0, 0};

Eigen::Vector3d pelvis_pos = {0, 0, com_height};
Eigen::Vector3d l_toe_pos = {0.06, stance_width/2, 0};
Eigen::Vector3d r_toe_pos = {0.06, -stance_width/2, 0};
Eigen::Vector3d l_toe_pos = {0.06, stance_width / 2, 0};
Eigen::Vector3d r_toe_pos = {0.06, -stance_width / 2, 0};

Eigen::Vector3d l_heel_pos = l_toe_pos - heel_rt_toe;
Eigen::Vector3d r_heel_pos = r_toe_pos-heel_rt_toe;

Eigen::Vector3d r_heel_pos = r_toe_pos - heel_rt_toe;

const auto& world_frame = plant.world_frame();
const auto& pelvis_frame = plant.GetFrameByName("pelvis");
Expand All @@ -74,19 +77,22 @@ Eigen::VectorXd GenerateNominalStand(const drake::multibody::MultibodyPlant<doub
drake::multibody::InverseKinematics ik(plant, context.get());
double eps = 1e-3;
Vector3d eps_vec = eps * VectorXd::Ones(3);
ik.AddOrientationConstraint(pelvis_frame, drake::math::RotationMatrix<double>(),
world_frame, drake::math::RotationMatrix<double>(), eps);
ik.AddPositionConstraint(toe_left_frame, dairlib::LeftToeFront(plant).first, world_frame,
l_toe_pos - eps_vec,
ik.AddOrientationConstraint(
pelvis_frame, drake::math::RotationMatrix<double>(), world_frame,
drake::math::RotationMatrix<double>(), eps);
ik.AddPositionConstraint(toe_left_frame, dairlib::LeftToeFront(plant).first,
world_frame, l_toe_pos - eps_vec,
l_toe_pos + eps_vec);
ik.AddPositionConstraint(toe_left_frame, dairlib::LeftToeRear(plant).first, world_frame,
l_heel_pos - eps_vec,
ik.AddPositionConstraint(toe_left_frame, dairlib::LeftToeRear(plant).first,
world_frame, l_heel_pos - eps_vec,
l_heel_pos + eps_vec);

ik.AddPositionConstraint(toe_right_frame, dairlib::RightToeFront(plant).first, world_frame,
r_toe_pos - eps_vec, r_toe_pos + eps_vec);
ik.AddPositionConstraint(toe_right_frame, dairlib::RightToeRear(plant).first, world_frame,
r_heel_pos - eps_vec, r_heel_pos + eps_vec);
ik.AddPositionConstraint(toe_right_frame, dairlib::RightToeFront(plant).first,
world_frame, r_toe_pos - eps_vec,
r_toe_pos + eps_vec);
ik.AddPositionConstraint(toe_right_frame, dairlib::RightToeRear(plant).first,
world_frame, r_heel_pos - eps_vec,
r_heel_pos + eps_vec);

ik.get_mutable_prog()->AddLinearConstraint(
(ik.q())(positions_map.at("hip_yaw_left")) == 0);
Expand All @@ -96,15 +102,16 @@ Eigen::VectorXd GenerateNominalStand(const drake::multibody::MultibodyPlant<doub
ik.get_mutable_prog()->AddLinearConstraint(
(ik.q())(positions_map.at("knee_left")) +
(ik.q())(positions_map.at("ankle_joint_left")) ==
M_PI * 13 / 180.0);
M_PI * 13 / 180.0);
ik.get_mutable_prog()->AddLinearConstraint(
(ik.q())(positions_map.at("knee_right")) +
(ik.q())(positions_map.at("ankle_joint_right")) ==
M_PI * 13 / 180.0);
M_PI * 13 / 180.0);

auto constraint = std::make_shared<drake::multibody::ComPositionConstraint>(&plant, std::nullopt, plant.world_frame(), context.get());
auto constraint = std::make_shared<drake::multibody::ComPositionConstraint>(
&plant, std::nullopt, plant.world_frame(), context.get());
auto r = ik.get_mutable_prog()->NewContinuousVariables(3);
ik.get_mutable_prog()->AddConstraint(constraint, {ik.q(),r});
ik.get_mutable_prog()->AddConstraint(constraint, {ik.q(), r});
Eigen::Vector3d rdes = {0, 0, com_height};
ik.get_mutable_prog()->AddBoundingBoxConstraint(rdes, rdes, r);

Expand All @@ -117,15 +124,16 @@ Eigen::VectorXd GenerateNominalStand(const drake::multibody::MultibodyPlant<doub
q_sol_normd << q_sol.head(4).normalized(), q_sol.tail(n_q - 4);
q_ik_guess = q_sol_normd;

if(visualize){
if (visualize) {
// Build temporary diagram for visualization
drake::systems::DiagramBuilder<double> builder_ik;
drake::geometry::SceneGraph<double>& scene_graph_ik = *builder_ik.AddSystem<drake::geometry::SceneGraph>();
drake::geometry::SceneGraph<double>& scene_graph_ik =
*builder_ik.AddSystem<drake::geometry::SceneGraph>();
scene_graph_ik.set_name("scene_graph_ik");
MultibodyPlant<double> plant_ik(0.0);
Parser parser(&plant_ik, &scene_graph_ik);
std::string full_name =
dairlib::FindResourceOrThrow("examples/Cassie/urdf/cassie_fixed_springs.urdf");
std::string full_name = dairlib::FindResourceOrThrow(
"examples/Cassie/urdf/cassie_fixed_springs.urdf");
parser.AddModelFromFile(full_name);
plant_ik.Finalize();

Expand All @@ -148,4 +156,28 @@ Eigen::VectorXd GenerateNominalStand(const drake::multibody::MultibodyPlant<doub
return rv;
}


std::vector<Complexity> GenerateComplexitySchedule(
int n_knot_points, const std::vector<std::string>& complexity_string_list) {
std::vector<Complexity> complexity_schedule;
std::regex number_regex("(^|\\s)([0-9]+)($|\\s)");
std::smatch match;
for (const auto& complexity_string : complexity_string_list) {
DRAKE_DEMAND(complexity_string.at(0) == 'c' or
complexity_string.at(0) == 's');
if (complexity_string.at(0) == 'c') {
std::regex_search(complexity_string, match, number_regex);
std::cout << std::stoi(match[0]) << std::endl;
for (int i = 0; i < std::stoi(match[0]); i++) {
complexity_schedule.push_back(Complexity::KINEMATIC_CENTROIDAL);
}
} else if (complexity_string.at(0) == 's') {
std::regex_search(complexity_string, match, number_regex);
std::cout << std::stoi(match[0]) << std::endl;
for (int i = 0; i < std::stoi(match[0]); i++) {
complexity_schedule.push_back(Complexity::SLIP);
}
}
}
DRAKE_DEMAND(n_knot_points == complexity_schedule.size());
return complexity_schedule;
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@

#pragma once

#include <drake/multibody/plant/multibody_plant.h>
#include <Eigen/Core>
#include <drake/common/trajectories/piecewise_polynomial.h>
#include <drake/multibody/plant/multibody_plant.h>

#include "examples/Cassie/kinematic_centroidal_planner/cassie_kinematic_centroidal_solver.h"
#include "multibody/kinematic/world_point_evaluator.h"

/*!
Expand All @@ -14,7 +16,9 @@
* @param visualize true if the stand should be visualized
* @return vector of state [nq + nv]
*/
Eigen::VectorXd GenerateNominalStand(const drake::multibody::MultibodyPlant<double> &plant,
double com_height,
double stance_width,
bool visualize = false);
Eigen::VectorXd GenerateNominalStand(
const drake::multibody::MultibodyPlant<double>& plant, double com_height,
double stance_width, bool visualize = false);

std::vector<Complexity> GenerateComplexitySchedule(
int n_knot_points, const std::vector<std::string>& complexity_string_list);
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <unistd.h>

#include <iostream>

#include <drake/common/yaml/yaml_io.h>
Expand All @@ -16,12 +18,13 @@

#include "common/find_resource.h"
#include "dairlib/lcmt_timestamped_saved_traj.hpp"
#include "examples/Cassie/kinematic_centroidal_planner/cassie_kc_utils.h"
#include "examples/Cassie/kinematic_centroidal_planner/cassie_kinematic_centroidal_solver.h"
#include "examples/Cassie/kinematic_centroidal_planner/cassie_reference_utils.h"
#include "examples/Cassie/kinematic_centroidal_planner/trajectory_parameters.h"
#include "systems/primitives/subvector_pass_through.h"
#include "systems/trajectory_optimization/kinematic_centroidal_planner/kcmpc_reference_generator.h"
#include "systems/trajectory_optimization/kinematic_centroidal_planner/kinematic_centroidal_gains.h"
#include "systems/trajectory_optimization/kinematic_centroidal_planner/reference_generation_utils.h"

using drake::geometry::DrakeVisualizer;
using drake::geometry::SceneGraph;
Expand All @@ -33,7 +36,7 @@ DEFINE_string(channel_reference, "KCMPC_REF",
"MPC are published");
DEFINE_string(
trajectory_parameters,
"examples/Cassie/kinematic_centroidal_planner/motions/motion_test.yaml",
"examples/Cassie/kinematic_centroidal_planner/motions/motion_walk.yaml",
"YAML file that contains trajectory parameters such as speed, tolerance, "
"target_com_height");
DEFINE_string(planner_parameters,
Expand Down Expand Up @@ -90,25 +93,35 @@ int DoMain(int argc, char* argv[]) {
gait_library["jump"] = jump;
// Create reference
std::vector<Gait> gait_samples;
for (auto gait : traj_params.gait_sequence){
for (auto gait : traj_params.gait_sequence) {
gait_samples.push_back(gait_library.at(gait));
}
DRAKE_DEMAND(gait_samples.size() == traj_params.duration_scaling.size());
std::vector<double> time_points = KcmpcReferenceGenerator::GenerateTimePoints(
traj_params.duration_scaling, gait_samples);

Eigen::VectorXd reference_state = GenerateNominalStand(
plant, traj_params.target_com_height, traj_params.stance_width, false);

// Create MPC and set gains
CassieKinematicCentroidalSolver mpc(
plant, traj_params.n_knot_points,
time_points.back() / (traj_params.n_knot_points - 1), 0.4);
time_points.back() / (traj_params.n_knot_points - 1), 0.4,
reference_state.head(plant.num_positions()), traj_params.spring_constant,
traj_params.damping_coefficient,
sqrt(pow(traj_params.target_com_height, 2) +
pow(traj_params.stance_width, 2)),
traj_params.stance_width);
mpc.SetGains(gains);
mpc.SetMinimumFootClearance(traj_params.swing_foot_minimum_height);
mpc.SetMaximumSlipLegLength(traj_params.max_slip_leg_length);

mpc.SetComplexitySchedule(GenerateComplexitySchedule(
traj_params.n_knot_points, traj_params.complexity_schedule));

KcmpcReferenceGenerator generator(plant, plant_context.get(),
CreateContactPoints(plant, 0));

Eigen::VectorXd reference_state = GenerateNominalStand(
plant, traj_params.target_com_height, traj_params.stance_width, false);
generator.SetNominalReferenceConfiguration(
reference_state.head(plant.num_positions()));
generator.SetComKnotPoints({time_points, traj_params.com_vel_vector});
Expand All @@ -131,7 +144,9 @@ int DoMain(int argc, char* argv[]) {
mpc.SetContactTrackingReference(
std::make_unique<drake::trajectories::PiecewisePolynomial<double>>(
generator.contact_traj_));
mpc.SetConstantMomentumReference(Eigen::VectorXd::Zero(6));
mpc.SetMomentumReference(
std::make_unique<drake::trajectories::PiecewisePolynomial<double>>(
generator.momentum_trajectory_));
mpc.SetModeSequence(generator.contact_sequence_);
//
// // Set initial guess
Expand All @@ -140,6 +155,7 @@ int DoMain(int argc, char* argv[]) {
mpc.SetComPositionGuess(generator.com_trajectory_);
mpc.SetContactGuess(generator.contact_traj_);
mpc.SetForceGuess(generator.grf_traj_);
mpc.SetMomentumGuess(generator.momentum_trajectory_);

{
drake::solvers::SolverOptions options;
Expand All @@ -148,7 +164,7 @@ int DoMain(int argc, char* argv[]) {
options.SetOption(id, "dual_inf_tol", gains.tol);
options.SetOption(id, "constr_viol_tol", gains.tol);
options.SetOption(id, "compl_inf_tol", gains.tol);
options.SetOption(id, "max_iter", 200);
options.SetOption(id, "max_iter", 800);
options.SetOption(id, "nlp_lower_bound_inf", -1e6);
options.SetOption(id, "nlp_upper_bound_inf", 1e6);
options.SetOption(id, "print_timing_statistics", "yes");
Expand Down Expand Up @@ -204,12 +220,11 @@ int DoMain(int argc, char* argv[]) {

while (true) {
drake::systems::Simulator<double> simulator(*diagram);
simulator.set_target_realtime_rate(1.0);
simulator.set_target_realtime_rate(0.25);
simulator.Initialize();
simulator.AdvanceTo(pp_xtraj.end_time());
sleep(2);
}
}

int main(int argc, char* argv[]) {
DoMain(argc, argv);
}
int main(int argc, char* argv[]) { DoMain(argc, argv); }
Loading