blob: 7c26f9d16983d0ff6b68cd7307215ae25f7683bd [file] [log] [blame]
Austin Schuh6e242ac2015-03-07 17:08:21 -08001#ifndef FRC971_ACTORS_FRIDGE_PROFILE_LIB_H_
2#define FRC971_ACTORS_FRIDGE_PROFILE_LIB_H_
3
4#include <cmath>
5
6#include "aos/common/actions/actor.h"
7#include "frc971/control_loops/fridge/fridge.q.h"
8
9namespace frc971 {
10namespace actors {
11
12struct ProfileParams {
13 double velocity;
14 double acceleration;
15};
16
17// Base class to provide helper utilities to all Actors who want to control the
18// fridge.
19template <typename T>
20class FridgeActorBase : public aos::common::actions::ActorBase<T> {
21 public:
22 FridgeActorBase(T *queues) : aos::common::actions::ActorBase<T>(queues) {}
23
24 protected:
25 void DoFridgeProfile(double height, double angle,
26 ProfileParams elevator_parameters,
27 ProfileParams arm_parameters, bool grabbers) {
28 DoFridgeProfile(height, angle, elevator_parameters, arm_parameters,
29 grabbers, grabbers, grabbers);
30 }
31
32 void DoFridgeProfile(double height, double angle,
33 ProfileParams elevator_parameters,
34 ProfileParams arm_parameters, bool top_grabbers,
35 bool front_grabbers, bool back_grabbers) {
36 auto new_fridge_goal = control_loops::fridge_queue.goal.MakeMessage();
37 new_fridge_goal->max_velocity = elevator_parameters.velocity;
38 new_fridge_goal->max_acceleration = elevator_parameters.acceleration;
39 new_fridge_goal->height = height;
40 new_fridge_goal->velocity = 0.0;
41 new_fridge_goal->max_angular_velocity = arm_parameters.velocity;
42 new_fridge_goal->max_angular_acceleration = arm_parameters.acceleration;
43 new_fridge_goal->angle = angle;
44 new_fridge_goal->angular_velocity = 0.0;
45 new_fridge_goal->grabbers.top_front = top_grabbers;
46 new_fridge_goal->grabbers.top_back = top_grabbers;
47 new_fridge_goal->grabbers.bottom_front = front_grabbers;
48 new_fridge_goal->grabbers.bottom_back = back_grabbers;
49
50 if (!new_fridge_goal.Send()) {
51 LOG(ERROR, "Failed to send fridge goal\n");
52 return;
53 }
54
55 while (true) {
56 control_loops::fridge_queue.status.FetchAnother();
57
58 constexpr double kProfileError = 1e-5;
59 constexpr double kAngleEpsilon = 0.02, kHeightEpsilon = 0.015;
60
61 if (::std::abs(control_loops::fridge_queue.status->goal_angle - angle) <
62 kProfileError &&
63 ::std::abs(control_loops::fridge_queue.status->goal_height - height) <
64 kProfileError &&
65 ::std::abs(
66 control_loops::fridge_queue.status->goal_angular_velocity) <
67 kProfileError &&
68 ::std::abs(control_loops::fridge_queue.status->goal_velocity) <
69 kProfileError &&
70 ::std::abs(control_loops::fridge_queue.status->angle - angle) <
71 kAngleEpsilon &&
72 ::std::abs(control_loops::fridge_queue.status->height - height) <
73 kHeightEpsilon) {
74 return;
75 }
76
77 if (this->ShouldCancel()) {
78 auto new_fridge_goal = control_loops::fridge_queue.goal.MakeMessage();
79 new_fridge_goal->max_velocity = elevator_parameters.velocity;
80 new_fridge_goal->max_acceleration = elevator_parameters.acceleration;
81 new_fridge_goal->height =
82 control_loops::fridge_queue.status->height +
83 ::std::pow(control_loops::fridge_queue.status->goal_velocity, 2.0) /
84 (2.0 * new_fridge_goal->max_acceleration);
85 new_fridge_goal->velocity = 0.0;
86 new_fridge_goal->max_angular_velocity = arm_parameters.velocity;
87 new_fridge_goal->max_angular_acceleration = arm_parameters.acceleration;
88 new_fridge_goal->angle =
89 control_loops::fridge_queue.status->angle +
90 ::std::pow(
91 control_loops::fridge_queue.status->goal_angular_velocity,
92 2.0) /
93 (2.0 * new_fridge_goal->max_angular_acceleration);
94 new_fridge_goal->angular_velocity = 0.0;
95 new_fridge_goal->grabbers.top_front = top_grabbers;
96 new_fridge_goal->grabbers.top_back = top_grabbers;
97 new_fridge_goal->grabbers.bottom_front = front_grabbers;
98 new_fridge_goal->grabbers.bottom_back = back_grabbers;
99
100 if (!new_fridge_goal.Send()) {
101 LOG(ERROR, "Failed to send fridge goal\n");
102 return;
103 }
104 }
105 }
106 }
107};
108
109} // namespace actors
110} // namespace frc971
111
112#endif // FRC971_ACTORS_FRIDGE_PROFILE_LIB_H_