3 #include "ros/console.h"
9 #define _USE_MATH_DEFINES
14 using drake::solvers::MatrixXDecisionVariable;
16 using drake::symbolic::sin;
18 using drake::symbolic::cos;
25 decision_variables.
position_center = prog.NewContinuousVariables(n_points, 2,
"position_center");
27 decision_variables.
position_front_left = prog.NewContinuousVariables(n_points, 2,
"position_front_left");
29 decision_variables.
position_front_right = prog.NewContinuousVariables(n_points, 2,
"position_front_right");
31 decision_variables.
position_rear_left = prog.NewContinuousVariables(n_points, 2,
"position_rear_left");
33 decision_variables.
position_rear_right = prog.NewContinuousVariables(n_points, 2,
"position_rear_right");
35 decision_variables.
stone_front_left = prog.NewBinaryVariables(n_points, n_stones,
"stone_front_left");
37 decision_variables.
stone_front_right = prog.NewBinaryVariables(n_points, n_stones,
"stone_front_right");
39 decision_variables.
stone_rear_left = prog.NewBinaryVariables(n_points, n_stones,
"stone_rear_left");
41 decision_variables.
stone_rear_right = prog.NewBinaryVariables(n_points, n_stones,
"stone_rear_right");
43 decision_variables.
theta = prog.NewContinuousVariables(n_points, 1,
"theta");
45 decision_variables.
lin_sin = prog.NewContinuousVariables(n_points, 1,
"sin_theta");
47 decision_variables.
lin_cos = prog.NewContinuousVariables(n_points, 1,
"cos_theta");
49 decision_variables.
bin_sin = prog.NewBinaryVariables(n_points, 5,
"sin_selection");
51 decision_variables.
bin_cos = prog.NewBinaryVariables(n_points, 5,
"cos_selection");
53 return decision_variables;
58 MatrixXDecisionVariable &position_center = decision_variables.
position_center;
60 MatrixXDecisionVariable &theta = decision_variables.
theta;
62 prog.AddLinearConstraint(position_center.row(0).transpose() == initial_center);
64 prog.AddLinearConstraint(position_center.row(position_center.rows() - 1).transpose() == goal_center);
66 prog.AddLinearConstraint(theta(0) == 0);
68 prog.AddLinearConstraint(theta(theta.rows() - 1) == 0);
73 MatrixXDecisionVariable &position_center = decision_variables.
position_center;
75 for (
int i = 0; i < n_points - 1; ++i)
77 prog.AddLinearConstraint(position_center.row(i + 1).transpose() - position_center.row(i).transpose() <= Eigen::Vector2d::Constant(wp_dist));
79 prog.AddLinearConstraint(position_center.row(i + 1).transpose() - position_center.row(i).transpose() >= Eigen::Vector2d::Constant(-wp_dist));
83 void geometry_limits(drake::solvers::MathematicalProgram &prog,
int n_points,
double length_legs,
double bbox_len,
DecVars &decision_variables)
85 MatrixXDecisionVariable &position_center = decision_variables.
position_center;
95 MatrixXDecisionVariable &lin_sin = decision_variables.
lin_sin;
97 MatrixXDecisionVariable &lin_cos = decision_variables.
lin_cos;
102 double angle_divided = 2*M_PI/n_legs;
104 double phis[] = {0.5*angle_divided, -0.5*angle_divided, 1.5*angle_divided, -1.5*angle_divided};
106 Eigen::Matrix<drake::symbolic::Expression, 2, 1> leg_offset;
108 for (
int i = 0; i < n_points; ++i)
110 leg_offset << length_legs*(lin_cos(i)*cos(phis[
front_left]) - lin_sin(i)*sin(phis[
front_left])),
114 prog.AddLinearConstraint(position_front_left.row(i).transpose() - (position_center.row(i).transpose() + leg_offset) <= Eigen::Vector2d::Constant(bbox_len/2));
116 prog.AddLinearConstraint(position_front_left.row(i).transpose() - (position_center.row(i).transpose() + leg_offset) >= Eigen::Vector2d::Constant(-bbox_len/2));
122 prog.AddLinearConstraint(position_front_right.row(i).transpose() - (position_center.row(i).transpose() + leg_offset) <= Eigen::Vector2d::Constant(bbox_len/2));
124 prog.AddLinearConstraint(position_front_right.row(i).transpose() - (position_center.row(i).transpose() + leg_offset) >= Eigen::Vector2d::Constant(-bbox_len/2));
126 leg_offset << length_legs*(lin_cos(i)*cos(phis[
rear_left]) - lin_sin(i)*sin(phis[
rear_left])),
130 prog.AddLinearConstraint(position_rear_left.row(i).transpose() - (position_center.row(i).transpose() + leg_offset) <= Eigen::Vector2d::Constant(bbox_len/2));
132 prog.AddLinearConstraint(position_rear_left.row(i).transpose() - (position_center.row(i).transpose() + leg_offset) >= Eigen::Vector2d::Constant(-bbox_len/2));
134 leg_offset << length_legs*(lin_cos(i)*cos(phis[
rear_right]) - lin_sin(i)*sin(phis[
rear_right])),
138 prog.AddLinearConstraint(position_rear_right.row(i).transpose() - (position_center.row(i).transpose() + leg_offset) <= Eigen::Vector2d::Constant(bbox_len/2));
140 prog.AddLinearConstraint(position_rear_right.row(i).transpose() - (position_center.row(i).transpose() + leg_offset) >= Eigen::Vector2d::Constant(-bbox_len/2));
146 MatrixXDecisionVariable &theta = decision_variables.
theta;
148 MatrixXDecisionVariable &lin_sin = decision_variables.
lin_sin;
150 MatrixXDecisionVariable &lin_cos = decision_variables.
lin_cos;
152 MatrixXDecisionVariable &bin_sin = decision_variables.
bin_sin;
154 MatrixXDecisionVariable &bin_cos = decision_variables.
bin_cos;
156 double big_M = 2*M_PI;
158 double sin_dividers[] = {0, 1, M_PI - 1, M_PI + 1, 2*M_PI - 1, 2*M_PI};
160 double cos_dividers[] = {0, M_PI/2 - 1, M_PI/2 + 1, 3*M_PI/2 - 1, 3*M_PI/2 + 1, 2*M_PI};
166 ROS_INFO(
"Right before loop");
167 for (
int i = 0; i < n_points; ++i)
170 prog.AddLinearConstraint(theta(i) >= 0);
172 prog.AddLinearConstraint(theta(i) <= 2*M_PI);
175 ROS_INFO(
"About to add relation between theta and bin constr");
176 for (
int l = 0; l < 5; ++l)
178 prog.AddLinearConstraint(theta(i) >= sin_dividers[l] - (1 - bin_sin(i, l))*big_M);
180 prog.AddLinearConstraint(theta(i) <= sin_dividers[l + 1] + (1 - bin_sin(i, l))*big_M);
182 prog.AddLinearConstraint(theta(i) >= cos_dividers[l] - (1 - bin_cos(i, l))*big_M);
184 prog.AddLinearConstraint(theta(i) <= cos_dividers[l + 1] + (1 - bin_cos(i, l))*big_M);
186 ROS_INFO(
"About to enforce exactly one line segment");
188 auto sin_const = prog.AddLinearConstraint((bin_sin.row(i)*Eigen::VectorXd::Ones(5))(0) == 1);
190 auto cos_const = prog.AddLinearConstraint((bin_cos.row(i)*Eigen::VectorXd::Ones(5))(0) == 1);
193 ROS_INFO(
"About to enforce linearized sin_theta/cos_theta");
194 auto sin_upper = prog.AddLinearConstraint(lin_sin(i) - (sin_coeffs.col(0) + sin_coeffs.col(1)*theta(i))(0) <= big_M);
196 auto sin_lower = prog.AddLinearConstraint(lin_sin(i) - (sin_coeffs.col(0) + sin_coeffs.col(1)*theta(i))(0) >= -big_M);
198 auto cos_upper = prog.AddLinearConstraint(lin_cos(i) - (cos_coeffs.col(0) + cos_coeffs.col(1)*theta(i))(0) <= big_M);
200 auto cos_lower = prog.AddLinearConstraint(lin_cos(i) - (cos_coeffs.col(0) + cos_coeffs.col(1)*theta(i))(0) >= -big_M);
202 std::cout << sin_upper << std::endl << sin_lower << std::endl << cos_upper << std::endl << cos_lower << std::endl;
208 MatrixXDecisionVariable &stone_front_left = decision_variables.
stone_front_left;
210 MatrixXDecisionVariable &stone_front_right = decision_variables.
stone_front_right;
212 MatrixXDecisionVariable &stone_rear_left = decision_variables.
stone_rear_left;
214 MatrixXDecisionVariable &stone_rear_right = decision_variables.
stone_rear_right;
216 prog.AddLinearConstraint(stone_front_left*Eigen::VectorXd::Ones(stone_front_left.cols()) == Eigen::VectorXd::Ones(stone_front_left.rows()));
218 prog.AddLinearConstraint(stone_front_right*Eigen::VectorXd::Ones(stone_front_right.cols()) == Eigen::VectorXd::Ones(stone_front_right.rows()));
220 prog.AddLinearConstraint(stone_rear_left*Eigen::VectorXd::Ones(stone_rear_left.cols()) == Eigen::VectorXd::Ones(stone_rear_left.rows()));
222 prog.AddLinearConstraint(stone_rear_right*Eigen::VectorXd::Ones(stone_rear_right.cols()) == Eigen::VectorXd::Ones(stone_rear_right.rows()));
252 MatrixXDecisionVariable &stone_front_left = decision_variables.
stone_front_left;
254 MatrixXDecisionVariable &stone_front_right = decision_variables.
stone_front_right;
256 MatrixXDecisionVariable &stone_rear_left = decision_variables.
stone_rear_left;
258 MatrixXDecisionVariable &stone_rear_right = decision_variables.
stone_rear_right;
264 Eigen::MatrixXd A,
b;
265 for (
int i = 0; i < n_points; ++i)
267 for (
int l = 0; l < n_stones ; ++l)
273 prog.AddLinearConstraint(A*position_front_left.row(i).transpose() <=
b + (1 - stone_front_left(i, l))*M);
275 prog.AddLinearConstraint(A*position_front_right.row(i).transpose() <=
b + (1 - stone_front_right(i, l))*M);
277 prog.AddLinearConstraint(A*position_rear_left.row(i).transpose() <=
b + (1 - stone_rear_left(i, l))*M);
279 prog.AddLinearConstraint(A*position_rear_right.row(i).transpose() <=
b + (1 - stone_rear_right(i, l))*M);
287 MatrixXDecisionVariable &position_center = decision_variables.
position_center;
289 Eigen::Matrix<drake::symbolic::Expression, 2, 1> dist;
291 for (
int i = 0; i < n_points - 1; ++i)
293 dist = (position_center.row(i + 1) - position_center.row(i)).transpose();
295 prog.AddQuadraticCost((dist.transpose()*dist)(0));
303 MatrixXDecisionVariable &lin_sin = decision_variables.
lin_sin;
305 MatrixXDecisionVariable &lin_cos = decision_variables.
lin_cos;
307 drake::symbolic::Expression sin_dist;
309 drake::symbolic::Expression cos_dist;
311 for (
int i = 0; i < n_points - 1; ++i)
313 sin_dist = lin_sin(i + 1) - lin_sin(i);
315 cos_dist = lin_cos(i + 1) - lin_cos(i);
317 prog.AddQuadraticCost(sin_dist*sin_dist);
319 prog.AddQuadraticCost(cos_dist*cos_dist);
325 std::ofstream file(filename);
333 ROS_INFO(
"writeMatToFile: Successfully wrote to file");
336 ROS_ERROR(
"could not open file");
338 throw "could not open file " + filename;
346 std::string fend =
".csv";
const Eigen::Vector3d & getCenter() const
const Eigen::Vector3d & getTopRight() const
const SteppingStone & getStoneByName(std::string name) const
const Eigen::Array< SteppingStone, Eigen::Dynamic, 1 > & getSteppingStones() const
DecVars add_decision_variables(drake::solvers::MathematicalProgram &prog, Terrain &terrain, int n_points)
void set_initial_and_goal_position(drake::solvers::MathematicalProgram &prog, Eigen::Vector2d &initial_center, Eigen::Vector2d &goal_center, DecVars &decision_variables)
void one_stone_per_foot(drake::solvers::MathematicalProgram &prog, int n_points, DecVars &decision_variables)
void foot_in_stepping_stone(drake::solvers::MathematicalProgram &prog, Terrain &terrain, int n_points, DecVars &decision_variables)
void minimize_step_length(drake::solvers::MathematicalProgram &prog, int n_points, DecVars &decision_variables)
Eigen::Vector4d get_big_M(Terrain terrain)
void geometry_limits(drake::solvers::MathematicalProgram &prog, int n_points, double length_legs, double bbox_len, DecVars &decision_variables)
void relative_position_limits(drake::solvers::MathematicalProgram &prog, int n_points, double wp_dist, DecVars &decision_variables)
void writeDecVarsToFile(DecVars_res &decision_variables, std::string base_name)
void theta_limits(drake::solvers::MathematicalProgram &prog, int n_points, DecVars &decision_variables)
void minimize_theta_change(drake::solvers::MathematicalProgram &prog, int n_points, DecVars &decision_variables)
void writeMatToFile(Eigen::MatrixXd &mat, std::string filename)
Eigen::MatrixXd position_front_right
Eigen::MatrixXd stone_front_left
Eigen::MatrixXd position_front_left
Eigen::MatrixXd position_rear_left
Eigen::MatrixXd stone_rear_right
Eigen::MatrixXd stone_rear_left
Eigen::MatrixXd position_rear_right
Eigen::MatrixXd stone_front_right
MatrixXDecisionVariable stone_front_left
MatrixXDecisionVariable bin_cos
MatrixXDecisionVariable theta
MatrixXDecisionVariable stone_front_right
MatrixXDecisionVariable position_front_left
MatrixXDecisionVariable position_front_right
MatrixXDecisionVariable position_rear_right
MatrixXDecisionVariable lin_cos
MatrixXDecisionVariable stone_rear_right
MatrixXDecisionVariable position_center
MatrixXDecisionVariable bin_sin
MatrixXDecisionVariable lin_sin
MatrixXDecisionVariable stone_rear_left
MatrixXDecisionVariable position_rear_left
Eigen::MatrixXd get_cos_coeffs()
Eigen::MatrixXd get_sin_coeffs()