UdonLibrary 1.0.0
機械システム研究部 C++ ライブラリ
読み取り中…
検索中…
一致する文字列を見つけられません
Trapezoidal.hpp
[詳解]
1#pragma once
2
3#ifdef ARDUINO
4
5# include "Stopwatch.hpp"
6
7/*
8 * 長さと旋回角の台形制御をして、ベジェ曲線の経路クラスと合わせて使用することを目的とした。
9 */
10
11namespace Udon
12{
13
14 class Trapezoidal
15 {
16 private:
17 double upTime, maxPowerTime, downTime;
18 double acc, maxSpeed, limitSpeed;
19 bool nextState, dir;
20 double nowPos, nowSpeed;
21 double oldTarget;
22 double startSpeed, endSpeed;
23 double nextNowPos, nextNowSpeed;
24 Stopwatch Stopwatch;
25 bool reCalculation;
26
27 public:
32 Trapezoidal(double acc, double maxSpeed, double nowPos)
33 : upTime()
34 , maxPowerTime()
35 , downTime()
36 , acc(acc * 0.001) // mm/ms^2 == (m/s^2)*0.001
37 , maxSpeed(maxSpeed) // mm/ms == m/s
38 , limitSpeed()
39 , nextState(true)
40 , dir()
41 , nowPos(nowPos)
42 , nowSpeed()
43 , oldTarget(nowPos)
44 , startSpeed()
45 , endSpeed()
46 , nextNowPos(nowPos)
47 , nextNowSpeed()
48 , Stopwatch()
49 , reCalculation()
50 {
51 }
52 // 入力はs単位で計算時はms単位にする
53
57 double operator()(const double target, bool isStop = false, const double endS = 0.0)
58 {
59 // X=Vot+(1/2)*at^2;
60 // V=a*t +Vo;
61 // V^2-Vo^2 =2as;
62 if (isStop)
63 {
64 // 非常停止時
65 Stopwatch.stop();
66 reCalculation = true;
67 nextNowSpeed = 0;
68 }
69 if (oldTarget != target || reCalculation)
70 { // 目標座標が変わったときは計算しなおす
71 Stopwatch.start(); // タイマーを開始する←何度呼び出しても一度だけ実行される
72 nextState = false;
73 oldTarget = target;
74 reCalculation = false;
75
76 nowPos = nextNowPos; // 途中までの経路情報の保持
77 startSpeed = nextNowSpeed; // 最初のスピードは前の経路情報をほじ
78 endSpeed = endS * 0.001;
79 const double distance = target - nowPos; // 距離を求める
80 dir = (distance > 0.0 ? 1 : 0); // 増減の方向を決める
81
82 endSpeed = abs(endSpeed) * (dir ? 1 : -1);
83 maxSpeed = abs(maxSpeed) * (dir ? 1 : -1);
84 acc = abs(acc) * (dir ? 1 : -1);
85
86 upTime = (maxSpeed - startSpeed) / acc; // 最高速度までの加速にかかる時間 ms
87 downTime = (maxSpeed - endSpeed) / acc; // 減速にかかる時間 ms
88 if (upTime < 0.0) // 今と逆に進みたいときに減速分を増加させるため
89 downTime -= upTime;
90
91 const double L1 = startSpeed * upTime + acc * sq(upTime) * 0.5; // 加速時における移動距離 mm
92 const double L3 = endSpeed * downTime + acc * sq(downTime) * 0.5; // 減速時における移動距離 mm
93 if (abs(L1) + abs(L3) > abs(distance))
94 { // 台形ができなくなり、三角形になるときの制御
95 limitSpeed = 2.00 * acc * distance * 0.5 + sq(startSpeed);
96 limitSpeed = sqrt(limitSpeed) * (dir ? 1 : -1); // 必ず+になる
97 if (abs(limitSpeed) < abs(startSpeed))
98 limitSpeed = startSpeed;
99 upTime = (limitSpeed - startSpeed) / acc;
100 downTime = (limitSpeed - endSpeed) / acc;
101 maxPowerTime = 0.0; // limitSpeed,upTimeがマイナスになることもある
102 }
103 else
104 { // 台形が作れる場合の制御
105 maxPowerTime = (distance - L1 - L3) / maxSpeed; // 最高速度での移動時間 ms
106 limitSpeed = maxSpeed;
107 }
108 // 目標値がずれることがあった↓
109 // 目標値を変えた際の速度によって確定で行き過ぎる場合があり、
110 // その場合に逆に進んでいないから目標値がずれてる
111 }
112
113 double ut = constrain(Stopwatch.getTime(), 0.00, upTime);
114 double mt = constrain(Stopwatch.getTime() - upTime, 0.00, maxPowerTime);
115 double dt = constrain(Stopwatch.getTime() - (upTime + maxPowerTime), 0.00, downTime);
116 double targets = acc * sq(ut) * 0.50 + startSpeed * ut + maxSpeed * mt + (-acc * sq(dt) * 0.50) + limitSpeed * dt;
117
118 if (!nextState)
119 { // 経路を巡行してないときだけ更新する
120 nextNowSpeed = startSpeed + acc * ut + -acc * dt;
121 nextNowPos = targets + nowPos;
122 }
123 if (upTime + downTime + maxPowerTime <= Stopwatch.getTime())
124 {
125 nowPos = nextNowPos; // 一つの経路を巡行し終えた時の座標の情報を保持
126 Stopwatch.reset();
127 Stopwatch.stop();
128 nextState = true;
129 oldTarget = nowPos; // 行き過ぎた場合にもう一度計算するようにする
130 }
131 return nextNowPos;
132 }
133
136 double getTime() const
137 {
138 return Stopwatch.getTime();
139 }
142 bool status() const
143 {
144 return nextState;
145 }
147 void setTarget()
148 {
149 reCalculation = true;
150 }
153 double getNowPos() const
154 {
155 return nowPos;
156 }
159 double getTargetPos() const
160 {
161 return nextNowPos;
162 }
165 double getNowSpeed() const
166 {
167 return nowSpeed * 1000;
168 }
169 void setAcc(double acc)
170 {
171 this->acc = acc * 0.001;
172 }
173 void posReset()
174 {
175 nextNowPos = 0;
176 nowPos = 0;
177 }
178 };
179} // namespace Udon
180#endif
Definition Bit.hpp:12