blob: 24a766c4e0c86be101fe82b0c323a4683cc892b7 [file] [log] [blame]
Austin Schuh80ff2e12014-03-08 12:06:19 -08001#include <functional>
2#include <numeric>
3
4#include <Eigen/Dense>
5
Brian3afd6fc2014-04-02 20:41:49 -07006#include "aos/common/util/phased_loop.h"
Austin Schuh80ff2e12014-03-08 12:06:19 -08007#include "aos/common/logging/logging.h"
8#include "aos/common/util/trapezoid_profile.h"
9
10#include "frc971/actions/drivetrain_action.h"
11#include "frc971/constants.h"
12#include "frc971/control_loops/drivetrain/drivetrain.q.h"
13
14namespace frc971 {
15namespace actions {
16
17DrivetrainAction::DrivetrainAction(actions::DrivetrainActionQueueGroup* s)
18 : actions::ActionBase<actions::DrivetrainActionQueueGroup>(s) {}
19
20void DrivetrainAction::RunAction() {
21 const double yoffset = action_q_->goal->y_offset;
Brian Silvermanad9e0002014-04-13 14:55:57 -070022 const double turn_offset =
23 action_q_->goal->theta_offset * constants::GetValues().turn_width / 2.0;
24 LOG(INFO, "Going to move %f and turn %f\n", yoffset, turn_offset);
Austin Schuh80ff2e12014-03-08 12:06:19 -080025
26 // Measured conversion to get the distance right.
27 ::aos::util::TrapezoidProfile profile(::aos::time::Time::InMS(10));
Brian Silvermanad9e0002014-04-13 14:55:57 -070028 ::aos::util::TrapezoidProfile turn_profile(::aos::time::Time::InMS(10));
Austin Schuh80ff2e12014-03-08 12:06:19 -080029 const double goal_velocity = 0.0;
30 const double epsilon = 0.01;
Brian Silvermanad9e0002014-04-13 14:55:57 -070031 ::Eigen::Matrix<double, 2, 1> left_goal_state, right_goal_state;
Austin Schuh80ff2e12014-03-08 12:06:19 -080032
Brian Silvermanad9e0002014-04-13 14:55:57 -070033 profile.set_maximum_acceleration(3.0);
Austin Schuh80ff2e12014-03-08 12:06:19 -080034 profile.set_maximum_velocity(action_q_->goal->maximum_velocity);
Brian Silvermanad9e0002014-04-13 14:55:57 -070035 turn_profile.set_maximum_acceleration(
36 10.0 * constants::GetValues().turn_width / 2.0);
37 turn_profile.set_maximum_velocity(3.0 * constants::GetValues().turn_width /
38 2.0);
Austin Schuh80ff2e12014-03-08 12:06:19 -080039
40 while (true) {
41 // wait until next 10ms tick
42 ::aos::time::PhasedLoop10MS(5000);
Brian Silvermanad9e0002014-04-13 14:55:57 -070043 const auto drive_profile_goal_state =
44 profile.Update(yoffset, goal_velocity);
45 const auto turn_profile_goal_state = turn_profile.Update(turn_offset, 0.0);
46 left_goal_state = drive_profile_goal_state - turn_profile_goal_state;
47 right_goal_state = drive_profile_goal_state + turn_profile_goal_state;
Austin Schuh80ff2e12014-03-08 12:06:19 -080048
Brian Silvermanad9e0002014-04-13 14:55:57 -070049 if (::std::abs(drive_profile_goal_state(0, 0) - yoffset) < epsilon &&
50 ::std::abs(turn_profile_goal_state(0, 0) - turn_offset) < epsilon) {
51 break;
52 }
Austin Schuh80ff2e12014-03-08 12:06:19 -080053 if (ShouldCancel()) return;
54
55 LOG(DEBUG, "Driving left to %f, right to %f\n",
Brian Silvermanad9e0002014-04-13 14:55:57 -070056 left_goal_state(0, 0) + action_q_->goal->left_initial_position,
57 right_goal_state(0, 0) + action_q_->goal->right_initial_position);
Austin Schuh80ff2e12014-03-08 12:06:19 -080058 control_loops::drivetrain.goal.MakeWithBuilder()
59 .control_loop_driving(true)
60 .highgear(false)
Brian Silvermanad9e0002014-04-13 14:55:57 -070061 .left_goal(left_goal_state(0, 0) + action_q_->goal->left_initial_position)
62 .right_goal(right_goal_state(0, 0) + action_q_->goal->right_initial_position)
63 .left_velocity_goal(left_goal_state(1, 0))
64 .right_velocity_goal(right_goal_state(1, 0))
Austin Schuh80ff2e12014-03-08 12:06:19 -080065 .Send();
66 }
Brian Silvermanad9e0002014-04-13 14:55:57 -070067 if (ShouldCancel()) return;
Austin Schuh577edf62014-04-13 10:33:05 -070068 control_loops::drivetrain.status.FetchLatest();
69 while (!control_loops::drivetrain.status.get()) {
70 LOG(WARNING,
71 "No previous drivetrain status packet, trying to fetch again\n");
72 control_loops::drivetrain.status.FetchNextBlocking();
73 if (ShouldCancel()) return;
74 }
75 while (true) {
76 if (ShouldCancel()) return;
77 const double kPositionThreshold = 0.05;
78
79 const double left_error = ::std::abs(
80 control_loops::drivetrain.status->filtered_left_position -
Brian Silvermanad9e0002014-04-13 14:55:57 -070081 (left_goal_state(0, 0) + action_q_->goal->left_initial_position));
Austin Schuh577edf62014-04-13 10:33:05 -070082 const double right_error = ::std::abs(
83 control_loops::drivetrain.status->filtered_right_position -
Brian Silvermanad9e0002014-04-13 14:55:57 -070084 (right_goal_state(0, 0) + action_q_->goal->right_initial_position));
Austin Schuh577edf62014-04-13 10:33:05 -070085 const double velocity_error =
86 ::std::abs(control_loops::drivetrain.status->robot_speed);
87 if (left_error < kPositionThreshold && right_error < kPositionThreshold &&
88 velocity_error < 0.2) {
89 break;
90 } else {
91 LOG(DEBUG, "Drivetrain error is %f, %f, %f\n", left_error, right_error,
92 velocity_error);
93 }
94 control_loops::drivetrain.status.FetchNextBlocking();
95 }
Austin Schuh80ff2e12014-03-08 12:06:19 -080096 LOG(INFO, "Done moving\n");
97}
98
99::std::unique_ptr<TypedAction< ::frc971::actions::DrivetrainActionQueueGroup>>
100MakeDrivetrainAction() {
101 return ::std::unique_ptr<
102 TypedAction< ::frc971::actions::DrivetrainActionQueueGroup>>(
103 new TypedAction< ::frc971::actions::DrivetrainActionQueueGroup>(
104 &::frc971::actions::drivetrain_action));
105}
106
107} // namespace actions
108} // namespace frc971