blob: 1000c3b263ca90fd339f2d67178f6f01bda4cd8b [file] [log] [blame]
Comran Morshede68e3732016-03-12 14:12:11 +00001#include "y2016/actors/autonomous_actor.h"
2
3#include <inttypes.h>
4
Comran Morshedb134e772016-03-16 21:05:05 +00005#include <cmath>
6
Comran Morshede68e3732016-03-12 14:12:11 +00007#include "aos/common/util/phased_loop.h"
8#include "aos/common/logging/logging.h"
Comran Morshed435f1112016-03-12 14:20:45 +00009
10#include "frc971/control_loops/drivetrain/drivetrain.q.h"
11#include "y2016/control_loops/drivetrain/drivetrain_base.h"
Comran Morshedb134e772016-03-16 21:05:05 +000012#include "y2016/control_loops/superstructure/superstructure.q.h"
13#include "y2016/actors/autonomous_action.q.h"
Comran Morshede68e3732016-03-12 14:12:11 +000014
15namespace y2016 {
16namespace actors {
Comran Morshed435f1112016-03-12 14:20:45 +000017using ::frc971::control_loops::drivetrain_queue;
18
19namespace {
20const ProfileParameters kSlowDrive = {1.0, 1.0};
21const ProfileParameters kFastDrive = {3.0, 2.5};
22
23const ProfileParameters kSlowTurn = {1.7, 3.0};
24const ProfileParameters kFastTurn = {3.0, 10.0};
25} // namespace
Comran Morshede68e3732016-03-12 14:12:11 +000026
27AutonomousActor::AutonomousActor(actors::AutonomousActionQueueGroup *s)
Comran Morshed435f1112016-03-12 14:20:45 +000028 : aos::common::actions::ActorBase<actors::AutonomousActionQueueGroup>(s),
Comran Morshedb134e772016-03-16 21:05:05 +000029 dt_config_(control_loops::drivetrain::GetDrivetrainConfig()),
30 initial_drivetrain_({0.0, 0.0}) {}
Comran Morshed435f1112016-03-12 14:20:45 +000031
32void AutonomousActor::ResetDrivetrain() {
33 LOG(INFO, "resetting the drivetrain\n");
34 drivetrain_queue.goal.MakeWithBuilder()
35 .control_loop_driving(false)
36 .highgear(true)
37 .steering(0.0)
38 .throttle(0.0)
Comran Morshedb134e772016-03-16 21:05:05 +000039 .left_goal(initial_drivetrain_.left)
Comran Morshed435f1112016-03-12 14:20:45 +000040 .left_velocity_goal(0)
Comran Morshedb134e772016-03-16 21:05:05 +000041 .right_goal(initial_drivetrain_.right)
Comran Morshed435f1112016-03-12 14:20:45 +000042 .right_velocity_goal(0)
43 .Send();
44}
45
46void AutonomousActor::StartDrive(double distance, double angle,
47 ProfileParameters linear,
48 ProfileParameters angular) {
49 {
50 {
51 const double dangle = angle * dt_config_.robot_radius;
Comran Morshedb134e772016-03-16 21:05:05 +000052 initial_drivetrain_.left += distance - dangle;
53 initial_drivetrain_.right += distance + dangle;
Comran Morshed435f1112016-03-12 14:20:45 +000054 }
55
Comran Morshedb134e772016-03-16 21:05:05 +000056 auto drivetrain_message = drivetrain_queue.goal.MakeMessage();
Comran Morshed435f1112016-03-12 14:20:45 +000057 drivetrain_message->control_loop_driving = true;
58 drivetrain_message->highgear = true;
59 drivetrain_message->steering = 0.0;
60 drivetrain_message->throttle = 0.0;
Comran Morshedb134e772016-03-16 21:05:05 +000061 drivetrain_message->left_goal = initial_drivetrain_.left;
Comran Morshed435f1112016-03-12 14:20:45 +000062 drivetrain_message->left_velocity_goal = 0;
Comran Morshedb134e772016-03-16 21:05:05 +000063 drivetrain_message->right_goal = initial_drivetrain_.right;
Comran Morshed435f1112016-03-12 14:20:45 +000064 drivetrain_message->right_velocity_goal = 0;
65 drivetrain_message->linear = linear;
66 drivetrain_message->angular = angular;
67
68 LOG_STRUCT(DEBUG, "drivetrain_goal", *drivetrain_message);
69
70 drivetrain_message.Send();
71 }
72}
73
74void AutonomousActor::InitializeEncoders() {
75 drivetrain_queue.status.FetchAnother();
Comran Morshedb134e772016-03-16 21:05:05 +000076 initial_drivetrain_.left = drivetrain_queue.status->estimated_left_position;
77 initial_drivetrain_.right = drivetrain_queue.status->estimated_right_position;
Comran Morshed435f1112016-03-12 14:20:45 +000078}
79
80void AutonomousActor::WaitUntilDoneOrCanceled(
81 ::std::unique_ptr<aos::common::actions::Action> action) {
82 if (!action) {
83 LOG(ERROR, "No action, not waiting\n");
84 return;
85 }
86
87 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
88 ::aos::time::Time::InMS(5) / 2);
89 while (true) {
90 // Poll the running bit and see if we should cancel.
91 phased_loop.SleepUntilNext();
92 if (!action->Running() || ShouldCancel()) {
93 return;
94 }
95 }
96}
97
98bool AutonomousActor::WaitForDriveDone() {
99 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
100 ::aos::time::Time::InMS(5) / 2);
101 constexpr double kPositionTolerance = 0.02;
102 constexpr double kVelocityTolerance = 0.10;
103 constexpr double kProfileTolerance = 0.001;
104
105 while (true) {
106 if (ShouldCancel()) {
107 return false;
108 }
109 phased_loop.SleepUntilNext();
110 drivetrain_queue.status.FetchLatest();
111 if (drivetrain_queue.status.get()) {
112 if (::std::abs(drivetrain_queue.status->profiled_left_position_goal -
Comran Morshedb134e772016-03-16 21:05:05 +0000113 initial_drivetrain_.left) < kProfileTolerance &&
Comran Morshed435f1112016-03-12 14:20:45 +0000114 ::std::abs(drivetrain_queue.status->profiled_right_position_goal -
Comran Morshedb134e772016-03-16 21:05:05 +0000115 initial_drivetrain_.right) < kProfileTolerance &&
Comran Morshed435f1112016-03-12 14:20:45 +0000116 ::std::abs(drivetrain_queue.status->estimated_left_position -
Comran Morshedb134e772016-03-16 21:05:05 +0000117 initial_drivetrain_.left) < kPositionTolerance &&
Comran Morshed435f1112016-03-12 14:20:45 +0000118 ::std::abs(drivetrain_queue.status->estimated_right_position -
Comran Morshedb134e772016-03-16 21:05:05 +0000119 initial_drivetrain_.right) < kPositionTolerance &&
Comran Morshed435f1112016-03-12 14:20:45 +0000120 ::std::abs(drivetrain_queue.status->estimated_left_velocity) <
121 kVelocityTolerance &&
122 ::std::abs(drivetrain_queue.status->estimated_right_velocity) <
123 kVelocityTolerance) {
124 LOG(INFO, "Finished drive\n");
125 return true;
126 }
127 }
128 }
129}
Comran Morshede68e3732016-03-12 14:12:11 +0000130
Comran Morshedb134e772016-03-16 21:05:05 +0000131void AutonomousActor::MoveSuperstructure(
132 double intake, double shoulder, double wrist,
133 const ProfileParameters intake_params,
134 const ProfileParameters shoulder_params,
135 const ProfileParameters wrist_params, double top_rollers,
136 double bottom_rollers) {
137 superstructure_goal_ = {intake, shoulder, wrist};
138
139 auto new_superstructure_goal =
140 ::y2016::control_loops::superstructure_queue.goal.MakeMessage();
141
142 new_superstructure_goal->angle_intake = intake;
143 new_superstructure_goal->angle_shoulder = shoulder;
144 new_superstructure_goal->angle_wrist = wrist;
145
146 new_superstructure_goal->max_angular_velocity_intake =
147 intake_params.max_velocity;
148 new_superstructure_goal->max_angular_velocity_shoulder =
149 shoulder_params.max_velocity;
150 new_superstructure_goal->max_angular_velocity_wrist =
151 wrist_params.max_velocity;
152
153 new_superstructure_goal->max_angular_acceleration_intake =
154 intake_params.max_acceleration;
155 new_superstructure_goal->max_angular_acceleration_shoulder =
156 shoulder_params.max_acceleration;
157 new_superstructure_goal->max_angular_acceleration_wrist =
158 wrist_params.max_acceleration;
159
160 new_superstructure_goal->voltage_top_rollers = top_rollers;
161 new_superstructure_goal->voltage_bottom_rollers = bottom_rollers;
162
163 if (!new_superstructure_goal.Send()) {
164 LOG(ERROR, "Sending superstructure goal failed.\n");
165 }
166}
167
168void AutonomousActor::WaitForSuperstructure() {
169 while (true) {
170 if (ShouldCancel()) return;
171 control_loops::superstructure_queue.status.FetchAnother();
172
173 constexpr double kProfileError = 1e-5;
174 constexpr double kEpsilon = 0.03;
175
176 if (control_loops::superstructure_queue.status->state < 12 ||
177 control_loops::superstructure_queue.status->state == 16) {
178 LOG(ERROR, "Superstructure no longer running, aborting action\n");
179 return;
180 }
181
182 if (::std::abs(
183 control_loops::superstructure_queue.status->intake.goal_angle -
184 superstructure_goal_.intake) < kProfileError &&
185 ::std::abs(
186 control_loops::superstructure_queue.status->shoulder.goal_angle -
187 superstructure_goal_.shoulder) < kProfileError &&
188 ::std::abs(
189 control_loops::superstructure_queue.status->wrist.goal_angle -
190 superstructure_goal_.wrist) < kProfileError &&
191 ::std::abs(control_loops::superstructure_queue.status->intake
192 .goal_angular_velocity) < kProfileError &&
193 ::std::abs(control_loops::superstructure_queue.status->shoulder
194 .goal_angular_velocity) < kProfileError &&
195 ::std::abs(control_loops::superstructure_queue.status->wrist
196 .goal_angular_velocity) < kProfileError) {
197 LOG(INFO, "Profile done.\n");
198 if (::std::abs(control_loops::superstructure_queue.status->intake.angle -
199 superstructure_goal_.intake) < kEpsilon &&
200 ::std::abs(
201 control_loops::superstructure_queue.status->shoulder.angle -
202 superstructure_goal_.shoulder) < kEpsilon &&
203 ::std::abs(control_loops::superstructure_queue.status->wrist.angle -
204 superstructure_goal_.wrist) < kEpsilon &&
205 ::std::abs(control_loops::superstructure_queue.status->intake
206 .angular_velocity) < kEpsilon &&
207 ::std::abs(control_loops::superstructure_queue.status->shoulder
208 .angular_velocity) < kEpsilon &&
209 ::std::abs(control_loops::superstructure_queue.status->wrist
210 .angular_velocity) < kEpsilon) {
211 LOG(INFO, "Near goal, done.\n");
Austin Schuh1c922402016-03-19 21:41:13 -0700212 return;
Comran Morshedb134e772016-03-16 21:05:05 +0000213 }
214 }
215 }
216}
217
Comran Morshede68e3732016-03-12 14:12:11 +0000218bool AutonomousActor::RunAction(const actors::AutonomousActionParams &params) {
219 LOG(INFO, "Starting autonomous action with mode %" PRId32 "\n", params.mode);
220
Comran Morshed435f1112016-03-12 14:20:45 +0000221 InitializeEncoders();
222 ResetDrivetrain();
223
224 StartDrive(1.0, 0.0, kSlowDrive, kSlowTurn);
225
226 if (!WaitForDriveDone()) return true;
227
228 StartDrive(0.0, M_PI, kSlowDrive, kSlowTurn);
229
230 if (!WaitForDriveDone()) return true;
231
232 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
233 ::aos::time::Time::InMS(5) / 2);
234 while (!ShouldCancel()) {
235 phased_loop.SleepUntilNext();
Comran Morshede68e3732016-03-12 14:12:11 +0000236 }
Comran Morshed435f1112016-03-12 14:20:45 +0000237 LOG(DEBUG, "Done running\n");
Comran Morshede68e3732016-03-12 14:12:11 +0000238
239 return true;
240}
241
242::std::unique_ptr<AutonomousAction> MakeAutonomousAction(
243 const ::y2016::actors::AutonomousActionParams &params) {
244 return ::std::unique_ptr<AutonomousAction>(
245 new AutonomousAction(&::y2016::actors::autonomous_action, params));
246}
247
248} // namespace actors
249} // namespace y2016