1

私の大学がコンテストに参加しているロボットのコードを書いています。私は現在、反射率センサーを使用していくつかのホイールエンコーダーを構築しようとしています。ロボットが左右のエンコーダーの両方を同時に監視する必要があるので、これを達成するにはおそらくスレッドを使用する必要があることにしばらく前に気づきました。以下のコードは私がこれまでに持っているものです:

from __future__ import division
import threading
import time
from sr import *
R = Robot()

class Encoder(threading.Thread):
    def __init__(self, motor, pin, div=16):
        self.motor = motor
        self.pin = pin
        self.div = div
        self.count = 0
        threading.Thread.__init__(self)

    def run(self):
        while True: 
            wait_for(R.io[0].input[self.pin].query.d)
            self.count += 1

    def rotations(self, angle, start_speed=50):
        seg = 360/self.div
        startcount = self.count
        current_dist = angle #Distance away from target
        R.motors[self.motor].target = start_speed
        while current_dist > 360:
            newcount = self.count - startcount
            current_dist = angle - newcount*seg
            R.motors[self.motor].target = 50
        while abs(current_dist) > seg/2:  
            newcount = self.count - startcount
            current_dist = angle - newcount*seg
            current_speed = start_speed * current_dist / 360
            if current_speed < 5:
                R.motors[self.motor].target = 5
            else:
                R.motors[self.motor].target = current_speed
        R.motors[self.motor].target = 0

WheelLeft = Encoder(0,0)
WheelLeft.start()
WheelRight = Encoder(1,3)
WheelRight.start()

WheelRight.rotations(720)
WheelLeft.rotations(720)

srモジュールは、コンテストを運営しているサウサンプトン大学によって提供されています。これにより、ロボットのハードウェアと対話できます。

現在、作成されるスレッドにより、2つの反射率センサーを別々に監視できるようになります。このコードのビット:R.io[0].input[self.pin].query.d反射率センサーからの値が変更されたかどうかを判断します。「回転」方式では、ホイールがすでに何度回転したかを常にチェックし、最後に到達するまで速度を落とすことにより、ホイールを特定の角度で回転させます。プログラムを実行すると両方のホイールが回転し始め、2回転したときに減速して停止します。しかし現在、プログラムを実行すると、一方のホイールが回転を開始し、減速して停止し、次にもう一方のホイールが続きます。'run'メソッドのように、'rotations'メソッドがスレッドで実行されていないように見えます。スレッドで実行されるのは、「ru​​n」メソッドの下のコードだけですか、

それが役に立ったら、私はこのチュートリアルに従っています:http ://www.devshed.com/c/a/Python/Basic-Threading-in-Python/1/

また、なぜスレッドを。だけで開始できるのか知りたいEncoder(0,0).start()です。クラスを使用してオブジェクトを作成する必要がないのはなぜですか(たとえばThread = Encoder(0,0).start()、新しいスレッドを作成する場合)。

私が使用した用語が完全ではない場合は申し訳ありません。おそらく、私はスレッド化とプログラミング全般にまったく慣れていないことがわかるでしょう。

4

3 に答える 3

1

Encoder(0,0).start()スレッドを開始するためのメソッドの呼び出しです。次に、このメソッドはrun、メソッドを使用しない実装を呼び出しますrotations。そうしたい場合は、のwhileループで呼び出す必要がありますrun

そのThread = Encoder(0,0).start()呼び出しから取得した値(None)を保存しますが、それを取得するには、とにかく最初に新しいスレッドを開始する必要があります。

于 2013-03-21T22:07:40.840 に答える
0

runメソッド実行のスレッドです。

そのスレッドで何か他のことをしたい場合は、から呼び出す必要がありますEncoder.run()

ああ、そしてオブジェクトを作成しEncoder(0,0).start() ます。そのオブジェクトをローカル変数にバインドしなかったからといって、それが存在しないことを意味するわけではありません。それが存在しなかった場合、そのstartメソッドを呼び出すことはできませんでした。

ただし、ローカル変数が存続することなく、その存続期間については非常に注意する必要があります。

于 2013-03-21T22:14:57.477 に答える
0

SRのクラスから拡張して、 :Pollで使用できるようにすることができます。wait_for

import poll

class Encoder(poll.Poll):
    def __init__(self, motor, pin, div=16):
        self.motor = motor
        self.pin = pin
        self.div = div
        self.count = 0
        self.target_reached = False

        # kick off a thread to count the encoder ticks
        self.counter_thread = threading.Thread(target=self._update_count)
        self.counter_thread.start()

    def _update_count(self):
        while True: 
            wait_for(R.io[0].input[self.pin].query.d)
            self.count += 1

    def rotations(self, angle, start_speed=50):
        if not self.target_reached:
            raise Exception("Last motion still in progress!")

        self.target_reached = False

        # kick off a thread to control the speed
        self.angle_thread = threading.Thread(
            target=self._update_speeds,
            args=(angle, start_speed)
        )
        self.angle_thread.start()

    def _update_speeds(self, angle, start_speed):
        # control the motor speed as before
        ...

        # let things know we're done
        self.target_reached = True

    # implement poll methods
    def eval(self):
        return (self.target_reached, None)

これにより、次のことが可能になります。

wheelLeft = Encoder(0,0)
wheelRight = Encoder(1,3)

wheelRight.rotations(720)
wheelLeft.rotations(720)

wait_for(wheelRight & wheelLeft)

エンコーダー自体はスレッドではないことに注意してください。これは「hasa」関係であり、「isa」関係ではありません。

于 2013-12-17T10:19:15.620 に答える