[PYTHON] Fabriquez une voiture robotique à conduite automatique avec Raspberry Pi3 B + et capteur de distance à ultrasons HC-SR04

introduction

Les éléments qui composent un véhicule autonome dans le monde réel sont l'estimation de la position du véhicule, la reconnaissance d'objets, le jugement d'action et le contrôle de la carrosserie du véhicule. Il est possible de mettre en œuvre l'ensemble de ces quatre éléments sur la base d'un contrôleur radio, mais il n'est pas facile d'estimer facilement la position du propre véhicule, et cette fois le but est de rouler à basse vitesse, il n'y a donc presque pas besoin de contrôle de la carrosserie du véhicule. Par conséquent, cette fois, je voudrais reconnaître l'objet en face avec le capteur de distance à ultrasons et réaliser facilement le jugement d'action pour l'éviter avec la voiture robot de conduite automatique basée sur le contrôleur radio.

environnement

Configuration globale de la voiture robot

Un signal PWM est envoyé de la tarte à la râpe à un contrôleur radio disponible dans le commerce pour contrôler l'accélérateur et la direction. Les trois capteurs de distance à ultrasons à l'avant sont utilisés pour reconnaître l'objet devant et juger du comportement en tournant la direction vers la gauche et la droite.

Pièces utilisées

** - Radicon: Tamiya 1/10 XB Series No.199 NSX (TT-02 Chassis) ** Tout est OK pour le corps principal, mais je veux toujours attacher le corps et adapter parfaitement divers matériels, donc je recommande un plus grand. Aussi, comme je l'expliquerai plus tard, cette fois je voulais rouler à basse vitesse, donc je pense qu'il était plus facile de contrôler la vitesse s'il ne s'agissait pas d'un système 7.2V.

** - Batterie du corps: pack personnalisé Tamiya 7.2V ** Il était normal d'aligner la tension de 7,2V du corps principal avec un régulateur linéaire et de la partager avec l'alimentation du Raspai, mais comme il était plus facile d'utiliser une batterie mobile pour l'alimentation du côté Raspai, cette fois l'alimentation du côté Raspai et le corps principal du Radicon sont indépendants J'étais autorisé à le faire.

** - Contrôleur de vitesse: contrôleur de vitesse PWM mini moteur à courant continu HiLetgo 5A 3V-35V ** C'est celui qui m'a le plus dérangé. Le moteur est contrôlé par un PWM de 7,2V, mais avec la méthode via le contrôleur cette fois, il semble que le rapport cyclique seul coupe à un certain rapport côté basse vitesse, donc je l'ai utilisé car il n'est pas possible d'obtenir une vitesse lente. De plus, comme il est redressé dans ce circuit, la rotation inverse ne se produit pas. Cela semble possible si vous en utilisez deux et que vous correspondez à la fois aux côtés positifs et négatifs, mais cette fois, il ne s'agit que d'une rotation avant.

** - Ordinateur monocarte: Raspberry Pi3 B + ** Il n'y a pas de précautions particulières. Il peut être utilisé tel quel. OS ver.

** - Batterie pour Raspeye: Batterie mobile Poweradd Ombar ijuice 3350mAh ** Tout type est bon marché et OK. Plus la capacité est grande, mieux c'est, mais j'ai choisi cette taille en tenant compte de la disposition.

** - Commutateur pour Raspeye: Ventilateur audio USB Type A ** Pour l'interrupteur qui active la tarte à la râpe. Lorsqu'il est activé, il entrera en état de veille.

** - Module de télécommande infrarouge: IR HX1838 ** Il est utilisé comme déclencheur pour démarrer la conduite en mode veille.

** - Capteur de distance à ultrasons: HC-SR04 + angle de montage acrylique ** C'est un capteur pour reconnaître les obstacles devant, à gauche et à droite.

** - Gabarit de fixation dur: plaque de réparation plate plaque droite MOLATE 96 * 19mm épaisseur 2.6mm ** La chose la plus difficile dans la fabrication de cette voiture robotique est de savoir comment disposer le matériel. J'ai attaché cette plaque en la plaçant entre les vis qui étaient à l'origine attachées au corps principal, ou en faisant des trous de vis avec une perceuse.

Implémentation matérielle

** - Câblage ** Pour la configuration générale, je me suis référé à ce site créé à partir du même type de contrôleur radio. Le câblage global final est montré dans la dernière figure.

**-Capteur à ultrasons ** L'utilisation de base des ondes ultrasonores est [ce site](http://make.bcde.jp/raspberry-pi/%e8%b6%85%e9%9f%b3%e6%b3%a2%e8% b7% 9d% e9% 9b% a2% e3% 82% bb% e3% 83% b3% e3% 82% b5hc-sr04% e3% 82% 92% e4% bd% bf% e3% 81% 86 /) Je l'ai utilisé comme référence. Les deux 5V et 3,3V sont utilisés pour utiliser 3 capteurs à ultrasons. Il est précisé que lors de l'utilisation d'une sortie 5V, il est nécessaire de descendre à 3,3V en utilisant une résistance, mais elle est utilisée directement telle quelle (5V peut être utilisée telle quelle sans aucun problème). J'ai vu un article disant, mais il était possible d'opérer pour le moment). De plus, quand je pensais avoir exactement les trois mêmes choses, on a découvert après coup qu'une seule était différente.

** - Télécommande infrarouge ** J'ai utilisé la télécommande infrarouge en me référant à ce site pour déclencher le mouvement de la voiture robot. Je n'ai pas eu le temps de passer ici, j'ai donc décidé de démarrer l'opération en appuyant sur n'importe quel bouton de la télécommande. Voir le code source ci-dessous pour plus de détails. La configuration générale du câblage matériel est illustrée dans la figure ci-dessous.

Configuration du Raspberry Pi

** - Paramètres réseau pour Raspberry Pi et PC ** Les paramètres nécessaires côté Raspeye sont la connexion à Internet et le téléchargement du logiciel nécessaire, et la configuration du serveur pour la connexion SSH. Bien sûr, le développement se fait dans un environnement où le serveur Raspai et le PC client peuvent utiliser le Wi-fi, mais lorsque le débogage est nécessaire dans un endroit où il n'y a pas d'environnement Wif-fi large pour le test de fonctionnement, Rasppie Une connexion ad hoc est nécessaire pour connecter le PC directement sans fil. Pour une connexion ad hoc, j'ai fait référence à ce site. ** - Paramètres de démarrage du Raspberry Pi ** Ajoutez la description suivante à /etc/rc.local pour que python3 exécute le programme /home/pi/nsx.py lorsque l'alimentation du contrôleur radio et de la tarte à la râpe est activée et que la tarte à la râpe démarre telle quelle. Veuillez noter que vous devez exécuter sudo dans votre environnement, vous devez donc passer le mot de passe (hogehoge dans ce cas) et le chemin complet.

:/etc/rc.local

echo "hogehoge" | sudo -u pi /user/bin/python3 /home/pi/nsx.py

Implémentation logicielle

** - Commande servo par ServoBraster ** J'ai utilisé Servo Blaster pour envoyer des valeurs de commande au contrôleur de vitesse et au servo de direction en utilisant des signaux PWM. En fonction du rapport cyclique du signal PWM, 150 est transmis au centre du neutre et une valeur de 100 à 200 est transmise pour régler l'ouverture. Comme cette valeur diffère selon le servo, il est nécessaire de déterminer la valeur à utiliser pour le contrôle lors de sa mise en œuvre. De plus, pour une raison quelconque, la valeur à la limite d'environ 150 n'a pas reçu de commande détaillée, et il y avait une zone morte entre 140 et 150 et entre 160 et 150, il y a donc une limite à la marche à basse vitesse en raison de l'ouverture de l'accélérateur. Par conséquent, nous utilisons un contrôleur de vitesse supplémentaire HiLetgo pour réduire la valeur actuelle.

** - Mesure de la distance à un objet avec un capteur de distance à ultrasons ** Il semble que la précision de la distance maximale soit d'environ plusieurs centimètres, mais à titre de mise en garde, si la réflexion des ondes ultrasonores ne peut pas être mesurée correctement, la mesure ne sera pas complétée indéfiniment et vous ne pourrez pas sortir de la boucle While, nous avons donc introduit une minuterie d'abandon. Lorsque Abort est effectué, la valeur mesurée la dernière fois est utilisée telle quelle. J'ai essayé diverses méthodes telles que prendre la valeur moyenne de plusieurs étapes, mais la précision de la valeur a été compromise car la méthode simple donne le fonctionnement le plus stable.

** - Commutateur de démarrage avec télécommande infrarouge ** J'ai utilisé lilc pour la transmission infrarouge et la réception de Raspai. La procédure d'installation, etc. est comme indiqué dans ce site auquel j'ai fait référence, mais les notes sont la description du fichier de configuration suivant. Spécifiez la broche GPIO en définissant dtoverlay comme gpio-ir et gpio_pin. Ici, 20 broches GPIO (= broche n ° 38 de la carte) sont utilisées.

:/boot/config.txt

# Uncomment this to enable the lirc-rpi module
#dtoverlay=lirc-rpi
#dtparam=gpio_in_pin=20
#dtparam=gpio_in_pull=up
dtoverlay=gpio-ir,gpio_pin=20
dtoverlay=gpio-irtx,gpio_pin=20

Sur la base de ce qui précède, le code source complet est le suivant.

:~/nsx.py

import subprocess as sp #Exécutez Servo Blaster avec sudo
import os
import sys
from time import sleep
import time 
import RPi.GPIO as GPIO #Pour Raspeye GPIO

#Définition de la valeur pour l'exécution
dirServo = "PiBits/ServoBlaster/user"
dirHome = "/home/pi"
passwd = ("hogehoge").encode() #Mot de passe pour exécuter sudo

#Paramètres du capteur de distance à ultrasons
trigCenter = 19
echoCenter = 18
trigLeft = 15
echoLeft = 16
trigRight = 7
echoRight = 8

#Exécution (initialisation) de Servo Blaster
def resetSystem(dirServo, passwd, dirHome):
    os.chdir(dirHome)
    os.chdir(dirServo)
    sp.run(("sudo", "./servod"), input=passwd)
    os.chdir(dirHome)
    print("Reset System")

#Neutraliser la direction et l'accélérateur (valeur de commande du moteur) en même temps
def setNeutral():
    stNeutral = "echo 1=150 > /dev/servoblaster"
    accNeutral = "echo 2=150 > /dev/servoblaster"    
    os.system(stNeutral)
    os.system(accNeutral)
    print("Set Neutral")

#Neutralisation de l'unité de direction
def setStNeutral():
    stNeutral = "echo 1=150 > /dev/servoblaster"
    os.system(stNeutral)
    print("Set Steer Neutral")

#Neutralisation de l'accélérateur seul
def setAccNeutral():
    accNeutral = "echo 2=150 > /dev/servoblaster"    
    os.system(accNeutral)
    #print("Set Accel Neutral")

#Valeur de commande maximale de l'accélérateur avant
def setFwdMax():
    fwdMax = "echo 2=100 > /dev/servoblaster"
    os.system(fwdMax)
    #print("Set fwdMax")

#Direction gauche Valeur de commande max.
def setLeftMax():
    leftMax = "echo 1=100 > /dev/servoblaster"
    os.system(leftMax)
    print("Set leftMax")

#Direction gauche Valeur de commande minimale (non utilisée cette fois)
def setLeftMin():
    leftMin = "echo 1=140 > /dev/servoblaster"
    os.system(leftMin)
    print("Set leftMin")

#Direction droite Valeur de commande max.
def setRightMax():
    rightMax = "echo 1=200 > /dev/servoblaster"
    os.system(rightMax)
    print("Set rightMax")

#Direction droite Valeur de commande min.
def setRightMin():
    rightMin = "echo 1=160 > /dev/servoblaster"
    os.system(rightMin)
    print("Set rightMin")

#Mesure de distance avec capteur de distance à ultrasons
def getDistance(TRIG, ECHO, abortTime):
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(TRIG, GPIO.OUT)
    GPIO.setup(ECHO, GPIO.IN)
    GPIO.output(TRIG, GPIO.LOW)
    time.sleep(0.01)

    GPIO.output(TRIG, True)
    time.sleep(0.00001)
    GPIO.output(TRIG, False)
    
    startTime = time.time()
    while GPIO.input(ECHO) == 0:
        signaloff = time.time()
        
        if ((signaloff - startTime) > abortTime):
            distance = -1
            return distance

    while GPIO.input(ECHO) == 1:
        signalon = time.time()

    timepassed = signalon - signaloff
    distance = timepassed * 17000
    
    return distance
    
    GPIO.cleanup()

#Réception de la télécommande infrarouge
def getRemoteSignal(flagState):
    boardNo = 38
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(boardNo, GPIO.IN)
  
    try: 
        if (GPIO.LOW  ==  GPIO.input(boardNo)):
            
            if (flagState == False):
                flagState = True
                print("Switch ON !!!!!!!!")

            elif (flagState == True):
                flagState = False
                print("Switch OFF !!!!!!!!")

            time.sleep(0.5)

    except:
        GPIO.cleanup()
    
    return flagState

#Commande d'accélérateur (commande simple avant et arrêt par mesure de la distance avant uniquement)
def getAccControl(currDist, setDist):

    flagStop = 0
    
    if (currDist < setDist) and (currDist > -1):
        
        setNeutral()
        flagStop = 1

    else:
        setFwdMax()
    
    return flagStop

#Commande de direction (commande simple par mesure de distance uniquement)
def getStControl(currDistRight, setDistRight, currDistLeft, setDistLeft, flagStop):
    statusRight = (currDistRight < setDistRight) and (currDistRight > -1)
    statusLeft =  (currDistLeft < setDistLeft) and (currDistLeft > -1)

    if (flagStop == 1):

        setStNeutral()

    elif (statusRight and statusLeft):

        setStNeutral()
    
    elif (statusRight):

        setLeftMin()

    elif (statusLeft):

        setRightMin()

    else:
        setStNeutral()

#Éviter les valeurs d'erreur du capteur de distance à ultrasons
def getTakeOverValue(distLeft, distRight):

    global prevDistLeft
    global prevDistRight

    if (distLeft == -1):
        distLeft = prevDistLeft

    prevDistLeft = distLeft

    if (distRight == -1):
        distRight = prevDistRight

    prevDistRight = distRight

    return (distLeft, distRight)


def main():

    #Initialisation du drapeau d'état de réception de la télécommande infrarouge
    global flagState
    flagState = False
    
    #Initialisation de la valeur précédente de la distance entre les objets gauche et droit
    global prevDistRight
    global prevDistLeft
    prevDistRight = 0
    prevDistLeft = 0

    #Valeur d'étalonnage du capteur de distance à ultrasons
    centerThreshold = 30 #L'avant est court pour s'arrêter
    rightThreshold = 70 #Seul le capteur droit a un type différent (lot ??), donc les valeurs gauche et droite sont différentes.
    leftThreshold = 60

    #Mettre en veille et régler les paramètres sur neutre
    resetSystem(dirServo, passwd, dirHome) 
    setNeutral()
    
    while True:
        
        #Vérifiez l'état de réception de la télécommande infrarouge (au début de l'opération)
        flagState = getRemoteSignal(flagState)
        
        if (flagState == True):        

            #Mesure de distance avec tous les capteurs de distance à ultrasons
            distCenter = getDistance(trigCenter, echoCenter, 0.1)
            distLeft = getDistance(trigLeft, echoLeft, 0.1)
            distRight = getDistance(trigRight, echoRight, 0.3)
           
            #Génération de valeur alternative lorsque le capteur de distance à ultrasons renvoie une erreur
            distLeft, distRight = getTakeOverValue(distLeft, distRight)
            
            #Arrêter la génération de la valeur de commande en fonction de la distance par rapport à l'objet devant
            flagStop = getAccControl(distCenter, centerThreshold)

            #Génération de valeur de commande de direction basée sur la distance aux objets gauche et droit
            getStControl(distRight, rightThreshold, distLeft, leftThreshold, flagStop)
            
            #Vérifiez l'état de réception de la télécommande infrarouge
            flagState = getRemoteSignal(flagState)
            
        else:
            setNeutral()

if __name__ == "__main__":
    main()

À la fin

Pourquoi avez-vous utilisé ce contrôleur radio? Je l'ai utilisé comme une voiture robot porte-oreillers à anneaux qui transporte des bagues lors de mariages. Probablement le premier au monde.

Link

  1. J'ai créé un contrôleur de radio Internet avec Raspberry Pi 2 et 1/10 RC de Tamiya

  2. [Utiliser le capteur de distance à ultrasons (HC-SR04)](http://make.bcde.jp/raspberry-pi/%e8%b6%85%e9%9f%b3%e6%b3%a2%e8 % b7% 9d% e9% 9b% a2% e3% 82% bb% e3% 83% b3% e3% 82% b5hc-sr04% e3% 82% 92% e4% bd% bf% e3% 81% 86 /)

  3. Contrôlez la télécommande à l'aide de Raspberry Pi 3 Model B + et lilc 1

  4. Comment créer un réseau Ad-Hoc pour RPI

  5. ServoBlaster

Recommended Posts

Fabriquez une voiture robotique à conduite automatique avec Raspberry Pi3 B + et capteur de distance à ultrasons HC-SR04
MQTT Radicon Car avec Arduino et Raspberry
Faire un rappel de parapluie avec Raspberry Pi Zero W
Fabriquez un climatiseur intégré à un ordinateur personnel "airpi" avec Raspberry Pi 3!
Fabriquez un incubateur à CO2 simple à l'aide de Raspberry PI et d'un capteur de CO2 (MH-Z14A)
Créez un thermomètre avec Raspberry Pi et rendez-le visible sur le navigateur Partie 4
Faire une boussole d'affichage kanji avec Raspberry Pi et Sense Hat
Faisons une chemise IoT avec Lambda, Kinesis, Raspberry Pi [Partie 1]
Créez un convertisseur Ethernet LAN sans fil et un routeur simple avec Raspberry Pi
Acquérir la valeur du capteur de Grove Pi + avec Raspberry Pi et la stocker dans Kintone
Surveillance des animaux avec Rekognition et Raspberry pi
Capteur humain amélioré fabriqué avec Raspberry Pi
Utiliser le capteur de mouvement PIR avec Raspberry Pi
Faire une minuterie de lavage-séchage avec Raspberry Pi
Faites fonctionner l'oscilloscope avec le Raspberry Pi
Créez un compteur de voiture avec Raspberry Pi
Fabriquez un thermomètre avec Raspberry Pi et rendez-le visible sur le navigateur Partie 3
J'ai tweeté l'éclairement de la pièce avec Raspberry Pi, Arduino et un capteur optique
[Pour les débutants] J'ai fait un capteur humain avec Raspberry Pi et notifié LINE!
Fabriquer un appareil de surveillance avec un capteur infrarouge
Raspberry + am2302 Mesure la température et l'humidité avec un capteur de température et d'humidité
Obtenez la température et l'humidité avec DHT11 et Raspberry Pi
Suivi GPS avec Raspeye 4B + BU-353S4 (Python)