blob: 3b6224c5d47719da963712d09a8686415f201e43 [file] [log] [blame]
#include "y2018/control_loops/superstructure/superstructure.h"
#include "aos/common/controls/control_loops.q.h"
#include "aos/common/logging/logging.h"
#include "frc971/control_loops/control_loops.q.h"
#include "y2018/constants.h"
#include "y2018/control_loops/superstructure/intake/intake.h"
namespace y2018 {
namespace control_loops {
namespace superstructure {
namespace {
// The maximum voltage the intake roller will be allowed to use.
constexpr double kMaxIntakeRollerVoltage = 12.0;
} // namespace
Superstructure::Superstructure(
control_loops::SuperstructureQueue *superstructure_queue)
: aos::controls::ControlLoop<control_loops::SuperstructureQueue>(
superstructure_queue),
intake_left_(constants::GetValues().left_intake.zeroing),
intake_right_(constants::GetValues().right_intake.zeroing) {}
void Superstructure::RunIteration(
const control_loops::SuperstructureQueue::Goal *unsafe_goal,
const control_loops::SuperstructureQueue::Position *position,
control_loops::SuperstructureQueue::Output *output,
control_loops::SuperstructureQueue::Status *status) {
if (WasReset()) {
LOG(ERROR, "WPILib reset, restarting\n");
intake_left_.Reset();
intake_right_.Reset();
arm_.Reset();
}
const double left_intake_goal = ::std::min(
arm_.max_intake_override(),
(unsafe_goal == nullptr ? 0.0 : unsafe_goal->intake.left_intake_angle));
intake_left_.Iterate(unsafe_goal != nullptr ? &(left_intake_goal) : nullptr,
&(position->left_intake),
output != nullptr ? &(output->left_intake) : nullptr,
&(status->left_intake));
const double right_intake_goal = ::std::min(
arm_.max_intake_override(),
(unsafe_goal == nullptr ? 0.0 : unsafe_goal->intake.right_intake_angle));
intake_right_.Iterate(unsafe_goal != nullptr ? &(right_intake_goal) : nullptr,
&(position->right_intake),
output != nullptr ? &(output->right_intake) : nullptr,
&(status->right_intake));
const bool intake_clear_of_box =
intake_left_.clear_of_box() && intake_right_.clear_of_box();
arm_.Iterate(
unsafe_goal != nullptr ? &(unsafe_goal->arm_goal_position) : nullptr,
unsafe_goal != nullptr ? unsafe_goal->grab_box : false,
unsafe_goal != nullptr ? unsafe_goal->open_claw : false, &(position->arm),
position->claw_beambreak_triggered,
position->box_back_beambreak_triggered, intake_clear_of_box,
output != nullptr ? &(output->voltage_proximal) : nullptr,
output != nullptr ? &(output->voltage_distal) : nullptr,
output != nullptr ? &(output->release_arm_brake) : nullptr,
output != nullptr ? &(output->claw_grabbed) : nullptr, &(status->arm));
status->estopped = status->left_intake.estopped ||
status->right_intake.estopped || status->arm.estopped;
status->zeroed = status->left_intake.zeroed && status->right_intake.zeroed &&
status->arm.zeroed;
if (output && unsafe_goal) {
double roller_voltage = ::std::max(
-kMaxIntakeRollerVoltage, ::std::min(unsafe_goal->intake.roller_voltage,
kMaxIntakeRollerVoltage));
constexpr int kReverseTime = 15;
if (unsafe_goal->intake.roller_voltage < 0.0) {
output->left_intake.voltage_rollers = roller_voltage;
output->right_intake.voltage_rollers = roller_voltage;
rotation_state_ = RotationState::NOT_ROTATING;
rotation_count_ = 0;
} else {
switch (rotation_state_) {
case RotationState::NOT_ROTATING:
if (position->left_intake.beam_break) {
rotation_state_ = RotationState::ROTATING_RIGHT;
rotation_count_ = kReverseTime;
break;
} else if (position->right_intake.beam_break) {
rotation_state_ = RotationState::ROTATING_LEFT;
rotation_count_ = kReverseTime;
break;
} else {
break;
}
case RotationState::ROTATING_LEFT:
if (position->right_intake.beam_break) {
rotation_count_ = kReverseTime;
} else {
--rotation_count_;
}
if (rotation_count_ == 0) {
rotation_state_ = RotationState::NOT_ROTATING;
}
break;
case RotationState::ROTATING_RIGHT:
if (position->left_intake.beam_break) {
rotation_count_ = kReverseTime;
} else {
--rotation_count_;
}
if (rotation_count_ == 0) {
rotation_state_ = RotationState::NOT_ROTATING;
}
break;
}
if (position->box_back_beambreak_triggered && roller_voltage > 0.0) {
roller_voltage = 0;
}
switch (rotation_state_) {
case RotationState::NOT_ROTATING:
output->left_intake.voltage_rollers = roller_voltage;
output->right_intake.voltage_rollers = roller_voltage;
break;
case RotationState::ROTATING_LEFT:
output->left_intake.voltage_rollers = roller_voltage;
output->right_intake.voltage_rollers = -roller_voltage;
break;
case RotationState::ROTATING_RIGHT:
output->left_intake.voltage_rollers = -roller_voltage;
output->right_intake.voltage_rollers = roller_voltage;
break;
}
}
}
}
} // namespace superstructure
} // namespace control_loops
} // namespace y2018