blob: 25bfc74224d4f3e342009268508e5d33de0a5520 [file] [log] [blame]
James Kuszmaulf7f5ec12013-11-01 17:58:58 -07001#include "bot3/control_loops/shooter/shooter.h"
James Kuszmaulb74c8112013-11-03 16:13:45 -08002#include "bot3/control_loops/shooter/shooter_motor.q.h"
James Kuszmaulf7f5ec12013-11-01 17:58:58 -07003
4#include "aos/common/control_loop/control_loops.q.h"
5#include "aos/common/logging/logging.h"
6
7#include "bot3/control_loops/shooter/shooter_motor_plant.h"
8
9namespace bot3 {
10namespace control_loops {
11
12ShooterMotor::ShooterMotor(control_loops::ShooterLoop *my_shooter)
13 : aos::control_loops::ControlLoop<control_loops::ShooterLoop>(my_shooter),
Daniel Petti6c3331b2013-11-03 19:18:10 +000014 loop_(new StateFeedbackLoop<1, 1, 1>(MakeShooterLoop())),
James Kuszmaulf7f5ec12013-11-01 17:58:58 -070015 last_velocity_goal_(0) {
Daniel Petti6c3331b2013-11-03 19:18:10 +000016 loop_->Reset();
James Kuszmaul8c0eed82013-11-05 20:28:05 -080017 U_add = loop_->B().inverse() * (loop_->A().Identity() - loop_->A());
James Kuszmaulf7f5ec12013-11-01 17:58:58 -070018}
19
20/*static*/ const double ShooterMotor::dt = 0.01;
21
22void ShooterMotor::RunIteration(
23 const control_loops::ShooterLoop::Goal *goal,
24 const control_loops::ShooterLoop::Position *position,
James Kuszmaulb74c8112013-11-03 16:13:45 -080025 control_loops::ShooterLoop::Output *output,
James Kuszmaulf7f5ec12013-11-01 17:58:58 -070026 control_loops::ShooterLoop::Status *status) {
27 double velocity_goal = goal->velocity;
Daniel Petti6c3331b2013-11-03 19:18:10 +000028 // Our position here is actually a velocity.
29 average_velocity_ =
Daniel Petti5003b772013-11-07 02:19:50 +000030 (position == NULL ? loop_->X_hat(0, 0) : position->velocity);
James Kuszmaulf7f5ec12013-11-01 17:58:58 -070031 double output_voltage = 0.0;
32
33/* 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;
James Kuszmaulb74c8112013-11-03 16:13:45 -080076 output->intake = goal->intake;
77 output->push = goal->push;
78 LOG(DEBUG, "goal: %lf, volt: %lf, push:%d\n", goal->intake, output_voltage, goal->push);
James Kuszmaulf7f5ec12013-11-01 17:58:58 -070079 }
80}
81
82} // namespace control_loops
83} // namespace bot3