Fang-Robotics-MCB
Fang Robotics Team Codebase
Loading...
Searching...
No Matches
multi_encoder.hpp
Go to the documentation of this file.
1/*****************************************************************************/
2/********** !!! WARNING: CODE GENERATED BY TAPROOT. DO NOT EDIT !!! **********/
3/*****************************************************************************/
4
5/*
6 * Copyright (c) 2024 Advanced Robotics at the University of Washington <robomstr@uw.edu>
7 *
8 * This file is part of Taproot.
9 *
10 * Taproot is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * Taproot is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with Taproot. If not, see <https://www.gnu.org/licenses/>.
22 */
23
24#ifndef TAPROOT_MULTI_ENCODER_HPP_
25#define TAPROOT_MULTI_ENCODER_HPP_
26
27#include <array>
28
29#include "tap/util_macros.hpp"
30
31#include "modm/architecture/interface/assert.hpp"
32
33#include "encoder_interface.hpp"
34
35namespace tap::encoder
36{
47template <uint32_t COUNT>
49{
50public:
51 MultiEncoder(std::array<EncoderInterface*, COUNT> encoders)
52 : encoders(encoders),
53 seenEncoders(0)
54 {
55 modm_assert(this->encoders[0] != nullptr, "MultiEncoder", "nullptr first encoder");
56 }
57
58 void initialize() override
59 {
60 for (EncoderInterface*& encoder : this->encoders)
61 {
62 if (encoder != nullptr)
63 {
64 encoder->initialize();
65 }
66 }
67 }
68
69 bool isOnline() const override
70 {
71 const_cast<MultiEncoder<COUNT>*>(this)->syncEncoders();
72
73 for (uint32_t i = 0; i < COUNT; i++)
74 {
75 if (this->validEncoder(i))
76 {
77 return true;
78 }
79 }
80
81 return false;
82 }
83
85 {
86 const_cast<MultiEncoder<COUNT>*>(this)->syncEncoders();
87 int onlineEncoders = 0;
88 float position = 0;
89
90 for (uint32_t i = 0; i < COUNT; i++)
91 {
92 if (this->validEncoder(i))
93 {
94 position += this->encoders[i]->getPosition().getUnwrappedValue();
95 onlineEncoders += 1;
96 }
97 }
98
100 onlineEncoders == 0 ? 0 : position / onlineEncoders,
101 0,
102 static_cast<float>(M_TWOPI));
103 }
104
105 float getVelocity() const override
106 {
107 const_cast<MultiEncoder<COUNT>*>(this)->syncEncoders();
108 int onlineEncoders = 0;
109 float velocity = 0;
110
111 for (uint32_t i = 0; i < COUNT; i++)
112 {
113 if (this->validEncoder(i))
114 {
115 velocity += this->encoders[i]->getVelocity();
116 onlineEncoders += 1;
117 }
118 }
119
120 return onlineEncoders == 0 ? 0 : velocity / onlineEncoders;
121 };
122
123 void resetEncoderValue() override
124 {
125 this->syncEncoders();
126
127 for (EncoderInterface*& encoder : this->encoders)
128 {
129 if (encoder != nullptr)
130 {
131 encoder->resetEncoderValue();
132 }
133 }
134 }
135
136 void alignWith(EncoderInterface* other) override
137 {
138 this->syncEncoders();
139
140 for (EncoderInterface*& encoder : this->encoders)
141 {
142 if (encoder != nullptr)
143 {
144 encoder->alignWith(other);
145 }
146 }
147 }
148
150
151private:
152 std::array<EncoderInterface*, COUNT> encoders;
153 uint32_t seenEncoders;
154
155 void syncEncoders()
156 {
157 // The primary encoder *must* be online before syncing anything to it
158 if (this->encoders[0]->isOnline())
159 {
160 for (uint32_t i = 1; i < COUNT; i++)
161 {
162 bool online = this->encoders[i] != nullptr && this->encoders[i]->isOnline();
163 if (online && !this->seenEncoder(i))
164 {
165 // Sync the newly discovered encoder to the primary encoder
166 this->seenEncoders |= 1 << i;
167 encoders[i]->alignWith(encoders[0]);
168 }
169 else if (validEncoder(i) && !seenEncoder(0))
170 {
171 // Primary encoder disappeared but came back, resync it.
172 this->seenEncoders |= 1;
173 encoders[0]->alignWith(encoders[i]);
174 }
175 else if (!online)
176 {
177 // This encoder disappeared, remove it
178 this->seenEncoders &= ~(1 << i);
179 }
180 }
181 this->seenEncoders |= 1;
182 }
183 else
184 {
185 this->seenEncoders &= ~(1);
186 }
187 }
188
189 inline bool validEncoder(uint32_t index) const
190 {
191 return this->seenEncoder(index) && this->encoders[index] != nullptr &&
192 this->encoders[index]->isOnline();
193 }
194
195 inline bool seenEncoder(uint32_t index) const
196 {
197 return ((this->seenEncoders) & (1 << index)) != 0;
198 }
199};
200
201} // namespace tap::encoder
202
203#endif // TAPROOT_MULTI_ENCODER_HPP_
Definition wrapped_float.hpp:51
Definition encoder_interface.hpp:32
Definition multi_encoder.hpp:49
void resetEncoderValue() override
Definition multi_encoder.hpp:123
MultiEncoder(std::array< EncoderInterface *, COUNT > encoders)
Definition multi_encoder.hpp:51
tap::algorithms::WrappedFloat getPosition() const override
Definition multi_encoder.hpp:84
float getVelocity() const override
Definition multi_encoder.hpp:105
void initialize() override
Definition multi_encoder.hpp:58
bool isOnline() const override
Definition multi_encoder.hpp:69
void alignWith(EncoderInterface *other) override
Definition multi_encoder.hpp:136
IUnit i
Definition dimensional_smooth_pid.hpp:2
Definition encoder_interface.hpp:30
#define DISALLOW_COPY_AND_ASSIGN(Typename)
Definition util_macros.hpp:27