blob: 165d99ffc323a7f65c855a708f8261ee7227530d [file] [log] [blame]
James Kuszmaulf7f5ec12013-11-01 17:58:58 -07001#include "bot3/control_loops/shooter/shooter.h"
2
3#include "aos/common/control_loop/control_loops.q.h"
4#include "aos/common/logging/logging.h"
5
6#include "bot3/control_loops/shooter/shooter_motor_plant.h"
7
8namespace bot3 {
9namespace control_loops {
10
11ShooterMotor::ShooterMotor(control_loops::ShooterLoop *my_shooter)
12 : aos::control_loops::ControlLoop<control_loops::ShooterLoop>(my_shooter),
Daniel Petti6c3331b2013-11-03 19:18:10 +000013 loop_(new StateFeedbackLoop<1, 1, 1>(MakeShooterLoop())),
James Kuszmaulf7f5ec12013-11-01 17:58:58 -070014 last_velocity_goal_(0) {
Daniel Petti6c3331b2013-11-03 19:18:10 +000015 loop_->Reset();
James Kuszmaul8c0eed82013-11-05 20:28:05 -080016 U_add = loop_->B().inverse() * (loop_->A().Identity() - loop_->A());
James Kuszmaulf7f5ec12013-11-01 17:58:58 -070017}
18
19/*static*/ const double ShooterMotor::dt = 0.01;
20
21void ShooterMotor::RunIteration(
22 const control_loops::ShooterLoop::Goal *goal,
23 const control_loops::ShooterLoop::Position *position,
24 ::aos::control_loops::Output *output,
25 control_loops::ShooterLoop::Status *status) {
26 double velocity_goal = goal->velocity;
Daniel Petti6c3331b2013-11-03 19:18:10 +000027 // Our position here is actually a velocity.
28 average_velocity_ =
James Kuszmaulf7f5ec12013-11-01 17:58:58 -070029 (position == NULL ? loop_->X_hat(0, 0) : position->position);
30 double output_voltage = 0.0;
31
Daniel Petti6c3331b2013-11-03 19:18:10 +000032// TODO (danielp): This must be modified for our index.
James Kuszmaulf7f5ec12013-11-01 17:58:58 -070033/* if (index_loop.status.FetchLatest() || index_loop.status.get()) {
34 if (index_loop.status->is_shooting) {
35 if (velocity_goal != last_velocity_goal_ &&
36 velocity_goal < 130) {
37 velocity_goal = last_velocity_goal_;
38 }
39 }
40 } else {
41 LOG(WARNING, "assuming index isn't shooting\n");
42 }*/
43 last_velocity_goal_ = velocity_goal;
44
Daniel Petti6c3331b2013-11-03 19:18:10 +000045 loop_->Y << average_velocity_;
46 loop_->R << velocity_goal;
James Kuszmaulf7f5ec12013-11-01 17:58:58 -070047
James Kuszmaul8c0eed82013-11-05 20:28:05 -080048 loop_->Update(position, output == NULL, U_add * loop_->R);
James Kuszmaulf7f5ec12013-11-01 17:58:58 -070049
50 // Kill power at low velocity goals.
51 if (velocity_goal < 1.0) {
Daniel Petti6c3331b2013-11-03 19:18:10 +000052 loop_->U(0) = 0.0;
James Kuszmaulf7f5ec12013-11-01 17:58:58 -070053 } else {
Daniel Petti6c3331b2013-11-03 19:18:10 +000054 output_voltage = loop_->U(0);
James Kuszmaulf7f5ec12013-11-01 17:58:58 -070055 }
56
57 LOG(DEBUG,
Daniel Petti6c3331b2013-11-03 19:18:10 +000058 "PWM: %f, raw_velocity: %f, xhat[0]: %f, R[0]: %f\n",
59 output_voltage, average_velocity_, loop_->X_hat[0], loop_->R[0]);
James Kuszmaulf7f5ec12013-11-01 17:58:58 -070060
61 status->average_velocity = average_velocity_;
62
63 // Determine if the velocity is close enough to the goal to be ready.
64 if (std::abs(velocity_goal - average_velocity_) < 10.0 &&
65 velocity_goal != 0.0) {
66 LOG(DEBUG, "Steady: ");
67 status->ready = true;
68 } else {
69 LOG(DEBUG, "Not ready: ");
70 status->ready = false;
71 }
72 LOG(DEBUG, "avg = %f goal = %f\n", average_velocity_, velocity_goal);
73
James Kuszmaulf7f5ec12013-11-01 17:58:58 -070074 if (output) {
75 output->voltage = output_voltage;
76 }
77}
78
79} // namespace control_loops
80} // namespace bot3