分散センサー群のシミュレーション用の Python プラットフォームを作成しています。これは、エンド ユーザーが SensorNode の動作 (通信、ログ記録など) で構成されるカスタム ノードを作成し、多数の異なるセンサーを実装できるという考え方です。
以下の例は、概念を簡単に示しています。
#prewritten
class Sensor(object):
def __init__(self):
print "Hello from Sensor"
#...
#prewritten
class PositionSensor(Sensor):
def __init__(self):
print "Hello from Position"
Sensor.__init__(self)
#...
#prewritten
class BearingSensor(Sensor):
def __init__(self):
print "Hello from Bearing"
Sensor.__init__(self)
#...
#prewritten
class SensorNode(object):
def __init__(self):
print "Hello from SensorNode"
#...
#USER WRITTEN
class MySensorNode(SensorNode,BearingSensor,PositionSensor):
def CustomMethod(self):
LogData={'Position':position(), 'Bearing':bearing()} #position() from PositionSensor, bearing() from BearingSensor
Log(LogData) #Log() from SensorNode
新しい編集:
まず、私が達成しようとしていることの概要: モバイル センサー ネットワークに特に焦点を当てて、群知能アルゴリズムをシミュレートするシミュレーターを作成しています。これらのネットワークは、環境の複雑な感覚マップを構築するために個々のセンサー データを通信する多数の小型ロボットで構成されています。
このプロジェクトの根底にある目標は、センサーに抽象化されたインターフェイスを提供するシミュレーション プラットフォームを開発して、組み込み Linux を実行するロボット群に同じユーザー実装機能を直接移植できるようにすることです。ロボットの実装が目標であるため、ソフトウェア ノードが同じように動作し、物理ノードが持つ情報にのみアクセスできるように設計する必要があります。
シミュレーション エンジンの一部として、さまざまな種類のセンサーとさまざまな種類のセンサー ノードをモデル化する一連のクラスを提供します。ユーザーがノード上に存在するセンサーと、実装されているセンサーノードのタイプ (モバイル、固定位置) を定義するだけで済むように、この複雑さをすべてユーザーから切り離したいと考えています。
私の最初の考えは、すべてのセンサーが関連する値を返す read() メソッドを提供するだろうということでしたが、質問への応答を読んで、おそらくもっとわかりやすいメソッド名が有益であることがわかりました (.distance(), .position( )、.bearing() など)。
私は当初、より技術的なユーザーが必要に応じて既存のクラスの 1 つを簡単に拡張して新しいセンサーを作成できるように、(共通の祖先を持つ) センサーに個別のクラスを使用したいと考えていました。例えば:
Sensor
|
DistanceSensor(designed for 360 degree scan range)
| | |
IR Sensor Ultrasonic SickLaser
(narrow) (wider) (very wide)
私が最初に多重継承を考えていた理由は (継承の IS-A 関係を半壊させますが)、シミュレーション システムの背後にある基本原理によるものでした。説明させてください:
ユーザーが実装した MySensorNode は、環境内のその位置に直接アクセスできません (ロボットと同様に、アクセスはセンサー インターフェイスを介して間接的に行われます)。同様に、センサーは自分がどこにいるかを認識できません。ただし、センサーの戻り値はすべて環境内の位置と方向に依存するため、この直接的な知識の欠如は問題を引き起こします (正しい値を返すにはシミュレートする必要があります)。
SensorNode は、シミュレーション ライブラリ内に実装されたクラスとして、pygame 環境内で MySensorNode を描画する責任があります。したがって、環境内のセンサー ノードの位置と向きに直接アクセスできる唯一のクラスです。
SensorNode は環境内での並進と回転も担当しますが、この並進と回転はモーター作動の副作用です。
つまり、ロボットはワールド内の位置を直接変更することはできず、モーターに電力を供給することしかできず、ワールド内での動きはモーターと環境との相互作用の副作用であるということです。シミュレーション内でこれを正確にモデル化する必要があります。
したがって、移動するために、ユーザーが実装した機能は次を使用できます。
motors(50,50)
この呼び出しは、副作用として、ワールド内のノードの位置を変更します。
SensorNode が構成を使用して実装されている場合、SensorNode.motors(...) はインスタンス変数 (位置など) を直接変更することも、MySensorNode.draw() を SensorNode.draw() に解決することもできません。継承を使用して実装されます。
センサーに関しては、このような問題に対する構成の利点は明らかです。MySensorNode は多数のセンサーで構成されています。
ただし、私が見ている問題は、センサーが世界内の位置と向きにアクセスする必要があることです。合成を使用すると、次のような呼び出しになります。
>>> PosSensor.position((123,456))
(123,456)
次に、初期化時にセンサーに self を渡すことができると考えてください。
PosSensor = PositionSensor(self)
じゃあ後で
PosSensor.position()
ただし、この PosSensor.position() はインスタンスにローカルな情報にアクセスする必要があります ( init () 中に self として渡されます)。では、情報にローカルにアクセスできるのに、なぜ PosSensor を呼び出すのでしょうか? また、カプセル化と情報隠蔽の境界を越えて、構成されているオブジェクトにインスタンスを渡すことは、まったく正しくないようです (Python は情報隠蔽のアイデアをサポートするためにあまり機能しませんが)。
多重継承を使用してソリューションを実装した場合、これらの問題は解消されます。
class MySensorNode(SensorNode,PositionSensor,BearingSensor):
def Think():
while bearing()>0:
# bearing() is provided by BearingSensor and in the simulator
# will simply access local variables provided by SensorNode
# to return the bearing. In robotic implementation, the
# bearing() method will instead access C routines to read
# the actual bearing from a compass sensor
motors(100,-100)
# spin on the spot, will as a side-effect alter the return
# value of bearing()
(Ox,Oy)=position() #provided by PositionSensor
while True:
(Cx,Cy)=position()
if Cx>=Ox+100:
break
else:
motors(100,100)
#full speed ahead!will alter the return value of position()
この編集でいくつかのことが明確になったことを願っています。質問がある場合は、喜んでそれらを明確にしてください
昔の事:
MySensorNode 型のオブジェクトを構築する場合、スーパークラスのすべてのコンストラクターを呼び出す必要があります。各スーパークラスからコンストラクターを呼び出す MySensorNode のカスタム コンストラクターを記述しなければならないことでユーザーを複雑にしたくありません。理想的には、私がしたいことは次のとおりです。
mSN = MySensorNode()
# at this point, the __init__() method is searched for
# and SensorNode.__init__() is called given the order
# of inheritance in MySensorNode.__mro__
# Somehow, I would also like to call all the other constructors
# that were not executed (ie BearingSensor and PositionSensor)
洞察や一般的なコメントをいただければ幸いです、乾杯:)
古い編集:次のようなことをしています:
#prewritten
class SensorNode(object):
def __init__(self):
print "Hello from SensorNode"
for clss in type(self).__mro__:
if clss!=SensorNode and clss!=type(self):
clss.__init__(self)
self は MySensorNode のインスタンスであるため、これは機能します。ただし、このソリューションは面倒です。