문제

무선 및 webiopi를 통해 Raspberry 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");
    }

이것이 내가 지금 가지고 있는 방법이지만 여전히 작동하지 않습니다. (나는 완전히 멍청한 사람입니다 :-) ):

 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가 자체 '루프'를 사용하는지 확인하고 모터 GPIO의 상태와 거리를 확인하고 모터가 작동 중인지, 거리가 너무 짧은지 확인하기 위해 루프 코드를 추가했습니다.이제 자동차는 앞으로 버튼을 누르면 움직이고 버튼을 놓으면 멈추고, 앞으로 움직이고 거리가 30cm 미만이면 멈추게 됩니다.유일한 문제는 거리가 너무 짧고 전진 버튼을 너무 빨리 여러 번 누르면 이제 "gpio.output (echo, 1) _webiopi.gpio.invalidDipectionException을 얻는다는 것입니다.GPIO 채널이 OUTPUT" 오류가 아닙니다 :-( .

이제 코드는 다음과 같습니다.

 def go_forward(direction):
   motor_forward()

 def loop():
   if get_range() < 30 and GPIO.digitalRead(M1) == GPIO.HIGH:
     stop()
     print "stop"
   sleep(1)
도움이 되었습니까?

해결책

잠시 후에 여러분의 주요 문제에 답해 드리겠습니다. 하지만 먼저 여러분이 Python 초보자로서 하고 있는 일, 즉 여러분의 삶을 필요 이상으로 복잡하게 만드는 것에 대해 언급하고 싶습니다.

그럴 필요는 없어요 global 함수 시작 시에 있는 진술입니다.Python에서는 다음을 사용해야 합니다. global 원한다면 진술 쓰다 전역 변수에.당신이해야 할 모든 것이 있다면 읽다 변수를 지정하거나 함수를 호출하면 global 성명.변수 이름이든 함수 이름이든 함수에 사용된 모든 이름은 다음 순서로 검색됩니다.로컬, 둘러싸기, 글로벌, 내장."로컬"은 함수 내부에 정의된 이름을 의미합니다. direction 변하기 쉬운."Enclosing"은 다른 함수 안에 함수를 정의할 때 사용되는 규칙입니다.이는 많은 상황에서 유용하지만 약간 고급 주제이므로 지금은 걱정할 필요가 없습니다."전역"은 프로그램의 최상위 수준에서 정의된 이름(변수, 함수 또는 클래스)을 의미합니다. motor_stop 기능을 수행합니다.마지막으로 "내장"은 Python의 내장 이름을 의미합니다. str 또는 int 또는 file.

그래서 만약 당신이 그것을 생략했다면 global 명령문을 사용하면 Python은 이름을 검색합니다. motor_stop (및 기타 함수 이름)은 다음과 같습니다.

  1. 현지의: 거기에 motor_stop 이 함수에 정의되어 있나요?아니요.계속해서.
  2. 포함: 이 함수가 다른 함수 내에 정의되어 있습니까?아니요, 따라서 "포함" 규칙이 적용되지 않습니다.계속해서.
  3. 글로벌: 거기에 motor_stop 프로그램의 최상위 수준에서 정의됩니까?예.그것을 발견.
  4. (내장):이 규칙은 "전역" 규칙에 의해 이름이 발견되었기 때문에 전혀 확인되지 않습니다.

모든 기능은 프로그램의 최상위 수준에서 정의되므로 "전역" 규칙은 global 성명.이것은 당신의 삶을 좀 더 단순하게 만들 것입니다.

이제 주요 질문은 다음과 같습니다.코드가 영원히 반복되는 이유.그 이유는 테스트 조건이 귀하의 while 루프는 결코 거짓이 되지 않습니다.당신은 반복하고 있습니다 while direction == "fwd", 그리고 그 안의 코드는 while 루프는 결코 변경하지 않습니다 direction 변하기 쉬운.따라서 루프 끝에 도달할 때마다 다시 조건을 테스트하기 위해 돌아갑니다.그만큼 direction 변수에 여전히 문자열이 포함되어 있습니다. "fwd", 그리고 while 루프가 두 번째로 실행됩니다.그런 다음 direction 변수에 여전히 문자열이 포함되어 있습니다. "fwd", 그래서 세 번째로 실행됩니다.등등.

나가는 방법 중 하나 while 루프를 종료하려는 경우 루프를 설정하는 것입니다. direction 예를 들어 다른 것으로 변수화 "stop", 멈추고 싶을 때.(예: 전화를 걸고 난 후 motor_stop()).또 다른 방법은 return 해당 시점에서 함수를 종료하는 명령문입니다.하지만 내 제안은 break 대신, "이 시점에서 즉시 내가있는 루프를 종료한다"는 것을 의미합니다. 그것은 둘 다에서 작동합니다 while 루프와 for 루프이며 알아두면 매우 유용한 설명입니다.당신이 원하는 것 같습니다 while 전화할 때마다 종료하는 루프 motor_stop(), 그래서 당신이 넣을 장소가 두 군데 있습니다 break 성명:

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

제가 제안하고 싶은 몇 가지 다른 변경 사항이 있습니다.먼저 전화를 하세요. get_range() 루프에서는 세 번 호출해야 하지만 실제로는 한 번만 호출하면 됩니다.이미 그 결과를 dist 변수가 있는데 왜 그 변수를 사용하지 않는 걸까요?

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

둘째, 내부에는 길이 없습니다. while 루프 direction ~ 아니다 "fwd"가 되려면 최종 else 불필요하며 기능은 다음과 같이 될 수 있습니다.

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()

마지막으로 다음과 같은 함수 매개변수가 있습니다. arg, 이는 용도에 대해 아무 것도 알려주지 않는 이름입니다.즉시 다음과 같은 변수에 할당합니다. direction, 훨씬 더 좋은 이름입니다.그렇다면 애초에 그것을 매개변수 이름으로 사용하지 않는 이유는 무엇입니까?함수의 매개변수를 지정하는 규칙은 없습니다. ~ 해야 하다 "arg"라고 불립니다.원하는 대로 무엇이든 불릴 수 있습니다(다음과 같은 Python의 예약어 중 하나는 제외). break 또는 if).따라서 함수에 보다 의미 있는 매개변수 이름을 지정하면 훨씬 더 단순화됩니다.

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()

거기.이는 읽고 이해하기가 훨씬 쉬우며, 귀하가 겪고 있는 문제를 해결해야 합니다. while 자동차가 물체에 너무 가까워지면 루프가 종료되지 않습니다.

(내가 볼 수 있는 한 가지 가능한 문제는 자동차가 앞으로 운전하는 동안 "앞으로" 버튼을 놓았음에도 불구하고 while 루프가 종료되지 않을 수 있다는 것입니다. motor_forward() 그 문제를 해결하는 방법을 아는 코드.다음을 넣는 것만큼 간단할 수도 있습니다. break 이후 진술 motor_forward(), 이 경우에는 실제로 a가 필요하지 않습니다. while 루프를 전혀 반복하지 마세요. 하지만 어떻게 해야 하는지 알아야 합니다. motor_forward() 코드는 webiopi와 상호 작용하며 webiopi의 이벤트 처리 코드가 작동하는 방식을 보여줍니다.지금은 아는 바가 하나도 없기 때문에 아예 답을 주지 않으시는 것보다는, 혹시 답변이 불완전하더라도 지금 제가 답변할 수 있는 문제는 무엇인지 답변해드리도록 하겠습니다.)

마크 편집: 다음은 motor_forward 코드입니다.

 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 만 필요하지 않습니다

인쇄 arg

호출 서명의 콜 렌즈는 함수에 PARM을 보여주기 위해

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top