vulp  2.3.0
Pi3HatInterface.h
Go to the documentation of this file.
1 // SPDX-License-Identifier: Apache-2.0
2 // Copyright 2022 Stéphane Caron
3 /*
4  * This file incorporates work covered by the following copyright and
5  * permission notice:
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  * Copyright 2020 Josh Pieper, jjp@pobox.com.
9  */
10 
11 #pragma once
12 
13 #include <mjbots/pi3hat/pi3hat.h>
14 #include <pthread.h>
15 #include <spdlog/spdlog.h>
16 
17 #include <Eigen/Geometry>
18 #include <condition_variable>
19 #include <functional>
20 #include <map>
21 #include <memory>
22 #include <mutex>
23 #include <stdexcept>
24 #include <string>
25 #include <thread>
26 #include <utility>
27 #include <vector>
28 
29 #include "vulp/actuation/ImuData.h"
31 #include "vulp/actuation/moteus/protocol.h"
32 #include "vulp/utils/realtime.h"
33 
34 namespace vulp::actuation {
35 
37 
43 class Pi3HatInterface : public Interface {
44  public:
51  Pi3HatInterface(const ServoLayout& layout, const int can_cpu,
52  const Pi3Hat::Configuration& pi3hat_config);
53 
56 
61  void reset(const Dictionary& config) override;
62 
67  void observe(Dictionary& observation) const override;
68 
78  void cycle(const moteus::Data& data,
79  std::function<void(const moteus::Output&)> callback) final;
80 
81  private:
86  void run_can_thread();
87 
92  moteus::Output cycle_can_thread();
93 
99  Eigen::Quaterniond get_attitude() const noexcept {
100  const double w = attitude_.attitude.w;
101  const double x = attitude_.attitude.x;
102  const double y = attitude_.attitude.y;
103  const double z = attitude_.attitude.z;
104  // These values were floats so the resulting quaternion is only
105  // approximately normalized. We saw this property in d7fcaa97fa.
106  return Eigen::Quaterniond(w, x, y, z).normalized();
107  }
108 
114  Eigen::Vector3d get_angular_velocity() const noexcept {
115  const double omega_x = attitude_.rate_dps.x * M_PI / 180.;
116  const double omega_y = attitude_.rate_dps.y * M_PI / 180.;
117  const double omega_z = attitude_.rate_dps.z * M_PI / 180.;
118  return {omega_x, omega_y, omega_z};
119  }
120 
126  Eigen::Vector3d get_linear_acceleration() const noexcept {
127  const double a_x = attitude_.accel_mps2.x;
128  const double a_y = attitude_.accel_mps2.y;
129  const double a_z = attitude_.accel_mps2.z;
130  return {a_x, a_y, a_z};
131  }
132 
133  private:
135  const int can_cpu_;
136 
137  // pi3hat configuration
138  const Pi3Hat::Configuration pi3hat_config_;
139 
141  std::mutex mutex_;
142 
144  std::condition_variable can_wait_condition_;
145 
147  bool ongoing_can_cycle_ = false;
148 
150  bool done_ = false;
151 
153  std::function<void(const moteus::Output&)> callback_;
154 
156  moteus::Data data_;
157 
159  std::thread can_thread_;
160 
162  std::unique_ptr<Pi3Hat> pi3hat_;
163 
164  // These are kept persistently so that no memory allocation is
165  // required in steady state.
166  std::vector<::mjbots::pi3hat::CanFrame> tx_can_;
167  std::vector<::mjbots::pi3hat::CanFrame> rx_can_;
168 
170  ::mjbots::pi3hat::Attitude attitude_;
171 };
172 
173 } // namespace vulp::actuation
Base class for actuation interfaces.
Definition: Interface.h:24
moteus::Data & data()
Get joint command-reply data.
Definition: Interface.h:97
Interface to moteus controllers.
void cycle(const moteus::Data &data, std::function< void(const moteus::Output &)> callback) final
Spin a new communication cycle.
Pi3HatInterface(const ServoLayout &layout, const int can_cpu, const Pi3Hat::Configuration &pi3hat_config)
Configure interface and spawn CAN thread.
void observe(Dictionary &observation) const override
Write actuation-interface observations to dictionary.
void reset(const Dictionary &config) override
Reset interface.
Map between servos, their busses and the joints they actuate.
Definition: ServoLayout.h:12
Send actions to actuators or simulators.
Definition: bullet_utils.h:13
::mjbots::pi3hat::Pi3Hat Pi3Hat