etrobocon2019 feat.KatLab  ece30a9a007fff7d3ad48592c0d09a74643377bb
Navigator.cpp
[詳解]
1 
8 #include "Navigator.h"
9 
10 Navigator::Navigator(Controller& controller_, double Kp_, double Ki_, double Kd_)
11  : distance(), controller(controller_), pidForSpeed(Kp_, Ki_, Kd_)
12 {
13 }
14 
15 void Navigator::setPidGain(double Kp, double Ki, double Kd)
16 {
17  pidForSpeed.setPidGain(Kp, Ki, Kd);
18 }
19 
20 void Navigator::move(double specifiedDistance, int pwm, const double pGain)
21 {
22  int leftAngle = controller.getLeftMotorCount();
23  int rightAngle = controller.getRightMotorCount();
24  double goalDistance = specifiedDistance + distance.getDistance(leftAngle, rightAngle);
25 
26  // 左車輪の回転量 - 右車輪の回転量
27  // 左車輪の方が多く回転していれば、alphaは正となり右車輪にPWM + alphaの操作量が加えられる
28  Pid pid(0, pGain);
29 
30  if(specifiedDistance < 0) {
31  while(hasArrived(goalDistance, false)) {
32  double alpha = pid.control(controller.getLeftMotorCount() - controller.getRightMotorCount());
33  setPwmValue(-std::abs(pwm), -alpha);
34  controller.tslpTsk(4);
35  }
36  } else {
37  while(hasArrived(goalDistance, true)) {
38  double alpha = pid.control(controller.getLeftMotorCount() - controller.getRightMotorCount());
39  setPwmValue(std::abs(pwm), -alpha);
40  controller.tslpTsk(4);
41  }
42  }
43 
44  controller.stopMotor();
45 }
46 
47 void Navigator::moveAtSpecifiedSpeed(double specifiedDistance, int specifiedSpeed)
48 {
49  int leftAngle = controller.getLeftMotorCount();
50  int rightAngle = controller.getRightMotorCount();
51  double goalDistance = specifiedDistance + distance.getDistance(leftAngle, rightAngle);
52 
53  SpeedControl speedControl(controller, specifiedSpeed, pidForSpeed.Kp, pidForSpeed.Ki,
54  pidForSpeed.Kd);
55 
56  if(specifiedDistance < 0) {
57  while(hasArrived(goalDistance, false)) {
58  double pwm = speedControl.calculateSpeed(specifiedSpeed, pidForSpeed.Kp, pidForSpeed.Ki,
59  pidForSpeed.Kd);
60  setPwmValue(static_cast<int>(-std::abs(pwm)));
61  controller.tslpTsk(4);
62  }
63  } else {
64  while(hasArrived(goalDistance, true)) {
65  double pwm = speedControl.calculateSpeed(specifiedSpeed, pidForSpeed.Kp, pidForSpeed.Ki,
66  pidForSpeed.Kd);
67  setPwmValue(static_cast<int>(std::abs(pwm)));
68  controller.tslpTsk(4);
69  }
70  }
71  controller.stopMotor();
72 }
73 
74 void Navigator::moveToSpecifiedColor(Color specifiedColor, int pwm)
75 {
76  int r = 0;
77  int g = 0;
78  int b = 0;
79 
80  // カラーセンサからrgb値を取得
81  controller.getRawColor(r, g, b);
82  // rgb値をhsv値に変換
83  controller.convertHsv(r, g, b);
84 
85  // 特定の色まで移動する
86  while(controller.hsvToColor(controller.getHsv()) != specifiedColor) {
87  setPwmValue(pwm);
88  // カラーセンサからrgb値を取得
89  controller.getRawColor(r, g, b);
90  // rgb値をhsv値に変換
91  controller.convertHsv(r, g, b);
92  controller.tslpTsk(4);
93  }
94  controller.stopMotor();
95 }
96 
97 void Navigator::spin(double angle, bool clockwise, int pwm)
98 {
99  // angleの絶対値を取る
100  angle = std::abs(angle);
101  Rotation rotation;
102 
103  controller.resetMotorCount();
104 
105  while(rotation.calculate(controller.getLeftMotorCount(), controller.getRightMotorCount())
106  < angle) {
107  controller.setLeftMotorPwm(clockwise ? pwm : -pwm);
108  controller.setRightMotorPwm(clockwise ? -pwm : pwm);
109  controller.tslpTsk(4);
110  }
111 
112  controller.stopMotor();
113 }
114 
115 bool Navigator::hasArrived(double goalDistance, bool isForward)
116 {
117  int leftAngle = controller.getLeftMotorCount();
118  int rightAngle = controller.getRightMotorCount();
119 
120  // スタート地点からみた現在の距離
121  int currentDistance = distance.getDistance(leftAngle, rightAngle);
122 
123  if(isForward) {
124  return currentDistance <= goalDistance;
125  } else {
126  return currentDistance >= goalDistance;
127  }
128 }
129 
130 void Navigator::setPwmValue(int pwm, double alpha)
131 {
132  controller.setRightMotorPwm(pwm + alpha);
133  controller.setLeftMotorPwm(pwm - alpha);
134 }
int getRightMotorCount()
Definition: Controller.cpp:188
void stopMotor()
Definition: Controller.cpp:272
double calculateSpeed(int targetSpeed, double Kp, double Ki, double Kd)
double Kp
Definition: Pid.h:11
double Kd
Definition: Pid.h:13
double Ki
Definition: Pid.h:12
void spin(double angle, bool clockwise=true, int pwm=10)
走行体を回頭させる(yawing)
Definition: Navigator.cpp:97
double calculate(const int leftAngle, const int rightAngle)
自転したときの角度を求める
Definition: Rotation.cpp:10
void setPidGain(double Kp_, double Ki_, double Kd_)
Definition: Pid.cpp:15
void setLeftMotorPwm(const int pwm)
Definition: Controller.cpp:203
int getLeftMotorCount()
Definition: Controller.cpp:183
Navigator(Controller &controller_, double Kp_=0.60, double Ki_=0.0, double Kd_=0.0)
Navigatorクラスのコンストラクタ
Definition: Navigator.cpp:10
Color hsvToColor(const HsvStatus &status)
Definition: Controller.cpp:86
void moveToSpecifiedColor(Color specifiedColor, int pwm=30)
Definition: Navigator.cpp:74
void convertHsv(int &r, int &g, int &b)
Definition: Controller.cpp:213
void setRightMotorPwm(const int pwm)
Definition: Controller.cpp:208
double control(double value, double delta=0.004)
Definition: Pid.cpp:28
void resetMotorCount()
Definition: Controller.cpp:266
static void tslpTsk(int time)
Definition: Controller.cpp:163
Definition: Pid.h:18
void moveAtSpecifiedSpeed(double specifiedDistance, int specifiedSpeed)
specifiedDistanceとSpeedControl.calculateSpeedから戻ってきたPWMをmoveに渡す
Definition: Navigator.cpp:47
void move(double specifiedDistance, int pwm=30, const double pGain=0.0)
specifiedDistanceの値でbackwardかforwardを呼び出す。
Definition: Navigator.cpp:20
double getDistance(int leftAngle, int rightAngle)
左右の平均走行距離を計算して戻り値として返す
Definition: Distance.cpp:15
void getRawColor(int &r, int &g, int &b)
Definition: Controller.cpp:78
void setPidGain(double Kp, double Ki, double Kd)
SpeedControl用のPidゲインのセッター
Definition: Navigator.cpp:15
HsvStatus getHsv() const
Definition: Controller.cpp:261
Color
Definition: Controller.h:32
直進と後進できるクラス