R2D2 – Automation mit Pico und Zero

Die UART Schnittstelle überträgt nun die Distanzmessungen, vorne und hinten vom Raspberry Pico zum Raspberry Zero 2.

Luke

Raspberry Pico:

import utime
from machine import Pin, UART, Timer

# Wichtig: nimmt man hier: uart = machine.UART(0, 115200)
# kann man nicht mehr per USB auf den Pico zugreifen.

uart = UART(1, 115200)

def ultra(trigger_pin, echo_pin):
    trigger = Pin(trigger_pin, Pin.OUT)
    echo = Pin(echo_pin, Pin.IN)
    trigger.low()
    utime.sleep_us(2)
    trigger.high()
    utime.sleep_us(5)
    trigger.low()

    while echo.value() == 0:
        signaloff = utime.ticks_us()

    while echo.value() == 1:
        signalon = utime.ticks_us()

    timepassed = signalon - signaloff
    distance = (timepassed * 0.0343) / 2
    return distance

def return_distance(t):
    distance1 = ultra(3, 2)
    distance2 = ultra(20, 21)
    uart.write(f"front,{distance1},rear,{distance2}\n")

# durch die Initialisierung kann der timer zur Laufzeit gestoppt werden mit timer.deinit()
timer = None
if __name__ == "__main__":
    timer = Timer(freq=5, callback=return_distance)

Merke: Verwende keine while True Schleife, sondern ein Timer Objekt. Damit bleibt die Konsole des Pico verfügbar.

Auf der Gegenstelle wird die Distanz empfangen.

Raspberry Zero 2:

import serial

from Sensors.sensor import Sensor

class UltraSonic(Sensor):

    def __init__(self):
        self._serial = serial.Serial ("/dev/ttyS0", 115200)

    def getPort(self):
        return self._serial

    def read_one(self):
        distance = {}
        ser = self.getPort()
        # Waiting Strings verwerfen
        ser.read_all()
        received_data = ser.readline()  #read serial port
        result = str(received_data.decode('utf-8')).split(",")
        distance[result[0]] = round(float(result[1]))
        distance[result[2]] = round(float(result[3]))
        return distance

Nach der Dekodierung des binären Inputs zu UTF-8 lässt sich die Distanz von “rear” und “front” in eine Struktur laden und verarbeiten.

Mit Ultraschall wird der Abstand vorne und hinten gemessen.

Damit sind die Voraussetzungen für das autonome Herumfahren gegeben. Die Klassenbibliothek habe ich bereits um die Klasse Automation erweitert:

from Automation.automation_events import AutomationEvents

# Automation Klasse
class Automation:
    def __init__(self, programs = None):
        self._eventController = AutomationEvents()
        self._sensors = {}
        self._programs = programs
        self.get_programs().set_event_controller(self.get_event_controller())
        self._car = None

    def set_car(self, car):
        self.get_programs().set_car(car)
        self._car = car

    def get_car(self):
        return self._car

    def get_event_controller(self):
        return self._eventController

    def add_sensor(self, sensor_name, sensor_object):
        self._sensors[sensor_name] = sensor_object

    def get_sensors(self):
        return self._sensors

    def get_programs(self):
        return self._programs

    def autoprogram(self, program_name):
        result = {}
        if self.get_programs():
            if program_name == "autoprogram_one":
                result = self.get_programs().program_one()
            if program_name == "autoprogram_stop":
                result = self.get_programs().program_stop()
        return result
            

und hier das Programm “autoprogram_one”: Es ist ganz einfach.

from Automation.automation_events import AutomationEvents


class AutomationPrograms:

    def __init__(self):
        self._car = None

    def set_car(self, car):
        self._car = car

    def get_car(self):
        return self._car

    def set_event_controller(self, event_controller: AutomationEvents):
        self._event_controller = event_controller

    def get_event_controller(self):
        return self._event_controller

    def get_sensors(self):
        return self.get_car().get_sensors()

    def program_one(self):
        result = {}
        sensors = self.get_sensors()
        eventcontroller = self._event_controller
        
        for sensor_name in sensors:
            sensor_result = sensors[sensor_name].read_one()
            result[sensor_name] = sensor_result
        
        event = eventcontroller.find_event("FORWARD", "MOVE")
        try:
            if result["UltraSonic"]["front"] >= 35:
                event = eventcontroller.find_event("FORWARD", "MOVE")
            elif result["UltraSonic"]["front"] < 35:
                event = eventcontroller.find_event("KOLLISIONFRONT", "OBSTACLE")
            elif result["UltraSonic"]["rear"] >= 35:
                event = eventcontroller.find_event("BACKWARD", "MOVE")
            elif result["UltraSonic"]["rear"] < 35:
                event = eventcontroller.find_event("KOLLISIONBACK", "OBSTACLE")
        except:
            pass

        result = event
        return result

Die Car Klasse besitzt nun eine Automation, die man während der Initialisierung konfiguriert:

import sys

sys.path.append("..")

import time

from Automation.automation import Automation
from Automation.automation_programs import AutomationPrograms
from car import Car
from Motor.bot_motor import BotMotorController
from Sensors.ultrasonic import UltraSonic

sensor_object = UltraSonic()
programs = AutomationPrograms()
selfDriving = Automation(programs)
selfDriving.add_sensor("UltraSonic", sensor_object)

motorcontroller = BotMotorController(default_speed=45, max_speed=100)
motorcontroller.add_motor("Motor1", 19, 13, 26, True, True, 50)
motorcontroller.add_motor("Motor2", 27, 17, 22, True, False, 50)

newcar = Car("Lukes Car", motorcontroller, None, selfDriving)

newcar.start()
newcar.drive("autoprogram_one")

Die Testfahrt per Automation:

YouTube player
Luke – auf erster Erkundungsfahrt

Nachtrag:

Um den Pico (oder den ESP32) mit dem JETSON Nano Board verwenden zu können, muss die UART Schnittstelle: /dev/ttyTHS1 angesprochen werden anstatt /dev/ttyS0.

Diese Seite verwendet Cookies, um die Nutzerfreundlichkeit zu verbessern. Mit der weiteren Verwendung stimmen Sie dem zu.

Datenschutzerklärung