blob: 0aa1c58bb1eeb04038bae2e7e9dc4192f197718c [file] [log] [blame]
Brian Silvermanb691f5e2015-08-02 11:37:55 -07001#include "y2015/actors/pickup_actor.h"
Austin Schuh6ab08b82015-02-22 21:41:05 -08002
Austin Schuhf2a50ba2016-12-24 16:16:26 -08003#include <chrono>
Austin Schuh6e242ac2015-03-07 17:08:21 -08004#include <cmath>
Austin Schuh6ab08b82015-02-22 21:41:05 -08005
Austin Schuh6ab08b82015-02-22 21:41:05 -08006#include "aos/common/controls/control_loop.h"
Austin Schuhf2a50ba2016-12-24 16:16:26 -08007#include "aos/common/logging/logging.h"
Austin Schuh6ab08b82015-02-22 21:41:05 -08008#include "aos/common/time.h"
Austin Schuhf2a50ba2016-12-24 16:16:26 -08009#include "aos/common/util/phased_loop.h"
Brian Silvermanb691f5e2015-08-02 11:37:55 -070010#include "y2015/control_loops/claw/claw.q.h"
Austin Schuh6ab08b82015-02-22 21:41:05 -080011
Austin Schuh88af0852016-12-04 20:31:32 -080012namespace y2015 {
Austin Schuh6ab08b82015-02-22 21:41:05 -080013namespace actors {
Austin Schuhe4e59ef2015-03-01 00:05:37 -080014namespace {
15constexpr double kClawPickupVelocity = 3.00;
Austin Schuh9c414f42015-04-19 20:01:56 -070016constexpr double kClawPickupAcceleration = 3.5;
Austin Schuha2ea71a2015-04-18 22:55:28 -070017constexpr double kClawMoveDownVelocity = 7.00;
18constexpr double kClawMoveDownAcceleration = 15.0;
19constexpr double kClawMoveUpVelocity = 8.0;
Austin Schuh9c414f42015-04-19 20:01:56 -070020constexpr double kClawMoveUpAcceleration = 25.0;
Austin Schuhe4e59ef2015-03-01 00:05:37 -080021} // namespace
Austin Schuh6ab08b82015-02-22 21:41:05 -080022
Austin Schuhf2a50ba2016-12-24 16:16:26 -080023namespace chrono = ::std::chrono;
24using ::aos::monotonic_clock;
Austin Schuh88af0852016-12-04 20:31:32 -080025using ::y2015::control_loops::claw_queue;
26
Austin Schuh6ab08b82015-02-22 21:41:05 -080027PickupActor::PickupActor(PickupActionQueueGroup* queues)
28 : aos::common::actions::ActorBase<PickupActionQueueGroup>(queues) {}
29
30bool PickupActor::RunAction(const PickupParams& params) {
Austin Schuhe4e59ef2015-03-01 00:05:37 -080031 constexpr double kAngleEpsilon = 0.10;
Austin Schuha2ea71a2015-04-18 22:55:28 -070032 // Start lifting the tote.
Austin Schuh6ab08b82015-02-22 21:41:05 -080033 {
Austin Schuh88af0852016-12-04 20:31:32 -080034 auto message = claw_queue.goal.MakeMessage();
Austin Schuh6ab08b82015-02-22 21:41:05 -080035 message->angle = params.pickup_angle;
Austin Schuhe4e59ef2015-03-01 00:05:37 -080036 message->max_velocity = kClawPickupVelocity;
37 message->max_acceleration = kClawPickupAcceleration;
Austin Schuh6ab08b82015-02-22 21:41:05 -080038 message->angular_velocity = 0.0;
39 message->intake = 0.0;
40 message->rollers_closed = true;
41
42 LOG_STRUCT(DEBUG, "Sending claw goal", *message);
43 message.Send();
44 }
45 while (true) {
Austin Schuh88af0852016-12-04 20:31:32 -080046 claw_queue.status.FetchAnother();
Austin Schuh6ab08b82015-02-22 21:41:05 -080047 if (ShouldCancel()) return true;
Austin Schuh88af0852016-12-04 20:31:32 -080048 const double current_angle = claw_queue.status->angle;
49 LOG_STRUCT(DEBUG, "Got claw status", *claw_queue.status);
Austin Schuh6ab08b82015-02-22 21:41:05 -080050
51 if (current_angle > params.suck_angle ||
52 ::std::abs(current_angle - params.pickup_angle) < kAngleEpsilon) {
53 break;
54 }
55 }
56
Austin Schuha2ea71a2015-04-18 22:55:28 -070057 // Once above params.suck_angle, start sucking while lifting.
Austin Schuh6ab08b82015-02-22 21:41:05 -080058 {
Austin Schuh88af0852016-12-04 20:31:32 -080059 auto message = claw_queue.goal.MakeMessage();
Austin Schuh6ab08b82015-02-22 21:41:05 -080060 message->angle = params.pickup_angle;
Austin Schuhe4e59ef2015-03-01 00:05:37 -080061 message->max_velocity = kClawPickupVelocity;
62 message->max_acceleration = kClawPickupAcceleration;
Austin Schuh6ab08b82015-02-22 21:41:05 -080063 message->angular_velocity = 0.0;
64 message->intake = params.intake_voltage;
65 message->rollers_closed = true;
66
67 LOG_STRUCT(DEBUG, "Sending claw goal", *message);
68 message.Send();
69 }
70
71 while (true) {
Austin Schuh88af0852016-12-04 20:31:32 -080072 claw_queue.status.FetchAnother();
Austin Schuh6ab08b82015-02-22 21:41:05 -080073 if (ShouldCancel()) return true;
Austin Schuh88af0852016-12-04 20:31:32 -080074 const double current_angle = claw_queue.status->angle;
75 LOG_STRUCT(DEBUG, "Got claw status", *claw_queue.status);
Austin Schuh6ab08b82015-02-22 21:41:05 -080076
77 if (::std::abs(current_angle - params.pickup_angle) < kAngleEpsilon) {
78 break;
79 }
80 }
81
Austin Schuha2ea71a2015-04-18 22:55:28 -070082 // Now that we have reached the upper height, come back down while intaking.
Austin Schuh6ab08b82015-02-22 21:41:05 -080083 {
Austin Schuh88af0852016-12-04 20:31:32 -080084 auto message = claw_queue.goal.MakeMessage();
Austin Schuhe4e59ef2015-03-01 00:05:37 -080085 message->angle = params.suck_angle_finish;
Austin Schuha2ea71a2015-04-18 22:55:28 -070086 message->max_velocity = kClawMoveDownVelocity;
87 message->max_acceleration = kClawMoveDownAcceleration;
Austin Schuh6ab08b82015-02-22 21:41:05 -080088 message->angular_velocity = 0.0;
89 message->intake = params.intake_voltage;
90 message->rollers_closed = true;
91
92 LOG_STRUCT(DEBUG, "Sending claw goal", *message);
93 message.Send();
94 }
95
Austin Schuha2ea71a2015-04-18 22:55:28 -070096 // Pull in for params.intake_time.
Austin Schuhf2a50ba2016-12-24 16:16:26 -080097 monotonic_clock::time_point end_time =
98 monotonic_clock::now() +
99 chrono::duration_cast<chrono::nanoseconds>(
100 chrono::duration<double>(params.intake_time));
101 ::aos::time::PhasedLoop phased_loop(::aos::controls::kLoopFrequency,
102 ::std::chrono::milliseconds(5) / 2);
103 while (monotonic_clock::now() <= end_time) {
104 phased_loop.SleepUntilNext();
Austin Schuh6ab08b82015-02-22 21:41:05 -0800105 if (ShouldCancel()) return true;
106 }
107
Austin Schuha2ea71a2015-04-18 22:55:28 -0700108 // Lift the claw back up to pack the box back in.
Austin Schuh6ab08b82015-02-22 21:41:05 -0800109 {
Austin Schuh88af0852016-12-04 20:31:32 -0800110 auto message = claw_queue.goal.MakeMessage();
Austin Schuh6ab08b82015-02-22 21:41:05 -0800111 message->angle = params.pickup_finish_angle;
Austin Schuha2ea71a2015-04-18 22:55:28 -0700112 message->max_velocity = kClawMoveUpVelocity;
113 message->max_acceleration = kClawMoveUpAcceleration;
Austin Schuh6ab08b82015-02-22 21:41:05 -0800114 message->angular_velocity = 0.0;
Austin Schuha2ea71a2015-04-18 22:55:28 -0700115 message->intake = params.intake_voltage;
Austin Schuh6ab08b82015-02-22 21:41:05 -0800116 message->rollers_closed = true;
117
118 LOG_STRUCT(DEBUG, "Sending claw goal", *message);
119 message.Send();
120 }
121
122 while (true) {
Austin Schuh88af0852016-12-04 20:31:32 -0800123 claw_queue.status.FetchAnother();
Austin Schuh6ab08b82015-02-22 21:41:05 -0800124 if (ShouldCancel()) return true;
Austin Schuh88af0852016-12-04 20:31:32 -0800125 const double current_angle = claw_queue.status->angle;
126 LOG_STRUCT(DEBUG, "Got claw status", *claw_queue.status);
Austin Schuh6ab08b82015-02-22 21:41:05 -0800127
128 if (::std::abs(current_angle - params.pickup_finish_angle) <
129 kAngleEpsilon) {
130 break;
131 }
132 }
133
Austin Schuha2ea71a2015-04-18 22:55:28 -0700134 // Stop the motors...
135 {
Austin Schuh88af0852016-12-04 20:31:32 -0800136 auto message = claw_queue.goal.MakeMessage();
Austin Schuha2ea71a2015-04-18 22:55:28 -0700137 message->angle = params.pickup_finish_angle;
138 message->max_velocity = kClawMoveUpVelocity;
139 message->max_acceleration = kClawMoveUpAcceleration;
140 message->angular_velocity = 0.0;
141 message->intake = 0.0;
142 message->rollers_closed = true;
143
144 LOG_STRUCT(DEBUG, "Sending claw goal", *message);
145 message.Send();
146 }
147
148
Austin Schuh6ab08b82015-02-22 21:41:05 -0800149 return true;
150}
151
152::std::unique_ptr<PickupAction> MakePickupAction(const PickupParams& params) {
153 return ::std::unique_ptr<PickupAction>(
Austin Schuh88af0852016-12-04 20:31:32 -0800154 new PickupAction(&::y2015::actors::pickup_action, params));
Austin Schuh6ab08b82015-02-22 21:41:05 -0800155}
156
157} // namespace actors
Austin Schuh88af0852016-12-04 20:31:32 -0800158} // namespace y2015