blob: 25bfc74224d4f3e342009268508e5d33de0a5520 [file] [log] [blame]
#include "bot3/control_loops/shooter/shooter.h"
#include "bot3/control_loops/shooter/shooter_motor.q.h"
#include "aos/common/control_loop/control_loops.q.h"
#include "aos/common/logging/logging.h"
#include "bot3/control_loops/shooter/shooter_motor_plant.h"
namespace bot3 {
namespace control_loops {
ShooterMotor::ShooterMotor(control_loops::ShooterLoop *my_shooter)
: aos::control_loops::ControlLoop<control_loops::ShooterLoop>(my_shooter),
loop_(new StateFeedbackLoop<1, 1, 1>(MakeShooterLoop())),
last_velocity_goal_(0) {
loop_->Reset();
U_add = loop_->B().inverse() * (loop_->A().Identity() - loop_->A());
}
/*static*/ const double ShooterMotor::dt = 0.01;
void ShooterMotor::RunIteration(
const control_loops::ShooterLoop::Goal *goal,
const control_loops::ShooterLoop::Position *position,
control_loops::ShooterLoop::Output *output,
control_loops::ShooterLoop::Status *status) {
double velocity_goal = goal->velocity;
// Our position here is actually a velocity.
average_velocity_ =
(position == NULL ? loop_->X_hat(0, 0) : position->velocity);
double output_voltage = 0.0;
/* if (index_loop.status.FetchLatest() || index_loop.status.get()) {
if (index_loop.status->is_shooting) {
if (velocity_goal != last_velocity_goal_ &&
velocity_goal < 130) {
velocity_goal = last_velocity_goal_;
}
}
} else {
LOG(WARNING, "assuming index isn't shooting\n");
}*/
last_velocity_goal_ = velocity_goal;
loop_->Y << average_velocity_;
loop_->R << velocity_goal;
loop_->Update(position, output == NULL, U_add * loop_->R);
// Kill power at low velocity goals.
if (velocity_goal < 1.0) {
loop_->U(0) = 0.0;
} else {
output_voltage = loop_->U(0);
}
LOG(DEBUG,
"PWM: %f, raw_velocity: %f, xhat[0]: %f, R[0]: %f\n",
output_voltage, average_velocity_, loop_->X_hat[0], loop_->R[0]);
status->average_velocity = average_velocity_;
// Determine if the velocity is close enough to the goal to be ready.
if (std::abs(velocity_goal - average_velocity_) < 10.0 &&
velocity_goal != 0.0) {
LOG(DEBUG, "Steady: ");
status->ready = true;
} else {
LOG(DEBUG, "Not ready: ");
status->ready = false;
}
LOG(DEBUG, "avg = %f goal = %f\n", average_velocity_, velocity_goal);
if (output) {
output->voltage = output_voltage;
output->intake = goal->intake;
output->push = goal->push;
LOG(DEBUG, "goal: %lf, volt: %lf, push:%d\n", goal->intake, output_voltage, goal->push);
}
}
} // namespace control_loops
} // namespace bot3