Add spline management to base_autonomous_actor
We can now start and run splines. And it works!
Change-Id: Ic58cf8fb298538bd5446f00c2989f817561f9db1
diff --git a/frc971/autonomous/base_autonomous_actor.cc b/frc971/autonomous/base_autonomous_actor.cc
index ac1b3b7..ade396e 100644
--- a/frc971/autonomous/base_autonomous_actor.cc
+++ b/frc971/autonomous/base_autonomous_actor.cc
@@ -66,7 +66,7 @@
drivetrain_message->linear = linear;
drivetrain_message->angular = angular;
- LOG_STRUCT(DEBUG, "drivetrain_goal", *drivetrain_message);
+ LOG_STRUCT(DEBUG, "dtg", *drivetrain_message);
drivetrain_message.Send();
}
@@ -349,6 +349,96 @@
}
}
+BaseAutonomousActor::SplineHandle BaseAutonomousActor::PlanSpline(
+ const ::frc971::MultiSpline &spline) {
+ LOG(INFO, "Planning spline\n");
+
+ int32_t spline_handle = (++spline_handle_) | ((getpid() & 0xFFFF) << 15);
+
+ drivetrain_queue.goal.FetchLatest();
+
+ auto drivetrain_message = drivetrain_queue.goal.MakeMessage();
+ drivetrain_message->controller_type = 2;
+
+ drivetrain_message->spline = spline;
+ drivetrain_message->spline.spline_idx = spline_handle;
+ drivetrain_message->spline_handle = goal_spline_handle_;
+
+ LOG_STRUCT(DEBUG, "dtg", *drivetrain_message);
+
+ drivetrain_message.Send();
+
+ return BaseAutonomousActor::SplineHandle(spline_handle, this);
+}
+
+bool BaseAutonomousActor::SplineHandle::IsPlanned() {
+ drivetrain_queue.status.FetchLatest();
+ LOG_STRUCT(INFO, "dts", *drivetrain_queue.status.get());
+ if (drivetrain_queue.status.get() &&
+ ((drivetrain_queue.status->trajectory_logging.planning_spline_idx ==
+ spline_handle_ &&
+ drivetrain_queue.status->trajectory_logging.planning_state == 3) ||
+ drivetrain_queue.status->trajectory_logging.current_spline_idx ==
+ spline_handle_)) {
+ return true;
+ }
+ return false;
+}
+
+bool BaseAutonomousActor::SplineHandle::WaitForPlan() {
+ ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
+ ::std::chrono::milliseconds(5) / 2);
+ while (true) {
+ if (base_autonomous_actor_->ShouldCancel()) {
+ return false;
+ }
+ phased_loop.SleepUntilNext();
+ if (IsPlanned()) {
+ return true;
+ }
+ }
+}
+
+void BaseAutonomousActor::SplineHandle::Start() {
+ auto drivetrain_message = drivetrain_queue.goal.MakeMessage();
+ drivetrain_message->controller_type = 2;
+
+ LOG(INFO, "Starting spline\n");
+
+ drivetrain_message->spline_handle = spline_handle_;
+ base_autonomous_actor_->goal_spline_handle_ = spline_handle_;
+
+ LOG_STRUCT(DEBUG, "dtg", *drivetrain_message);
+
+ drivetrain_message.Send();
+}
+
+bool BaseAutonomousActor::SplineHandle::IsDone() {
+ drivetrain_queue.status.FetchLatest();
+ LOG_STRUCT(INFO, "dts", *drivetrain_queue.status.get());
+
+ if (drivetrain_queue.status.get() &&
+ drivetrain_queue.status->trajectory_logging.current_spline_idx ==
+ spline_handle_) {
+ return false;
+ }
+ return true;
+}
+
+bool BaseAutonomousActor::SplineHandle::WaitForDone() {
+ ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
+ ::std::chrono::milliseconds(5) / 2);
+ while (true) {
+ if (base_autonomous_actor_->ShouldCancel()) {
+ return false;
+ }
+ phased_loop.SleepUntilNext();
+ if (IsDone()) {
+ return true;
+ }
+ }
+}
+
::std::unique_ptr<AutonomousAction> MakeAutonomousAction(
const AutonomousActionParams ¶ms) {
return ::std::unique_ptr<AutonomousAction>(
diff --git a/frc971/autonomous/base_autonomous_actor.h b/frc971/autonomous/base_autonomous_actor.h
index dd53a7d..7e3ef35 100644
--- a/frc971/autonomous/base_autonomous_actor.h
+++ b/frc971/autonomous/base_autonomous_actor.h
@@ -20,6 +20,32 @@
const control_loops::drivetrain::DrivetrainConfig<double> &dt_config);
protected:
+ class SplineHandle {
+ public:
+ bool IsPlanned();
+ bool WaitForPlan();
+ void Start();
+
+ bool IsDone();
+ bool WaitForDone();
+
+ // Wait for done, wait until X from the end, wait for distance from the end
+
+ private:
+ friend BaseAutonomousActor;
+ SplineHandle(int32_t spline_handle,
+ BaseAutonomousActor *base_autonomous_actor)
+ : spline_handle_(spline_handle),
+ base_autonomous_actor_(base_autonomous_actor) {}
+
+ int32_t spline_handle_;
+ BaseAutonomousActor *base_autonomous_actor_;
+ };
+
+ // Starts planning the spline, and returns a handle to be used to manipulate
+ // it.
+ SplineHandle PlanSpline(const ::frc971::MultiSpline &spline);
+
void ResetDrivetrain();
void InitializeEncoders();
void StartDrive(double distance, double angle, ProfileParameters linear,
@@ -67,7 +93,14 @@
}
private:
+ friend class SplineHandle;
+
double max_drivetrain_voltage_ = 12.0;
+
+ // Unique counter so we get unique spline handles.
+ int spline_handle_ = 0;
+ // Last goal spline handle;
+ int32_t goal_spline_handle_ = 0;
};
using AutonomousAction =