blob: 357c4b6c938e3ea1a48920948ad2ddf11abeb2eb [file] [log] [blame]
Austin Schuh87c10632017-02-05 19:02:17 -08001#include "y2017/control_loops/superstructure/superstructure.h"
2
3#include "aos/common/controls/control_loops.q.h"
4#include "aos/common/logging/logging.h"
5#include "y2017/constants.h"
Austin Schuhd5ccb862017-03-11 22:06:36 -08006#include "y2017/control_loops/superstructure/column/column.h"
Austin Schuh87c10632017-02-05 19:02:17 -08007#include "y2017/control_loops/superstructure/hood/hood.h"
Adam Snaider79900c22017-02-08 20:23:15 -08008#include "y2017/control_loops/superstructure/intake/intake.h"
Austin Schuhd5ccb862017-03-11 22:06:36 -08009#include "y2017/control_loops/superstructure/shooter/shooter.h"
Austin Schuh87c10632017-02-05 19:02:17 -080010
11namespace y2017 {
12namespace control_loops {
13namespace superstructure {
14
Campbell Crowley651c4b42017-02-17 22:30:50 -080015namespace {
16// The maximum voltage the intake roller will be allowed to use.
17constexpr double kMaxIntakeRollerVoltage = 12.0;
18constexpr double kMaxIndexerRollerVoltage = 12.0;
19} // namespace
20
Austin Schuh87c10632017-02-05 19:02:17 -080021Superstructure::Superstructure(
22 control_loops::SuperstructureQueue *superstructure_queue)
23 : aos::controls::ControlLoop<control_loops::SuperstructureQueue>(
24 superstructure_queue) {}
25
26void Superstructure::RunIteration(
27 const control_loops::SuperstructureQueue::Goal *unsafe_goal,
28 const control_loops::SuperstructureQueue::Position *position,
29 control_loops::SuperstructureQueue::Output *output,
30 control_loops::SuperstructureQueue::Status *status) {
31 if (WasReset()) {
32 LOG(ERROR, "WPILib reset, restarting\n");
33 hood_.Reset();
Adam Snaider79900c22017-02-08 20:23:15 -080034 intake_.Reset();
Tyler Chatow2737d2a2017-02-08 21:20:51 -080035 shooter_.Reset();
Austin Schuhd5ccb862017-03-11 22:06:36 -080036 column_.Reset();
Austin Schuh87c10632017-02-05 19:02:17 -080037 }
38
39 hood_.Iterate(unsafe_goal != nullptr ? &(unsafe_goal->hood) : nullptr,
40 &(position->hood),
41 output != nullptr ? &(output->voltage_hood) : nullptr,
42 &(status->hood));
Tyler Chatow2737d2a2017-02-08 21:20:51 -080043 shooter_.Iterate(unsafe_goal != nullptr ? &(unsafe_goal->shooter) : nullptr,
Austin Schuh932a5ce2017-03-05 01:04:18 -080044 &(position->theta_shooter), position->sent_time,
Campbell Crowley651c4b42017-02-17 22:30:50 -080045 output != nullptr ? &(output->voltage_shooter) : nullptr,
46 &(status->shooter));
Austin Schuhd5ccb862017-03-11 22:06:36 -080047
48 // Implement collision avoidance by passing down a freeze or range restricting
49 // signal to the column and intake objects.
50
51 // Wait until the column is ready before doing collision avoidance.
52 if (unsafe_goal && column_.state() == column::Column::State::RUNNING) {
53 if (!ignore_collisions_) {
54 // The turret is in a position (or wants to be in a position) where we
55 // need the intake out. Push it out.
56 if (::std::abs(unsafe_goal->turret.angle) >
57 column::Column::kTurretNearZero ||
58 ::std::abs(column_.turret_position()) >
59 column::Column::kTurretNearZero) {
60 intake_.set_min_position(column::Column::kIntakeZeroingMinDistance);
61 } else {
62 intake_.clear_min_position();
63 }
64 // The intake is in a position where it could hit. Don't move the turret.
65 if (intake_.position() < column::Column::kIntakeZeroingMinDistance -
66 column::Column::kIntakeTolerance &&
67 ::std::abs(column_.turret_position()) >
68 column::Column::kTurretNearZero) {
69 column_.set_freeze(true);
70 } else {
71 column_.set_freeze(false);
72 }
73 } else {
74 // If we are ignoring collisions, unfreeze and un-limit the min.
75 column_.set_freeze(false);
76 intake_.clear_min_position();
77 }
78 } else {
79 column_.set_freeze(false);
80 }
81
82 // Make some noise if someone left this set...
83 if (ignore_collisions_) {
84 LOG(ERROR, "Collisions ignored\n");
85 }
86
87 intake_.Iterate(unsafe_goal != nullptr ? &(unsafe_goal->intake) : nullptr,
88 &(position->intake),
89 output != nullptr ? &(output->voltage_intake) : nullptr,
90 &(status->intake));
91
92 column_.Iterate(unsafe_goal != nullptr ? &(unsafe_goal->indexer) : nullptr,
93 unsafe_goal != nullptr ? &(unsafe_goal->turret) : nullptr,
94 &(position->column),
95 output != nullptr ? &(output->voltage_indexer) : nullptr,
96 output != nullptr ? &(output->voltage_turret) : nullptr,
97 &(status->indexer), &(status->turret), &intake_);
Campbell Crowley651c4b42017-02-17 22:30:50 -080098
99 if (output && unsafe_goal) {
100 output->voltage_intake_rollers =
101 ::std::max(-kMaxIntakeRollerVoltage,
102 ::std::min(unsafe_goal->intake.voltage_rollers,
103 kMaxIntakeRollerVoltage));
104 output->voltage_indexer_rollers =
105 ::std::max(-kMaxIndexerRollerVoltage,
106 ::std::min(unsafe_goal->indexer.voltage_rollers,
107 kMaxIndexerRollerVoltage));
Adam Snaidere0554ef2017-03-11 23:02:45 -0800108
109 // Set the lights on or off
110 output->lights_on = unsafe_goal->lights_on;
Campbell Crowley651c4b42017-02-17 22:30:50 -0800111 }
Austin Schuh87c10632017-02-05 19:02:17 -0800112}
113
114} // namespace superstructure
115} // namespace control_loops
116} // namespace y2017