Skip to content

Commit 44e1116

Browse files
authored
Merge pull request #3 from KatLab-MiyazakiUniv/ticket-KL25-20
#KL25-20 PID計算
2 parents 35b5e28 + dd2bb88 commit 44e1116

File tree

5 files changed

+511
-5
lines changed

5 files changed

+511
-5
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ set(PROJECT_TEST_DIR ${PROJECT_SOURCE_DIR}/tests)
3232
# 必要なインクルードディレクトリの設定 (適宜登録)
3333
set(INCLUDE_DIRS
3434
${PROJECT_MODULE_DIR}
35+
${PROJECT_MODULE_DIR}/calculators
3536
${PROJECT_MODULE_DIR}/API
3637
${PROJECT_TEST_DIR}
3738
${PROJECT_TEST_DIR}/dummy
@@ -41,6 +42,7 @@ set(INCLUDE_DIRS
4142
# ソースファイルの登録 (適宜登録)
4243
file(GLOB_RECURSE PROJECT_SOURCES
4344
"${PROJECT_MODULE_DIR}/*.cpp"
45+
"${PROJECT_MODULE_DIR}/calculators/*.cpp"
4446
"${PROJECT_TEST_DIR}/helpers/*.cpp"
4547
)
4648

Makefile.inc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ USE_RASPIKE_ART=1
22

33
mkfile_path := $(dir $(lastword $(MAKEFILE_LIST)))
44

5-
65
# Shellスクリプトで、moduleディレクトリ中のソースコード名をオブジェクトファイル名に変換している
76
SRCS := $(shell find ${mkfile_path}modules -name '*.cpp')
87
OBJS := $(notdir $(SRCS:.cpp=.o))
@@ -14,10 +13,10 @@ APPL_LIBS += -lm
1413

1514
APPL_DIRS += \
1615
$(mkfile_path)modules\
17-
$(mkfile_path)modules/API
18-
19-
16+
$(mkfile_path)modules/API\
17+
$(mkfile_path)modules/calculators
2018

2119
INCLUDES += \
2220
-I$(mkfile_path)modules\
23-
-I$(mkfile_path)modules/API
21+
-I$(mkfile_path)modules/API\
22+
-I$(mkfile_path)modules/calculators

modules/calculators/Pid.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/**
2+
* @file Pid.cpp
3+
* @brief PIDを計算するクラス
4+
* @author miyahara046
5+
*/
6+
7+
#include "Pid.h"
8+
9+
PidGain::PidGain(double _kp, double _ki, double _kd)
10+
// pidゲインが負の値にならないようにする
11+
: kp(_kp < 0 ? 0 : _kp), ki(_ki < 0 ? 0 : _ki), kd(_kd < 0 ? 0 : _kd)
12+
{
13+
}
14+
15+
Pid::Pid(double _kp, double _ki, double _kd, double _targetValue, double _maxIntegral,
16+
double _minIntegral)
17+
: pidGain(_kp, _ki, _kd),
18+
targetValue(_targetValue),
19+
maxIntegral(_maxIntegral),
20+
minIntegral(_minIntegral)
21+
{
22+
}
23+
24+
Pid::Pid(double _kp, double _ki, double _kd, double _targetValue)
25+
: Pid(_kp, _ki, _kd, _targetValue, 100.0, -100.0)
26+
{
27+
}
28+
29+
void Pid::setPidGain(double _kp, double _ki, double _kd)
30+
{
31+
// pidゲインが負の値にならないようにする
32+
pidGain.kp = _kp < 0 ? 0 : _kp;
33+
pidGain.ki = _ki < 0 ? 0 : _ki;
34+
pidGain.kd = _kd < 0 ? 0 : _kd;
35+
}
36+
37+
double Pid::calculatePid(double currentValue, double delta)
38+
{
39+
// 0除算を避けるために delta=0 の場合はデフォルト周期0.01とする
40+
if(delta == 0) delta = 0.01;
41+
42+
// 現在の目標値との偏差を求める
43+
double currentDeviation = targetValue - currentValue;
44+
// 積分の処理を行う
45+
integral += (currentDeviation + prevDeviation) * delta / 2.0;
46+
// 累積する積分値の大きさ制限
47+
if(integral > maxIntegral) {
48+
integral = maxIntegral;
49+
} else if(integral < minIntegral) {
50+
integral = minIntegral;
51+
}
52+
// 微分の処理を行う
53+
double currentDerivative = (currentDeviation - prevDeviation) / delta;
54+
/**
55+
* 微分項にローパスフィルタを適用
56+
* 偏差が大きい際に過大な変化量を一気に与えず
57+
* 滑らかな変化にし、機体の暴走を防ぐため
58+
*/
59+
filteredDerivative = alpha * currentDerivative + (1.0 - alpha) * filteredDerivative;
60+
61+
// 前回の偏差を更新する
62+
prevDeviation = currentDeviation;
63+
64+
// P制御の計算を行う
65+
double p = pidGain.kp * currentDeviation;
66+
// I制御の計算を行う
67+
double i = pidGain.ki * integral;
68+
// D制御の計算を行う
69+
double d = pidGain.kd * filteredDerivative;
70+
71+
// 操作量 = P制御 + I制御 + D制御
72+
return (p + i + d);
73+
}

modules/calculators/Pid.h

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/**
2+
* @file Pid.h
3+
* @brief PIDを計算するクラス
4+
* @author miyahara046
5+
*/
6+
7+
#ifndef PID_H
8+
#define PID_H
9+
10+
// PIDゲインを保持する構造体
11+
struct PidGain {
12+
public:
13+
double kp; // Pゲイン
14+
double ki; // Iゲイン
15+
double kd; // Dゲイン
16+
17+
/** コンストラクタ
18+
* @param _kp Pゲイン
19+
* @param _ki Iゲイン
20+
* @param _kd Dゲイン
21+
*/
22+
PidGain(double _kp, double _ki, double _kd);
23+
};
24+
25+
class Pid {
26+
public:
27+
/** コンストラクタ
28+
* @param _kp Pゲイン
29+
* @param _ki Iゲイン
30+
* @param _kd Dゲイン
31+
* @param _targetValue 目標値
32+
* @param _maxIntegral 累積積分値の最大値
33+
* @param _minIntegral 累積積分値の最小値
34+
*/
35+
Pid(double _kp, double _ki, double _kd, double _targetValue, double _maxIntegral,
36+
double _minIntegral);
37+
38+
/** 積分値制限を設定しない場合のコンストラクタ
39+
* @param _kp Pゲイン
40+
* @param _ki Iゲイン
41+
* @param _kd Dゲイン
42+
* @param _targetValue 目標値
43+
*/
44+
Pid(double _kp, double _ki, double _kd, double _targetValue);
45+
46+
/**
47+
* @brief PIDゲインを設定する
48+
* @param _kp Pゲイン
49+
* @param _ki Iゲイン
50+
* @param _kd Dゲイン
51+
*/
52+
void setPidGain(double _kp, double _ki, double _kd);
53+
54+
/**
55+
* @brief PIDを計算する
56+
* @param currentValue 現在値
57+
* @param delta 周期[ms](デフォルト値0.01[10ms]、省略可)
58+
* @return PIDの計算結果(操作量)
59+
*/
60+
double calculatePid(double currentValue, double delta = 0.01);
61+
62+
private:
63+
PidGain pidGain;
64+
double prevDeviation = 0.0; // 前回の偏差
65+
double integral = 0.0; // 偏差の累積
66+
double filteredDerivative = 0.0; // フィルタされた微分項を保持する変数
67+
double targetValue; // 目標値
68+
double maxIntegral = 100.0; // 累積積分値の最大値
69+
double minIntegral = -100.0; // 累積積分値の最小値
70+
static constexpr double alpha = 0.8; // ローパスフィルタの係数
71+
};
72+
73+
#endif // PID_H

0 commit comments

Comments
 (0)