僕の考えた最強のパラメータ格納法

パラメータ格納

マイクロマウスではいろいろなパラメータ,調整項目があります.きれいに走るためには,たくさんのパラメータを真心込めて調整してあげる必要があります.ほんとうにしんどい.

さて,乱雑なコードを書いているといろんなよくない問題が発生します.
例えば,

  • 同じパラメータが複数ヶ所で定義されている
  • 使われていないパラメータが乱立している
  • 変更したいパラメータがどこに書かれているか見つからない

……などなど.ちなみに全て実話です

というわけで,パラメータの格納方法はこだわったほうがいいというのがこの記事で言いたいことです.

先駆者

某先輩がポインタまみれのスラロームパラメータ保存を紹介していました.全容を把握するのには苦労しますが,すべてのパラメータを#defineするよりも良い方法だと思います.
C言語を頑張りたい人はこの記事を読んで,ポインタとは何者なのか理解しちゃいましょう!

ぼくのかんがえた(以下略

では,僕の考えた最強のパラメータ格納法をででんと紹介します.

あ,予め言っておきますがC++11とSTLを使いまくっているので,用法用量にはお気をつけください.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
namespace slalomparams{
enum class RunType : uint8_t {
SLALOM90SML_RIGHT,
SLALOM90SML_LEFT,
SLALOM90_RIGHT,
SLALOM90_LEFT,
SLALOM180_RIGHT,
SLALOM180_LEFT,
SLALOM45IN_RIGHT,
SLALOM45IN_LEFT,
SLALOM45OUT_RIGHT,
SLALOM45OUT_LEFT,
SLALOM135IN_RIGHT,
SLALOM135IN_LEFT,
SLALOM135OUT_RIGHT,
SLALOM135OUT_LEFT,
SLALOM90OBL_RIGHT,
SLALOM90OBL_LEFT,
TRAPACCEL,
PIVOTTURN,
};

struct pack{
float d_before;
float d_after;
float acc_rad;
float deg;
float const_deg;
float in_vel;
float out_vel;
float min_vel;
float acc_lin;
};
typedef struct pack pack_t;
}

array< map<float,pack_t>* , 16> slalomparams::getParams(){
static map<float, pack_t> SLALOM90SML_RIGHT = {
// { vel, {d_bef, d_aft, a_rad, deg, cnsdeg, in_vel, out_vel, min_vel, acc_lin}},
{0.25, {0.010, 0.012, 9000,95.5, 30, 0.25, 0.25, 0.25, 0.0}},
};
static map<float, pack_t> SLALOM90SML_LEFT = {
// { vel, {d_bef, d_aft, a_rad, deg, cnsdeg, in_vel, out_vel, min_vel, acc_lin}},
{0.25, {0.010, 0.012, 9000,95.5, 30, 0.25, 0.25, 0.25, 0.0}},
};
static map<float, pack_t> SLALOM90_RIGHT = {};
static map<float, pack_t> SLALOM90_LEFT = {};
static map<float, pack_t> SLALOM180_RIGHT = {};
static map<float, pack_t> SLALOM180_LEFT = {};
static map<float, pack_t> SLALOM45IN_RIGHT = {};
static map<float, pack_t> SLALOM45IN_LEFT = {};
static map<float, pack_t> SLALOM45OUT_RIGHT = {};
static map<float, pack_t> SLALOM45OUT_LEFT = {};
static map<float, pack_t> SLALOM135IN_RIGHT = {};
static map<float, pack_t> SLALOM135IN_LEFT = {};
static map<float, pack_t> SLALOM135OUT_RIGHT = {};
static map<float, pack_t> SLALOM135OUT_LEFT = {};
static map<float, pack_t> SLALOM90OBL_RIGHT = {};
static map<float, pack_t> SLALOM90OBL_LEFT = {};

static array< map<float,pack_t>* , 16> params = {
&SLALOM90SML_RIGHT,
&SLALOM90SML_LEFT,
&SLALOM90_RIGHT,
&SLALOM90_LEFT,
&SLALOM180_RIGHT,
&SLALOM180_LEFT,
&SLALOM45IN_RIGHT,
&SLALOM45IN_LEFT,
&SLALOM45OUT_RIGHT,
&SLALOM45OUT_LEFT,
&SLALOM135IN_RIGHT,
&SLALOM135IN_LEFT,
&SLALOM135OUT_RIGHT,
&SLALOM135OUT_LEFT,
&SLALOM90OBL_RIGHT,
&SLALOM90OBL_LEFT,
};

return params;
}

struct pack がスラロームの1パラメータを格納した構造体です.
スラロームには,代表的なターンが16種類あるので,
1種類のスラロームパラメータをまとめたもの(A) へのポインタを,サイズ16の配列(B) にしています
(A)map<float, pack_t>で,(B)array< map<float, pack_t>*, 16>です.

(A)にstd::mapを使うことで,パラメータの存在確認を可能にしました.
スラロームのターン速を引数に取ることで,欲しいパラメータを参照することができます.

具体的には,次のようなコードでターンパラメータを取得・参照できます.

1
2
3
4
5
6
using namespace slalomparams;
auto it = getParams().at(static_cast<uint16_t>(RunType::SLALOM90SML_RIGHT))->find(0.25f);
if(it == getParams().at(static_cast<uint16_t>(RunType::SLALOM90SML_RIGHT))->end()) printf("Undefined parameter");

it->second.deg; //95.5
it->second.d_before; //0.01

ちなみに,諸事情あってconstにはしていませんが,問題なくconstをつけられると思います.