Easy Control Library for Cubic 0.01
Loading...
Searching...
No Matches
Cubic.controller.h
Go to the documentation of this file.
1
5#pragma once
6#include <Arduino.h>
7#include "PID.h"
8#include "cubic_arduino.h"
9
16constexpr double degToRad(double deg)
17{
18 return deg * DEG_TO_RAD;
19}
20
27constexpr double radToDeg(double rad)
28{
29 return rad * RAD_TO_DEG;
30}
31
32namespace Cubic_controller
33{
38 constexpr uint16_t AMT22_CPR = 16384;
39
41 constexpr double LOOP_THRESHOLD = 5.0 * PI / 6.0;
42
47 constexpr double ALLOWED_ROTATION_RANGE = 2.0 * PI;
48
55 enum class encoderType
56 {
57 inc,
58 abs
59 };
60
68 constexpr double limitAngle(double angle, const double min = -PI)
69 {
70 while (angle < min)
71 {
72 angle += TWO_PI;
73 }
74 while (angle >= min + TWO_PI)
75 {
76 angle -= TWO_PI;
77 }
78 return angle;
79 }
80
90 constexpr double encoderToAngle(const int32_t encoder, const uint16_t CPR, const double offset = -PI, const bool limit = true)
91 {
92 if (limit)
93 {
94 return limitAngle(offset + encoder * (TWO_PI / (double)CPR));
95 }
96 else
97 {
98 return offset + encoder * (TWO_PI / (double)CPR);
99 }
100 }
101
107 {
108 private:
109 PID::PID &pid;
110
111 double capableDutyCycle;
112 double dutyCycle;
113
114 protected:
116 const uint8_t motorNo;
118 const enum class encoderType encoderType;
120 const uint8_t encoderNo;
125 const uint16_t CPR;
127 const bool direction;
129 const bool logging;
130
137 double compute_PID(double current);
138
139 public:
156 Controller(uint8_t motorNo, uint8_t encoderNo, enum class encoderType encoderType, uint16_t CPR, double Kp, double Ki, double Kd, double target, bool direction, double capableDutyCycle, double current, bool logging = false);
157
163 virtual double compute() = 0;
169 virtual void setTarget(double target);
177 void setGains(double Kp, double Ki, double Kd);
183 void setKp(double Kp);
189 void setKi(double Ki);
195 void setKd(double Kd);
201 int32_t readEncoder() const;
207 double getTarget() const;
213 double getDutyCycle() const;
219 double getDt() const;
225 double getCurrent() const;
226
232 virtual void reset();
233
239 virtual void reset(double target);
240
248 virtual void reset(double Kp, double Ki, double Kd);
249
258 virtual void reset(double Kp, double Ki, double Kd, double target);
259
266 virtual double encoderToAngle(int32_t encoder) = 0;
267 };
268
274 {
275 private:
276 double p;
277 double vLPF = 0.0;
278
279 public:
297 Velocity_PID(uint8_t motorNo, uint8_t encoderNo, enum class encoderType encoderType, uint16_t CPR, double Kp, double Ki, double Kd, double target, bool direction, double capableDutyCycle = 1.0, double p = 1.0, bool logging = false);
303 void setLPF(double p);
304 double encoderToAngle(int32_t encoder) override;
305 double compute() override;
311 void reset() override;
312 void reset(double target) override;
313 void reset(double Kp, double Ki, double Kd) override;
314 void reset(double Kp, double Ki, double Kd, double target) override;
315 };
316
322 {
323 private:
324 int8_t loopCount = 0;
325
326 public:
342 Position_PID(uint8_t motorNo, uint8_t encoderNo, enum class encoderType encoderType, uint16_t CPR, double Kp, double Ki, double Kd, double target, bool direction, double capableDutyCycle = 1.0, bool logging = false);
343
344 void setTarget(double target) override;
345 double encoderToAngle(int32_t encoder) override;
346 double compute() override;
347 };
348
349 // Definition
350
351 inline double Controller::compute_PID(const double current)
352 {
353 return dutyCycle = this->pid.compute_PID(current, logging);
354 }
355 inline void Controller::setTarget(const double target)
356 {
357 this->pid.setTarget(target);
358 }
359 inline void Controller::setGains(const double Kp, const double Ki, const double Kd)
360 {
361 this->pid.setGains(abs(Kp), abs(Ki), abs(Kd));
362 }
363 inline void Controller::setKp(const double Kp)
364 {
365 this->pid.setKp(abs(Kp));
366 }
367 inline void Controller::setKi(const double Ki)
368 {
369 this->pid.setKi(abs(Ki));
370 }
371 inline void Controller::setKd(const double Kd)
372 {
373 this->pid.setKd(abs(Kd));
374 }
375 inline double Controller::getTarget() const
376 {
377 return this->pid.getTarget();
378 }
379 inline double Controller::getCurrent() const
380 {
381 return this->pid.getCurrent();
382 }
383 inline double Controller::getDutyCycle() const
384 {
385 return this->dutyCycle;
386 }
387 inline double Controller::getDt() const
388 {
389 return this->pid.getDt();
390 }
391 inline double Velocity_PID::encoderToAngle(const int32_t encoder)
392 {
393 return Cubic_controller::encoderToAngle(encoder, this->CPR, 0, false);
394 }
395 inline double Position_PID::encoderToAngle(const int32_t encoder)
396 {
397 double angle = Cubic_controller::encoderToAngle(encoder, this->CPR, -PI, true);
398 static double prevAngle = angle;
399 double actualAngle = angle;
400
401 if (actualAngle < -LOOP_THRESHOLD && prevAngle > LOOP_THRESHOLD)
402 {
403 this->loopCount++;
404 }
405 else if (actualAngle > LOOP_THRESHOLD && prevAngle < -LOOP_THRESHOLD)
406 {
407 this->loopCount--;
408 }
409 prevAngle = actualAngle;
410
411 return angle + TWO_PI * this->loopCount;
412 }
413 inline int32_t Controller::readEncoder() const
414 {
415 int32_t value = encoderType == encoderType::inc ? Inc_enc::get_diff(encoderNo) : Abs_enc::get(encoderNo);
416 if (logging)
417 {
418 Serial.print("encoder:");
419 Serial.print(value);
420 Serial.print(",");
421 }
422 return value;
423 }
424 inline void Velocity_PID::setLPF(const double p)
425 {
426 this->p = p;
427 }
428 inline void Controller::reset()
429 {
430 this->pid.reset();
431 }
432 inline void Controller::reset(const double target)
433 {
434 this->pid.reset(target);
435 }
436 inline void Controller::reset(const double Kp, const double Ki, const double Kd)
437 {
438 this->pid.reset(Kp, Ki, Kd);
439 }
440 inline void Controller::reset(const double Kp, const double Ki, const double Kd, const double target)
441 {
442 this->pid.reset(Kp, Ki, Kd, target);
443 }
445 {
447 this->vLPF = 0;
448 }
449 inline void Velocity_PID::reset(const double target)
450 {
451 Controller::reset(target);
452 this->vLPF = 0;
453 }
454 inline void Velocity_PID::reset(const double Kp, const double Ki, const double Kd)
455 {
456 Controller::reset(Kp, Ki, Kd);
457 this->vLPF = 0;
458 }
459 inline void Velocity_PID::reset(const double Kp, const double Ki, const double Kd, const double target)
460 {
461 Controller::reset(Kp, Ki, Kd, target);
462 this->vLPF = 0;
463 }
464}
encoderType
エンコーダの種類を示します
Definition Cubic.controller.h:56
constexpr double ALLOWED_ROTATION_RANGE
アブソリュートエンコーダーの回転をどこまで許容するか。
Definition Cubic.controller.h:47
constexpr double radToDeg(double rad)
弧度法から度数法に変換します
Definition Cubic.controller.h:27
constexpr double LOOP_THRESHOLD
アブソリュートエンコーダのループ閾値
Definition Cubic.controller.h:41
constexpr uint16_t AMT22_CPR
AMT22のCPRです
Definition Cubic.controller.h:38
constexpr double limitAngle(double angle, const double min=-PI)
与えられた角度を一定範囲(min<=angle<min+2pi)に収めます
Definition Cubic.controller.h:68
constexpr double degToRad(double deg)
度数法から弧度法に変換します
Definition Cubic.controller.h:16
constexpr double encoderToAngle(const int32_t encoder, const uint16_t CPR, const double offset=-PI, const bool limit=true)
与えられたCPRのもと、エンコーダの値から角度を計算します
Definition Cubic.controller.h:90
Cubic制御器の抽象クラス
Definition Cubic.controller.h:107
virtual void reset()
制御器のリセット
Definition Cubic.controller.h:428
double compute_PID(double current)
pid.compute_PID()を呼ぶだけの関数です。
Definition Cubic.controller.h:351
const bool logging
ログを出力するかどうか
Definition Cubic.controller.h:129
virtual double compute()=0
duty比を計算します。各ループで一回呼び出してください。このduty比は、DUTY_SPI_MAXに対する比です。計算された値は、この関数内部で、DC_motor::put()されます。
const bool direction
モータをプラスの方向に回したとき、エンコーダが増加するかどうか
Definition Cubic.controller.h:127
const uint8_t motorNo
モータ番号
Definition Cubic.controller.h:116
double getCurrent() const
直前に読んだ制御量を返します。
Definition Cubic.controller.h:379
enum encoderType encoderType
エンコーダの種類
Definition Cubic.controller.h:118
void setKd(double Kd)
Dゲインを設定します。負の値は-1倍されます。
Definition Cubic.controller.h:371
virtual double encoderToAngle(int32_t encoder)=0
エンコーダの値から角度を計算します。設定したCPR(Count Per Revolution)に依存します。
const uint16_t CPR
CPR(Counts Per Revolution)
Definition Cubic.controller.h:125
int32_t readEncoder() const
エンコーダを読みだします。
Definition Cubic.controller.h:413
virtual void setTarget(double target)
制御量の目標値を設定します。
Definition Cubic.controller.h:355
Controller(uint8_t motorNo, uint8_t encoderNo, enum class encoderType encoderType, uint16_t CPR, double Kp, double Ki, double Kd, double target, bool direction, double capableDutyCycle, double current, bool logging=false)
Construct a new Controller object.
Definition Cubic.controller.cpp:9
const uint8_t encoderNo
エンコーダ番号
Definition Cubic.controller.h:120
void setKi(double Ki)
Iゲインを設定します。負の値は-1倍されます。
Definition Cubic.controller.h:367
double getTarget() const
目標値を返します。
Definition Cubic.controller.h:375
void setGains(double Kp, double Ki, double Kd)
PIDゲインを設定します。負の値は-1倍されます。
Definition Cubic.controller.h:359
double getDutyCycle() const
直前に計算したデューティ比を返します。
Definition Cubic.controller.h:383
void setKp(double Kp)
Pゲインを設定します。負の値は-1倍されます。
Definition Cubic.controller.h:363
double getDt() const
直前のループにおける経過時間dtを返します
Definition Cubic.controller.h:387
アブソリュートエンコーダを用いた、DCモータの位置制御を行うためのクラス
Definition Cubic.controller.h:322
Position_PID(uint8_t motorNo, uint8_t encoderNo, enum class encoderType encoderType, uint16_t CPR, double Kp, double Ki, double Kd, double target, bool direction, double capableDutyCycle=1.0, bool logging=false)
Construct a new Position_PID object.
Definition Cubic.controller.cpp:46
void setTarget(double target) override
制御量の目標値を設定します。
Definition Cubic.controller.cpp:111
double compute() override
duty比を計算します。各ループで一回呼び出してください。このduty比は、DUTY_SPI_MAXに対する比です。計算された値は、この関数内部で、DC_motor::put()されます。
Definition Cubic.controller.cpp:62
double encoderToAngle(int32_t encoder) override
エンコーダの値から角度を計算します。設定したCPR(Count Per Revolution)に依存します。
Definition Cubic.controller.h:395
インクリメンタルエンコーダを用いた、DCモータの速度制御を行うためのクラス
Definition Cubic.controller.h:274
Velocity_PID(uint8_t motorNo, uint8_t encoderNo, enum class encoderType encoderType, uint16_t CPR, double Kp, double Ki, double Kd, double target, bool direction, double capableDutyCycle=1.0, double p=1.0, bool logging=false)
Construct a new Velocity_PID object.
Definition Cubic.controller.cpp:14
void reset() override
制御器のリセット
Definition Cubic.controller.h:444
double compute() override
duty比を計算します。各ループで一回呼び出してください。このduty比は、DUTY_SPI_MAXに対する比です。計算された値は、この関数内部で、DC_motor::put()されます。
Definition Cubic.controller.cpp:23
double encoderToAngle(int32_t encoder) override
エンコーダの値から角度を計算します。設定したCPR(Count Per Revolution)に依存します。
Definition Cubic.controller.h:391
void setLPF(double p)
ローパスフィルタの係数pを設定します。
Definition Cubic.controller.h:424
Definition PID.h:13
double getDt() const
Get the Dt object.
Definition PID.h:153
void setKi(double Ki)
Set the Ki object.
Definition PID.h:169
void setKp(double Kp)
Set the Kp object.
Definition PID.h:165
void setTarget(double target)
目標を変更する。
Definition PID.h:177
void setKd(double Kd)
Set the Kd object.
Definition PID.h:173
double getTarget() const
目標を取得する。
Definition PID.h:181
void reset()
制御器のリセット
Definition PID.h:193
double getCurrent() const
現在値を取得する。
Definition PID.h:185
void setGains(double Kp, double Ki, double Kd)
ゲインを変更する。
Definition PID.h:159
double compute_PID(double current, bool logging=false)
PID制御を行う関数
Definition PID.cpp:13