Python、WebiopiとRaspberry Pi
-
20-12-2019 - |
質問
ワイヤレスとWebiopiを介して私のラズベリーPIカーを制御しようとしています。基本機能は問題になります。 - [FWD]をクリックして[車]をクリックし、車が前方に移動します。ボタンをリリースすると停止します。
私は今、私が走るときに車がそれの前にあるときに車が止まるべきであるように超音波距離センサーを統合したいと考えています。私がFWDボタンをクリックすると、何かが範囲内にあるときに車が停止して停止するのか、車は停止しますが、ボタンを解放したときには停止します。私のwhileループはどういうわけかループ(貼られている)で、Webiopiからリリースボタン関数を読んでいません。
誰かが助けてくれることができます - 今何日の間それを行ってきました、そして、私が間違っているのかわからない:-(
これは私のPythonスクリプトからのループです:
def go_forward(arg):
global motor_stop, motor_forward, motor_backward, get_range
print "Testing"
print mousefwd()
while (arg) == "fwd":
print (arg)
direction = (arg)
dist = get_range()
print "Distance %.1f " % get_range()
if direction == "fwd" and get_range() < 30:
motor_stop()
return
else:
motor_forward()
.
そしてここで私のWebiopi関数呼び出しからのコードは次のとおりです。
function go_forward() {
var args = "fwd"
webiopi().callMacro("go_forward", args);
}
function stop1() {
var args = "stop"
webiopi().callMacro("go_forward", args);
webiopi().callMacro("stop");
}
.
これは私が今持っているのですが、それでも働いていない(私は総Noobです:-)):
def go_forward(arg):
global motor_stop, motor_forward, motor_backward, get_range
print "Testing"
direction = arg
while direction == "fwd":
print arg
dist = get_range()
print "Distance %.1f " % get_range()
if get_range() < 30:
motor_stop()
elif direction == "fwd":
motor_forward()
else:
motor_stop()
.
は少し前進します。 Webipiが独自の 'Loop'を使用していて、モーターGPIOのステータスと距離とモーターが実行されているかどうかを確認し、距離が短すぎる場合は、ループコードを追加します。車両を押してから移動して停止したときに停止し、前方に移動するときに停止すると、30cmが停止します。距離が短すぎると、前方ボタンを複数回押しすぎると、「gpio.output(echo、1)を得ることが問題だけです。 _webiopi.gpio.InvalidDirectionException:GPIOチャネルは出力ではありません "エラー:。
コードは今こそこんな感じされています:
def go_forward(direction):
motor_forward()
def loop():
if get_range() < 30 and GPIO.digitalRead(M1) == GPIO.HIGH:
stop()
print "stop"
sleep(1)
. 解決
私は1分であなたの主な問題に答えますが、最初に私はあなたがPythonの初心者としてやっている何かを言及したいです。それはそれが必要以上に複雑になっているよりもっと複雑になっています。
あなたの関数の始めにあなたが持っているglobal
ステートメントの必要はありません。 Pythonでは、 write をグローバル変数にしたい場合にのみ、global
ステートメントを使用する必要があります。 read 変数、または関数を呼び出すことだけである場合は、global
ステートメントを必要としません。関数で使用されている名前は、変数の名前または関数の名前であろうと、次の順序で検索されます。ローカル、囲み、グローバル、組み込み。 "Local"とは、direction
変数のように、関数内で定義されている名前を意味します。 "囲む"は、他の関数内で関数を定義するときに使用されるルールです。これは多くの状況で役立ちますが、高度なトピックの少しであり、今のところ心配する必要はありません。 "Global"とは、他のプログラムの最上位レベルで定義されている名前(変数、または関数、またはクラス)を意味します。そして最後に、「組み込み」とは、Pythonの組み込み名、motor_stop
またはstr
またはint
などを意味します。
SO file
ステートメントを省略した場合、Pythonは次のようにglobal
(および他の関数名)を検索します。
- local:この関数で定義された
motor_stop
はありますか?いいえ。 - 囲む:他の関数内で定義されているこの関数は?いいえ、「囲む」規則は適用されません。移動してください。
- global:プログラムの最上位レベルで定義された
motor_stop
はありますか?はい。見つけました。 - (組み込み):名前は "Global"ルールによって見つかったため、このルールはまったくチェックされません。
すべての機能はプログラムの最上位レベルで定義されているため、 "Global"規則はそれらをmotor_stop
ステートメントを必要としません。これはあなたの人生を少し単純にするはずです。
今あなたの主な質問のために:あなたのコードが永遠にループしている理由。これは、global
ループが誤って偽になることはないためです。 while
をループしているため、while direction == "fwd"
ループ内のコードはwhile
変数を変更しません。したがって、ループの終わりに達するたびに、その状態を再度テストします。 direction
変数には、文字列direction
が含まれているので、whileループは2回目に実行されます。その後、"fwd"
変数には文字列direction
が含まれているため、3回目が実行されます。など、そしてそれほど続く。
"fwd"
ループを終了する1つの方法は、停止したいときに、while
変数をdirection
のように設定することです。 (例えば、"stop"
を呼び出した後)。もう1つの方法は、その時点で関数を終了するためにmotor_stop()
ステートメントを使用することです。しかし、私の提案は、代わりにreturn
文を使用することです。これは、「この時点で、すぐにループを終了している」という意味です。それはbreak
ループとwhile
ループの両方で動作します、そして、知っておくべき非常に便利な声明です。 for
を呼び出すときは、while
ループを終了するようにするようになりますので、motor_stop()
ステートメントを入力する2つの場所があります。
def go_forward(arg):
print "Testing"
direction = arg
while direction == "fwd":
print arg
dist = get_range()
print "Distance %.1f " % get_range()
if get_range() < 30:
motor_stop()
break
elif direction == "fwd":
motor_forward()
# No break statement here, so the while loop continues
else:
motor_stop()
break
.
他にはいくつかの変更があります。まず、Loopでbreak
を3回呼び出しますが、本当にそれを1回呼び出すだけです。結果をget_range()
変数にすでに割り当てたので、その変数を使用しないのですか?
def go_forward(arg):
print "Testing"
direction = arg
while direction == "fwd":
print arg
dist = get_range()
print "Distance %.1f " % dist
if dist < 30:
motor_stop()
break
elif direction == "fwd":
motor_forward()
# No break statement here, so the while loop continues
else:
motor_stop()
break
.
と2番目に、dist
not のためのwhile
ループの内側には "FWD"であるため、最後のdirection
は不要で、機能になることができます。
def go_forward(arg):
print "Testing"
direction = arg
while direction == "fwd":
print arg
dist = get_range()
print "Distance %.1f " % dist
if dist < 30:
motor_stop()
break
else:
motor_forward()
.
最後に、else
という名前の関数パラメータがあります。これは、それが使用されているものについては何も指示しない名前です。すぐにそれをarg
という変数に割り当てます。これははるかに良い名前です。それで、それを最初にパラメータ名として使用しないのはなぜですか?関数のパラメータを「arg」と呼ばれる必要があるという規則はありません。彼らはあなたが好きなものと呼ぶことができます(direction
やbreak
などのPythonの予約語の1つを除く)。それでは、機能にもっと意味のあるパラメータ名を与えましょう、そしてそれはそれ以上それを単純化するでしょう:
def go_forward(direction):
print "Testing"
while direction == "fwd":
print direction
dist = get_range()
print "Distance %.1f " % dist
if dist < 30:
motor_stop()
break
else:
motor_forward()
.
。それは読みやすく理解しやすく、それはあなたが車がオブジェクトに近づくときに出ていないあなたのif
ループを見ていた問題を解決するべきです。
(まだ1つの可能な問題があるのは私がwhileループが終了しているかもしれないということです。
while
コードを見なければならないでしょう。motor_forward()
の後にbreak
ステートメントを入れるのと同じくらい簡単かもしれません。その場合、一般にmotor_forward()
ループを必要としませんが、while
コードがWebIOPIとどのように対話するかを知る必要があります。コードが機能します。私が今知っているのではないので、私の答えが不完全であっても、私の答えが不完全なのではなく、私が今答えることができる問題に答えるつもりです。)
マークごとに編集:これはMotor_Forward Code:
def motor_forward():
GPIO.output(M1, GPIO.HIGH)
GPIO.output(M2, GPIO.LOW)
string = "echo 0=130 > /dev/servoblaster"
os.system(string)
. 他のヒント
これを試してください - あなたは常に範囲で止まるが、方向を止めることができます
if get_range() < 30:
motor_stop()
elif direction == "fwd":
motor_forward()
else:
motor_stop()
.
BTWあなたがそれを参照したときに(arg)argを必要としない
arg
を印刷する呼び出しの署名の中の理論は、そのPARMが関数
に表示するためのものです。