Sped box grab up significantly and handle disable
Add some more trajectories and cut tolerances to make box grabbing go
faster. Also, go to the nearest node when disabled.
Change-Id: Ic641db69a8c18eb61771ebc352e05ceef0d90084
diff --git a/y2018/control_loops/superstructure/arm/arm.cc b/y2018/control_loops/superstructure/arm/arm.cc
index 45d0e45..c283f19 100644
--- a/y2018/control_loops/superstructure/arm/arm.cc
+++ b/y2018/control_loops/superstructure/arm/arm.cc
@@ -26,7 +26,8 @@
.finished()),
search_graph_(MakeSearchGraph(&trajectories_, alpha_unitizer_, kVMax())),
// Go to the start of the first trajectory.
- follower_(ReadyAboveBoxPoint()) {
+ follower_(ReadyAboveBoxPoint()),
+ points_(PointList()) {
int i = 0;
for (const auto &trajectory : trajectories_) {
LOG(INFO, "trajectory length for edge node %d: %f\n", i,
@@ -115,20 +116,34 @@
break;
}
- case State::DISABLED:
- if (!outputs_disabled) {
- follower_.SwitchTrajectory(nullptr);
- close_enough_for_full_power_ = false;
- // TODO(austin): Nearest point at the end of Initialize.
- // So, get a vector of all the points, loop through them, and find the
- // closest one.
- follower_.set_theta(ReadyAboveBoxPoint());
- current_node_ = ReadyAboveBoxIndex();
+ case State::DISABLED: {
+ follower_.SwitchTrajectory(nullptr);
+ close_enough_for_full_power_ = false;
+ const ::Eigen::Matrix<double, 2, 1> current_theta =
+ (::Eigen::Matrix<double, 2, 1>() << arm_ekf_.X_hat(0),
+ arm_ekf_.X_hat(2))
+ .finished();
+ uint32_t best_index = 0;
+ double best_distance = (points_[0] - current_theta).norm();
+ uint32_t current_index = 0;
+ for (const ::Eigen::Matrix<double, 2, 1> &point : points_) {
+ const double new_distance = (point - current_theta).norm();
+ if (new_distance < best_distance) {
+ best_distance = new_distance;
+ best_index = current_index;
+ }
+ ++current_index;
+ }
+ follower_.set_theta(points_[best_index]);
+ current_node_ = best_index;
+
+ if (!outputs_disabled) {
state_ = State::GOTO_PATH;
} else {
break;
}
+ }
case State::GOTO_PATH:
if (outputs_disabled) {
@@ -162,6 +177,7 @@
close_enough_for_full_power_ = false;
}
+ // TODO(austin): Do we need to debounce box_back_beambreak_triggered ?
if (claw_closed_) {
if ((filtered_goal == ReadyAboveBoxIndex()) ||
(filtered_goal == TallBoxGrabIndex()) ||
@@ -194,9 +210,6 @@
case GrabState::TALL_BOX:
if (!grab_box) {
grab_state_ = GrabState::NORMAL;
- } else if (!box_back_beambreak_triggered) {
- // Lost the box, go back to wait for it.
- grab_state_ = GrabState::WAIT_FOR_BOX;
} else if (AtState(TallBoxGrabIndex()) && NearEnd()) {
// We are being asked to grab the box, and the claw is near the box.
if (claw_beambreak_triggered) {
@@ -211,9 +224,6 @@
case GrabState::SHORT_BOX:
if (!grab_box) {
grab_state_ = GrabState::NORMAL;
- } else if (!box_back_beambreak_triggered) {
- // Lost the box, go back to wait for it.
- grab_state_ = GrabState::WAIT_FOR_BOX;
} else if (AtState(ShortBoxGrabIndex()) && NearEnd()) {
// We are being asked to grab the box, and the claw is near the box.
if (claw_beambreak_triggered) {
@@ -227,7 +237,7 @@
break;
case GrabState::CLAW_CLOSE:
if (::aos::monotonic_clock::now() >
- claw_close_start_time_ + ::std::chrono::milliseconds(500)) {
+ claw_close_start_time_ + ::std::chrono::milliseconds(300)) {
grab_state_ = GrabState::OPEN_INTAKE;
}
break;
diff --git a/y2018/control_loops/superstructure/arm/arm.h b/y2018/control_loops/superstructure/arm/arm.h
index d296703..8e1860f 100644
--- a/y2018/control_loops/superstructure/arm/arm.h
+++ b/y2018/control_loops/superstructure/arm/arm.h
@@ -19,17 +19,18 @@
Arm();
// If true, tune down all the constants for testing.
- static constexpr bool kGrannyMode() { return true; }
+ static constexpr bool kGrannyMode() { return false; }
// The operating voltage.
static constexpr double kOperatingVoltage() {
return kGrannyMode() ? 4.0 : 12.0;
}
static constexpr double kDt() { return 0.00505; }
- static constexpr double kAlpha0Max() { return kGrannyMode() ? 10.0 : 25.0; }
- static constexpr double kAlpha1Max() { return kGrannyMode() ? 10.0 : 25.0; }
- static constexpr double kVMax() { return kGrannyMode() ? 4.0 : 11.5; }
- static constexpr double kPathlessVMax() { return 4.0; }
+ static constexpr double kAlpha0Max() { return kGrannyMode() ? 10.0 : 15.0; }
+ static constexpr double kAlpha1Max() { return kGrannyMode() ? 10.0 : 15.0; }
+
+ static constexpr double kVMax() { return kGrannyMode() ? 5.0 : 11.5; }
+ static constexpr double kPathlessVMax() { return 5.0; }
void Iterate(const uint32_t *unsafe_goal, bool grab_box, bool open_claw,
const control_loops::ArmPosition *position,
@@ -68,7 +69,7 @@
private:
bool AtState(uint32_t state) const { return current_node_ == state; }
- bool NearEnd(double threshold = 0.01) const {
+ bool NearEnd(double threshold = 0.02) const {
return ::std::abs(arm_ekf_.X_hat(0) - follower_.theta(0)) <= threshold &&
::std::abs(arm_ekf_.X_hat(2) - follower_.theta(1)) <= threshold &&
follower_.path_distance_to_go() < 1e-3;
@@ -100,6 +101,8 @@
EKF arm_ekf_;
TrajectoryFollower follower_;
+ const ::std::vector<::Eigen::Matrix<double, 2, 1>> points_;
+
// Start at the 0th index.
uint32_t current_node_ = 0;
diff --git a/y2018/control_loops/superstructure/arm/trajectory.cc b/y2018/control_loops/superstructure/arm/trajectory.cc
index 018a218..48140dd 100644
--- a/y2018/control_loops/superstructure/arm/trajectory.cc
+++ b/y2018/control_loops/superstructure/arm/trajectory.cc
@@ -477,6 +477,7 @@
void TrajectoryFollower::Update(const ::Eigen::Matrix<double, 6, 1> &X,
bool disabled, double dt, double plan_vmax,
double voltage_limit) {
+ // TODO(austin): Separate voltage limit for shoulder for no path.
last_goal_ = goal_;
if (!has_path()) {
diff --git a/y2018/control_loops/superstructure/intake/intake.h b/y2018/control_loops/superstructure/intake/intake.h
index 599ddde..2c36efa 100644
--- a/y2018/control_loops/superstructure/intake/intake.h
+++ b/y2018/control_loops/superstructure/intake/intake.h
@@ -94,7 +94,7 @@
State state() const { return state_; }
bool clear_of_box() const {
- return controller_.output_position() < -0.2;
+ return controller_.output_position() < -0.1;
}
private: