2022年1月3日月曜日

MINDSTORMS Python まとめ

 MINDSTORMS Python 全部入り

今まで実装してきた非同期処理、ステートマシン、独自ライブラリについて全てまとめたソースについてGiHubへ公開しておきました。
非同期処理で距離センサーを使用しながら、ステートマシンで直進します。距離センサーが20cm以内に物体を検知した場合にイベントで通知するので停止するという簡単なプログラムです。
メイン処理、ステートマシンでの処理、非同期処理するプログラムと3つのプロジェクトに分けて作成してあります。
MINDSTORMSのモーターやセンサーオブジェクトはそれぞれでimportしても動くとは思いますが、接続ポートの変更などを考慮してメインで全て定義して引数で渡す様にしています。
独自ライブラリの方ではできるだけ汎用性が出る様にプログラムを作成する様に心がけるなどすると将来的にも役立つと思います。

クラスの継承問題

サンプルプログラムではclassを使ってオブジェクト思考風に設計していますが、ここで1つ問題が出てきます。オブジェクト指向で設計していくと継承を使いたくなりますがプロジェクトを分割した場合、親クラスが自分のプロジェクト内に定義されているか、importする必要があるということです。(クラスだけでなく関数でも同じです。)

サンプルではステートマシン用のプロジェクト内にStateクラスとGoStraightクラス(Stateクラスを継承)が定義されていますが、プログラムが大きるなくと各ステート毎にプロジェクトを分割したくなると思います。(私だとステート毎にプロジェクトに分割すると思います)
StateクラスとStateMachineクラス(やその他共通で使用するクラスや関数)を共通ライブラリ化して1つのプロジェクトとして各ステートではStateクラスなどをimportして使うというやり方です。
GoStraightクラスを別プロジェクトにした例が以下です。(Project3.pyとします)

import json

class CopyProject:
    def __init__(self):
        f = open('projects/.slots', 'r')
        data = f.read()
        f.close()
        self.slots = json.loads(data.replace('\'', '"'))

    def getID(self, no):
        return self.slots[no]['id']

    def copy(self, no_from, no_to, name):
        from_path = 'projects/{}/__init__.mpy'.format(self.slots[no_from]['id'])
        to_path = 'projects/{}/{}.mpy'.format(self.slots[no_to]['id'], name)
        f = open(from_path, 'rb')
        data = f.read()
        f.close()
        f = open(to_path, 'wb')
        f.write(data)
        f.close()

cp = CopyProject()
cp.copy(1, 3, 'lib1')
from .lib1 import State

# 直進
class GoStraight(State):
    def __init__(self, name: String, wheels):
        super().__init__(name)
        self.__wheels = wheels

    def entry(self):
        self.__wheels.start(0, -20)

    def exit(self):
        self.__wheels.stop()

if __file__.split('/')[3] == '__init__.mpy':
    print(__file__)

Stateのimportを行わないとプロジェクトをアップロードする時にStateが無いというエラーが出てアップロードすることが出来ません。またStateをimportするのはアップロードする時だけて良さそうですが(ライブラリとしてimportされる場合は、事前にStateをimportしておく)、GoStraightをimportする時もStateをimportしていないとエラーとなります。

CopyProjectクラスだけはimportして使うことが出来ないので、今回の例の様にStateクラスの提供する機能が殆どない様なケースではGoStraightクラスではStateクラスを継承せずに必要なメソッドは自力でコーディングしておく方がソースがスッキリする様です。

共通ライブラリ化の場合は参照関係を整理して助長性とのトレードオフを考える必要がありそうです。


0 件のコメント:

コメントを投稿

Edisonが故障した一件

 最近またEdisonで遊んでいます。 教育用のデバイスとしてよく出来ているなと思っている Edison ですが、現在3台を所有しています。 最近このうちの1台が調子が悪くなってしましました。具体的にはBeep用のデバイスが壊れたようです。購入時にチェックをしたつもりですが今回久...