Comran Morshed | e9b1292 | 2015-11-04 19:46:48 +0000 | [diff] [blame] | 1 | #include <stdio.h> |
| 2 | #include <string.h> |
| 3 | #include <unistd.h> |
| 4 | |
Brian Silverman | c206573 | 2015-11-28 22:55:30 +0000 | [diff] [blame] | 5 | #include "aos/output/motor_output.h" |
Comran Morshed | e9b1292 | 2015-11-04 19:46:48 +0000 | [diff] [blame] | 6 | #include "aos/common/logging/logging.h" |
| 7 | #include "aos/linux_code/init.h" |
| 8 | #include "aos/common/util/log_interval.h" |
| 9 | #include "aos/common/time.h" |
| 10 | #include "aos/common/logging/queue_logging.h" |
| 11 | #include "aos/common/controls/output_check.q.h" |
| 12 | |
| 13 | #include "bot3/control_loops/drivetrain/drivetrain.q.h" |
| 14 | #include "bot3/control_loops/rollers/rollers.q.h" |
| 15 | |
| 16 | using ::aos::util::SimpleLogInterval; |
| 17 | |
| 18 | namespace bot3 { |
| 19 | namespace output { |
| 20 | |
| 21 | class MotorWriter : public ::aos::MotorOutput { |
| 22 | // Maximum age of an output packet before the motors get zeroed instead. |
Austin Schuh | f2a50ba | 2016-12-24 16:16:26 -0800 | [diff] [blame] | 23 | static constexpr chrono::milliseconds kOutputMaxAge = |
| 24 | chrono::milliseconds(20); |
| 25 | static constexpr chrono::milliseconds kOldLogInterval = |
| 26 | chrono::milliseconds(500); |
Comran Morshed | e9b1292 | 2015-11-04 19:46:48 +0000 | [diff] [blame] | 27 | |
| 28 | double Cap(double value, double max) { |
| 29 | if (value > max) return max; |
| 30 | if (value < -max) return -max; |
| 31 | return value; |
| 32 | } |
| 33 | |
| 34 | virtual void RunIteration() { |
| 35 | values_.digital_module = 0; |
| 36 | values_.pressure_switch_channel = 1; |
| 37 | values_.compressor_channel = 1; |
| 38 | values_.solenoid_module = 0; |
| 39 | |
| 40 | if (true) { |
| 41 | static auto &drivetrain = ::bot3::control_loops::drivetrain.output; |
| 42 | drivetrain.FetchLatest(); |
Austin Schuh | f2a50ba | 2016-12-24 16:16:26 -0800 | [diff] [blame] | 43 | if (drivetrain.IsNewerThan(kOutputMaxAge)) { |
Comran Morshed | e9b1292 | 2015-11-04 19:46:48 +0000 | [diff] [blame] | 44 | LOG_STRUCT(DEBUG, "will output", *drivetrain); |
| 45 | SetPWMOutput(5, drivetrain->right_voltage / 12.0, kTalonBounds); |
| 46 | SetPWMOutput(2, -drivetrain->left_voltage / 12.0, kTalonBounds); |
| 47 | SetSolenoid(1, drivetrain->left_high); |
| 48 | SetSolenoid(8, drivetrain->right_high); |
| 49 | } else { |
| 50 | DisablePWMOutput(2); |
| 51 | DisablePWMOutput(5); |
| 52 | LOG_INTERVAL(drivetrain_old_); |
| 53 | } |
| 54 | drivetrain_old_.Print(); |
| 55 | } |
| 56 | |
| 57 | { |
| 58 | static auto &rollers = ::bot3::control_loops::rollers.output; |
| 59 | rollers.FetchLatest(); |
Austin Schuh | f2a50ba | 2016-12-24 16:16:26 -0800 | [diff] [blame] | 60 | if (rollers.IsNewerThan(kOutputMaxAge)) { |
Comran Morshed | e9b1292 | 2015-11-04 19:46:48 +0000 | [diff] [blame] | 61 | LOG_STRUCT(DEBUG, "will output", *rollers); |
| 62 | // There are two motors for each of these. |
| 63 | SetPWMOutput(3, rollers->front_intake_voltage / 12.0, kTalonBounds); |
| 64 | SetPWMOutput(7, -rollers->front_intake_voltage / 12.0, kTalonBounds); |
| 65 | SetPWMOutput(1, rollers->back_intake_voltage / 12.0, kTalonBounds); |
| 66 | SetPWMOutput(6, -rollers->back_intake_voltage / 12.0, kTalonBounds); |
| 67 | SetPWMOutput(4, rollers->low_goal_voltage / 12.0, kTalonBounds); |
| 68 | |
| 69 | SetSolenoid(2, rollers->front_extended); |
| 70 | SetSolenoid(5, !rollers->front_extended); |
| 71 | SetSolenoid(3, rollers->back_extended); |
| 72 | SetSolenoid(4, !rollers->back_extended); |
| 73 | } else { |
| 74 | DisablePWMOutput(3); |
| 75 | DisablePWMOutput(7); |
| 76 | DisablePWMOutput(1); |
| 77 | DisablePWMOutput(6); |
| 78 | DisablePWMOutput(4); |
| 79 | |
| 80 | // Retract intakes. |
| 81 | SetSolenoid(2, false); |
| 82 | SetSolenoid(3, false); |
| 83 | SetSolenoid(5, true); |
| 84 | SetSolenoid(4, true); |
| 85 | |
| 86 | LOG_INTERVAL(rollers_old_); |
| 87 | } |
| 88 | rollers_old_.Print(); |
| 89 | } |
| 90 | |
| 91 | { |
| 92 | auto message = ::aos::controls::output_check_sent.MakeMessage(); |
| 93 | ++output_check_; |
| 94 | if (output_check_ == 0) output_check_ = 1; |
| 95 | SetRawPWMOutput(10, output_check_); |
| 96 | message->pwm_value = output_check_; |
| 97 | message->pulse_length = |
| 98 | static_cast<double>(message->pwm_value) / 255.0 * 2.0 + 0.5; |
| 99 | LOG_STRUCT(DEBUG, "sending", *message); |
| 100 | message.Send(); |
| 101 | } |
| 102 | } |
| 103 | |
| 104 | SimpleLogInterval drivetrain_old_ = |
| 105 | SimpleLogInterval(kOldLogInterval, WARNING, "drivetrain too old"); |
| 106 | SimpleLogInterval rollers_old_ = |
| 107 | SimpleLogInterval(kOldLogInterval, WARNING, "rollers too old"); |
| 108 | |
| 109 | uint8_t output_check_ = 0; |
| 110 | }; |
| 111 | |
Austin Schuh | f2a50ba | 2016-12-24 16:16:26 -0800 | [diff] [blame] | 112 | constexpr chrono::milliseconds MotorWriter::kOldLogInterval; |
Comran Morshed | e9b1292 | 2015-11-04 19:46:48 +0000 | [diff] [blame] | 113 | |
| 114 | } // namespace output |
| 115 | } // namespace bot3 |
| 116 | |
| 117 | int main() { |
| 118 | ::aos::Init(); |
| 119 | ::bot3::output::MotorWriter writer; |
| 120 | writer.Run(); |
| 121 | ::aos::Cleanup(); |
| 122 | } |