見出し画像

LITE版第二次リファクタリングが完了

Meridian計画。
懸案だったLITE版のリファクタリングが完了しました。
すでにあるコードをヘッダファイルごとに切り分けるという単純作業ですが、これがなかなか大変です。
まとめて作業してエラーが出ると原因を見つけるのが大変になるので、ちょっと変更しては書き込んで動作確認、ということの繰り返しで進めるのが理想なのですが、ESP32は書き込みが遅いため作業のテンポがどうしても悪くなりがちです。書き込みを怠って作業を続けた後でエラーが出て、作業の巻き戻しにかなり時間がかかる場面もありました。まさに急がば回れです。

今回のリファクタリングではなるべく一般的なコードの作法に則るように行いました。当記事は我流のプロトタイパーの方にも参考になるかもしれません。他にも気を付けるべきルールがいろいろとありそうなので、ぜひ教えていただければと思います。

さて、LITE版のバージョンはこれで1.1.1。
機能は以前と全く変わりませんが、中身は見違えるようにバージョンアップしました。以下、アップデートのポイントを挙げていきます。

セマンティックバージョニング1.1.1

バージョンの命名にもルールがあり、セマンティックバージョニングという規則に従っています。

書式は、
Major. Minor. Patch
という順になります。

Majorは重大な変更や後方互換性がない変更の場合に増加。
Minorは新機能が追加されつつも、後方互換性が保たれている場合に増加。
Patchは後方互換性が保たれた小さな修正や改善で増加します。

今回はMeridim配列のデータ自体は後方互換性を保っていながら、モジュール化という新機能が加わったと言えるため、1.0.1から1.1.0へのバージョンアップとし、さらに内部的な変数名の刷新を行ったことで1.1.1としています。
これはすでにモジュール化まで完了しつつ変数名のアップデートが行われていないTWIN版を1.1.0としていることにも整合させています。

フローチャートのアップデート

drawioを使ってmain.cppのフローチャートを作成しました。
チャートのおかげでリファクタリング自体の見通しもだいぶ良くなりました。処理番号もコード内に記入しておいたので、少なくとも自分にとっては今後の増築がしやすくなっていると思います。

drowioの図で頭もスッキリ

コーディング規約はLLVM準拠

Google C++ Style GuideやC++ Core Guidelinesなどがメジャーなようですが、自動変換をしてみて見た目が一番しっくり来たLLVMのコーディング規約に準拠することとしました。
前回の記事にも書いたようにもちろんローカルルールを含むのですが、基本をLLVMに準拠するとしたことで、迷いを少なくできます。
さらに「.clang-format」にそのルールを書いておくことで、ローカルルールを含んでいてもVSCODEで自動整形できるようになります。
ついでに命名規則などもそのファイルにコメントで書いておきました。
以下はそのローカルルールの内容です。

BasedOnStyle: LLVM
ColumnLimit: 100
AlignTrailingComments: true
AlignConsecutiveMacros: true

# コーディングスタイルはおおむねLLVMガイドラインに準拠する.

# <Meridian 命名規則ローカルルール>
# 1. 変数名はスネークケースとする 例)a_meridim
# 2. 関数名はスネークケースとする(ROS風)
# 3. クラス名・構造体名・列挙型名はパスカルケースとする
# 4. 関数宣言時の引数は a_ をつける 例)a_meridim
# 5. 関数内の補助変数は _tmp をつける 例)int count_tmp
# 6. モジュールとなるファイル名は mrd_ をつける 例)mrd_wifi.h

# <ドキュメンテーションコメント>
# 関数などの解説には下記のように///を使用する。 
#
# /// @brief 解説.
# /// @param 引数.
# /// @return 戻り値.
#
# /** */はコードの改造時にブロックコメントアウトとして使用できるよう,
# ドキュメンテーションコメントとしては使用しないこと.

# <主な用語>
# Meridian  : デバイスやソフトを中間プロトコルでつなぐリアルタイムシステム
# Meridim   : Meridianのコアとなる配列
# Meridim90 : 基準となる簡易的な固定配列(180バイト)

# <主な定数の命名ルール>
# MODE_    動作モードのconfig
# EEPROM_  EEPROM関連
# CHECK_   起動時の動作チェック関連
# MONITOR_ シリアルモニタリング
# MOUNT_   ハードウェアのマウント設定
# PAD_     ジョイパッド・リモコン関連
# SERVO_   サーボの通信設定関連
# MCMD_    Meridimのマスターコマンド
# PIN_     ピンアサイン
# IDR_     L系統のサーボパラメータ
# IDL_     R系統のサーボパラメータ
# MRD_   Meridim90の配列キー(例外ありconfig.h参照)

ヘッダファイル分割によるモジュール化

これまでのMeridian LITE版はconfig.h, keys.h, main.cpp, main.h という4つだけのファイル(最初期にはmain.cpp一つだけ)で構成していましたが、今回のリファクタリングではmain.cppから機能ごとに関数をまとめ、各ヘッダファイルに切り出しました。
ファイル数が増えるので見た目は複雑になりますが、メインコードがスッキリし、main.cpp本体への改造も最小限にできるので、増改築がしやすくなったと思います。追加機能の作成時にモジュールとなるヘッダファイルだけ更新すればよしとなるのでメンテも便利になるはずです。
LITE版とTWIN版でこれらの関数モジュールを共有できる場面も多くなりそうで、今後の開発がグッとやりやすくなるはずです。
たとえば有線LANに対応させる場合には、mrd_wifi.hの代わりにmrd_Ethernet.hなどのファイルを命名して追加開発すればOKです。
各社サーボへの対応も、だいぶ楽になりそうです。

Meridian_LITE_for_ESP32
│
├── lib
│   └── IcsClass_V210  // KONDOサーボのライブラリ
├── platformio.ini
└── src
    ├── .clang-format  // VSCODEでのコードフォーマット設定ファイル
    ├── config.h       // Meridianの主なconfig設定
    ├── keys.h         // wifiのSSIDやパスワード
    ├── main.cpp       // メインプログラム
    ├── main.h         // メインプログラムのヘッダファイル
    │
    ├── mrd_eeprom.h   // EEPROM関連
    ├── mrd_move.h     // モーション設定
    ├── mrd_msg.h      // メッセージ関連
    ├── mrd_pad.h      // リモコンパッド関連
    ├── mrd_sd.h       // SDメモリ関連
    ├── mrd_servo.h    // サーボ処理
    ├── mrd_wifi.h     // WiFi関連
    ├── mrd_wire0.h    // I2C関連
    └── mrd_module     // モジュールディレクトリ
        ├── mv_firstIK.h    // 簡易IK関連(未定義)
        ├── mv_motionplay.h // モーション再生(未定義)
        ├── sv_dxl2.h       // ダイナミクセル制御(未定義)
        ├── sv_ftbrx.h      // 双葉サーボ制御(未定義)
        ├── sv_ftc.h        // Feetechサーボ制御(未定義)
        └── sv_ics.h        // KONDOサーボ制御

関数を引数と戻り値のあるものに修正

これまでの実験段階では動けばそれでよい!という勢いで作成しており、void定義の関数がたくさんあったり、さらに関数内で外部のグローバル変数を直接使いまくったりと、かなり雑なコーディングをしていました。
そのままだと関数を転用しにくかったり、変数の動きを追いきれなくなるという問題があります。
そこで関数は極力returnで結果を返すようにし、グローバル関数も引数として渡すようにしました。
これで、関数を転用する際の機能の再現性が高くなります。
(細かな事情でグローバル変数を関数内部で使うものがまだ少し残っているのでご注意ください。)

変数の管理性を大幅向上

サーボ用の変数やフラグなど、同じカテゴリでパラメーターが多いものは、main.h内の構造体にまとめました。こうすることで変数の管理がしやすくなり、変数を追加する際にも迷わずにすみます。
また、変数についてのドキュメントコメントについても表記ルールを統一しました。VS CODE上で変数をマウスオーバーした時に、解説コメントが出るようになりました。
さらに列挙型を導入することで、デバイスタイプの設定などを番号での選択から名称での選択に変更できました。ドキュメントコメントもつけたので、列挙型の中身をすぐに確認できます。

オリジナルライブラリの使用を控える

meridian.hというオリジナルのライブラリを登録していますが、開発する側からするとライブラリのコードの中身が分かりずらかったり、ライブラリをその場で改造できないという課題もありました。
今回はmeridian.hの使用は最小限とし、モジュール全体を見渡しながら、コードの見通しが良くなるよう、使用頻度が高くてシンプルな関数を改めてライブラリにまとめていこうと思います。

配列のコマンド一覧や関数のインデックスも更新

Meridm90のインデックスリストコマンドのリストも久々に更新しました。同じディレクトリにエクセル版もアップしているので、こちらをベースにまた増築していければと思います。

gs2dにも準拠予定

@reomatsumuraさんが開発されたgs2dという汎用シリアルバス RC サーボドライバ・ライブラリにも対応、準拠予定です。まだ未導入ですが、各社サーボの導入が便利になったり、Meridianで使用する用に新規作成したサーボライブラリをgs2dライブラリに還元できる可能性もあるかもしれないと考えています。

今後の予定

前回のTWIN版のリファクタリングの積み残しだった改善点を今回はかなり導入しました。
次の作業として、まずはTWINを今回のリファクタリングに合わせたものにして、バージョンをそろえていきます。(地味なのでつらそう)
その後でUnity版のリファクタリングやストップモーション用のプロトコルの整備など、楽しい作業を進めていきます。

前回の記事:

目次:


この記事が気に入ったらサポートをしてみませんか?