You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Conception/drake-master/solvers/test/plot_feasible_rotation_matr...

129 lines
4.1 KiB

#include <iostream>
#include <limits>
#include "drake/common/proto/call_python.h"
#include "drake/solvers/mathematical_program.h"
#include "drake/solvers/mixed_integer_rotation_constraint.h"
#include "drake/solvers/rotation_constraint.h"
#include "drake/solvers/solve.h"
/// Provides a simple utility for developers to visualize (slices of) the
/// rotation matrix relaxations. Sets up the problem:
/// min_R max_(i,j) |R(i,j) - R_sample(i,j)|
/// subject to [ chosen list of constraints on R ]
/// It then evaluates this program over a large number of samples and plots the
/// points (using call_python) for which R==R_sample (within some tol).
using Eigen::Matrix3d;
using Eigen::Vector3d;
namespace drake {
namespace solvers {
namespace {
// Use this method to change the feasibility envelope for all of the plotting
// tools.
void AddTestConstraints(MathematicalProgram* prog,
const MatrixDecisionVariable<3, 3>& R) {
// Add your favorite constraints here.
AddRotationMatrixBoxSphereIntersectionMilpConstraints(R, 1, prog);
}
bool IsFeasible(
const MathematicalProgram& prog,
const std::shared_ptr<LinearEqualityConstraint>& feasibility_constraint,
const Eigen::Ref<const Eigen::MatrixXd>& R_sample) {
Eigen::Map<const Eigen::VectorXd> R_sample_vec(R_sample.data(),
R_sample.size());
feasibility_constraint->UpdateLowerBound(R_sample_vec);
feasibility_constraint->UpdateUpperBound(R_sample_vec);
return Solve(prog).is_success();
}
void DrawCircle(double radius = 1.0) {
const int N = 100;
Eigen::Matrix2Xd points(2, N);
// Draw circle.
for (int i = 0; i < N; i++) {
const double theta = i * 2.0 * M_PI / (N - 1);
points.col(i) =
Eigen::Vector2d(radius * std::cos(theta), radius * std::sin(theta));
}
common::CallPython("plot", points.row(0), points.row(1), "k", "linewidth",
4.0);
}
void PlotFeasiblePoints(const Eigen::Matrix2Xd& points, double radius = 1.0,
int fig_num = 1) {
using common::CallPython;
CallPython("figure", fig_num);
CallPython("clf");
CallPython("plot", points.row(0), points.row(1), ".", "markersize", 20.0);
DrawCircle(radius);
CallPython("xlim", Eigen::RowVector2d(-1.1, 1.1));
CallPython("ylim", Eigen::RowVector2d(-1.1, 1.1));
CallPython("axis", "equal");
}
void PlotColumnVectorXYSlice(double z = 0.0, int fig_num = 1) {
Vector3d sample(0, 0, z);
MathematicalProgram prog;
MatrixDecisionVariable<3, 3> R = NewRotationMatrixVars(&prog);
AddTestConstraints(&prog, R);
// Add a feasibility constraint.
std::shared_ptr<LinearEqualityConstraint> feasibility_constraint =
prog.AddLinearEqualityConstraint(Eigen::Matrix3d::Identity(),
Eigen::Vector3d::Zero(), R.col(0))
.evaluator();
const int num_samples_per_axis = 50;
Eigen::Matrix2Xd feasible_points(2,
num_samples_per_axis * num_samples_per_axis);
int num_feasible = 0;
double minval = -1.0, maxval = 1.0;
for (int i = 0; i < num_samples_per_axis; i++) {
double x = minval + i * (maxval - minval) / (num_samples_per_axis - 1);
sample(0) = x;
for (int j = 0; j < num_samples_per_axis; j++) {
double y = minval + j * (maxval - minval) / (num_samples_per_axis - 1);
sample(1) = y;
if (IsFeasible(prog, feasibility_constraint, sample))
feasible_points.col(num_feasible++) = Eigen::Vector2d(x, y);
}
std::cout << "." << std::flush;
}
feasible_points.conservativeResize(2, num_feasible);
PlotFeasiblePoints(feasible_points, std::sqrt(1 - sample(2) * sample(2)),
fig_num);
using common::CallPython;
CallPython("xlabel", "R(0,0)");
CallPython("ylabel", "R(1,0)");
CallPython("title", "R(2,0) = " + std::to_string(z));
}
void DoMain() {
// Make some plots
// Plots z=0 slice of the first column.
// To plot z=0.25, set R0(2,0) = 0.25.
PlotColumnVectorXYSlice(0.0);
}
} // namespace
} // namespace solvers
} // namespace drake
int main() {
drake::solvers::DoMain();
return 0;
}