Cours:SaéSBC robotAutonome : Différence entre versions
(→rplidar) |
|||
(8 révisions intermédiaires par 2 utilisateurs non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
− | =pi5 et pwm= | + | L'objectif général est de concevoir la partie logicielle (POO/C++/Qt) d'une voiture autonome. |
+ | |||
+ | Le projet sera décomposé en deux parties : | ||
+ | # Conception logicielle d'une voiture simulée | ||
+ | # Conception logicielle d'une voiture réelle= | ||
+ | |||
+ | = Partie 1 : voiture simulée = | ||
+ | |||
+ | * À partir du lundi matin jusqu'au mardi fin de matinée | ||
+ | * Objectifs progressifs | ||
+ | |||
+ | 1) Tours de circuits sans sortir des limites, au minimum sans la gestion des collisions entre voitures | ||
+ | |||
+ | 2) Ajout d'une interface déportée : | ||
+ | * Un bouton ''Start'' | ||
+ | * Affichage d'informations sur l'état de la voiture | ||
+ | * Communiquant avec la voiture par TCP | ||
+ | |||
+ | 3) Tours sur un circuit plus complexe, comportant des virages serrés et nécessitant une gestion de la marche arrière | ||
+ | |||
+ | = Partie 2 : voiture réelle = | ||
+ | |||
+ | Objectifs progressifs | ||
+ | |||
+ | 1) Déplacement en évitant les obstacles | ||
+ | |||
+ | 2) Ajout d'une interface délocalisée | ||
+ | |||
+ | 3) Gestion de la marche arrière | ||
+ | |||
+ | 4) Déplacement sur un trajet connu à l'avance, comportant des croisements (par ex. départ en GEII, arrivée dans la hall central de l'IUT). | ||
+ | |||
+ | = Annexe : ressources = | ||
+ | |||
+ | ==rplidar== | ||
+ | |||
+ | {{Todo|Ajouter au fichier de projet :}} | ||
+ | <source lang=cpp> | ||
+ | unix:!macx: LIBS += -L/opt/electronique/pi4TpInfo/sysroot/rplidar/rplidar_sdk/output/Linux/Release/ -lsl_lidar_sdk | ||
+ | |||
+ | INCLUDEPATH += /opt/electronique/pi4TpInfo/sysroot/rplidar/rplidar_sdk/sdk/include | ||
+ | INCLUDEPATH += /opt/electronique/pi4TpInfo/sysroot/rplidar/rplidar_sdk/sdk/src | ||
+ | DEPENDPATH += /opt/electronique/pi4TpInfo/sysroot/rplidar/rplidar_sdk/sdk/include | ||
+ | |||
+ | unix:!macx: PRE_TARGETDEPS += /opt/electronique/pi4TpInfo/sysroot/rplidar/rplidar_sdk/output/Linux/Release/libsl_lidar_sdk.a | ||
+ | </source> | ||
+ | |||
+ | Initialisation : | ||
+ | |||
+ | <source lang=cpp> | ||
+ | |||
+ | // fichier .h | ||
+ | |||
+ | #include "sl_lidar_driver.h" | ||
+ | using namespace std; | ||
+ | using namespace sl; | ||
+ | |||
+ | ILidarDriver * drv; | ||
+ | |||
+ | |||
+ | // fichier .cpp | ||
+ | #include <QtMath> | ||
+ | |||
+ | #ifndef _countof | ||
+ | #define _countof(_Array) (int)(sizeof(_Array) / sizeof(_Array[0])) | ||
+ | #endif | ||
+ | |||
+ | |||
+ | |||
+ | drv = *createLidarDriver(); | ||
+ | if (!drv) { | ||
+ | qDebug()<<"erreur"; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | qDebug()<<"driver ok"; | ||
+ | } | ||
+ | |||
+ | IChannel* _channel; | ||
+ | _channel = (*createSerialPortChannel("/dev/ttyUSB0", 115200)); | ||
+ | |||
+ | sl_result op_result; | ||
+ | sl_lidar_response_device_info_t devinfo; | ||
+ | bool connectSuccess = false; | ||
+ | if (SL_IS_OK((drv)->connect(_channel))) { | ||
+ | op_result = drv->getDeviceInfo(devinfo); | ||
+ | if (SL_IS_OK(op_result)) | ||
+ | { | ||
+ | connectSuccess = true; | ||
+ | qDebug()<<"connecté sur le lidar"; | ||
+ | } | ||
+ | else{ | ||
+ | delete drv; | ||
+ | drv = NULL; | ||
+ | } | ||
+ | qDebug()<<"SLAMTEC LIDAR S/N: "<<devinfo.serialnum; | ||
+ | qDebug()<<"Firmware Ver: "<<(devinfo.firmware_version>>8)<<"."<<(devinfo.firmware_version & 0xFF) | ||
+ | <<"Hardware Rev: "<<(int)devinfo.hardware_version; | ||
+ | } | ||
+ | drv->setMotorSpeed(); | ||
+ | drv->startScan(0,1); | ||
+ | |||
+ | </source> | ||
+ | |||
+ | Lecture des données (utiliser un QTimer, toutes les 50ms par ex): | ||
+ | |||
+ | <source lang=cpp> | ||
+ | sl_lidar_response_measurement_node_hq_t nodes[8192]; | ||
+ | size_t count = _countof(nodes); | ||
+ | sl_result op_result = drv->grabScanDataHq(nodes, count); | ||
+ | |||
+ | if (SL_IS_OK(op_result)) | ||
+ | { | ||
+ | distances.fill(0); | ||
+ | for (int i=0;i<(int)count;i++) | ||
+ | { | ||
+ | int angle=round((nodes[i].angle_z_q14 * 90.f) / 16384.f); | ||
+ | if (angle>=180) angle=angle-360; | ||
+ | if ((angle>=-180)and(angle<180)) | ||
+ | { | ||
+ | int d=nodes[i].dist_mm_q2/4.0; | ||
+ | if (d>0) distances.at(angle+180)=d; | ||
+ | } | ||
+ | } | ||
+ | for (int i=0;i<360;i++) | ||
+ | { | ||
+ | if (distances.at(i)==0) | ||
+ | { | ||
+ | for (int j=1;j<10;j++) | ||
+ | { | ||
+ | int pos=(i+j)%360; | ||
+ | if (distances.at(pos)!=0) distances.at(i)=distances.at(pos); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | ==pi5 et gpio== | ||
+ | |||
+ | cat /sys/kernel/debug/gpio | ||
+ | |||
+ | utiliser libgpiod !! | ||
+ | |||
+ | ==pi5 et pwm== | ||
*config : modifier le fichier /boot/firmware/config.txt | *config : modifier le fichier /boot/firmware/config.txt | ||
Ligne 18 : | Ligne 162 : | ||
***modifier duty_cyle et period | ***modifier duty_cyle et period | ||
− | =tfmini= | + | ==tfmini== |
*https://github.com/TFmini/TFmini-I2C-MasterExample_Arduino/blob/master/TFminiReadData/TFminiReadData.ino | *https://github.com/TFmini/TFmini-I2C-MasterExample_Arduino/blob/master/TFminiReadData/TFminiReadData.ino |
Version actuelle datée du 17 octobre 2024 à 10:51
L'objectif général est de concevoir la partie logicielle (POO/C++/Qt) d'une voiture autonome.
Le projet sera décomposé en deux parties :
- Conception logicielle d'une voiture simulée
- Conception logicielle d'une voiture réelle=
Sommaire
Partie 1 : voiture simulée
- À partir du lundi matin jusqu'au mardi fin de matinée
- Objectifs progressifs
1) Tours de circuits sans sortir des limites, au minimum sans la gestion des collisions entre voitures
2) Ajout d'une interface déportée :
- Un bouton Start
- Affichage d'informations sur l'état de la voiture
- Communiquant avec la voiture par TCP
3) Tours sur un circuit plus complexe, comportant des virages serrés et nécessitant une gestion de la marche arrière
Partie 2 : voiture réelle
Objectifs progressifs
1) Déplacement en évitant les obstacles
2) Ajout d'une interface délocalisée
3) Gestion de la marche arrière
4) Déplacement sur un trajet connu à l'avance, comportant des croisements (par ex. départ en GEII, arrivée dans la hall central de l'IUT).
Annexe : ressources
rplidar
Ajouter au fichier de projet :
unix:!macx: LIBS += -L/opt/electronique/pi4TpInfo/sysroot/rplidar/rplidar_sdk/output/Linux/Release/ -lsl_lidar_sdk
INCLUDEPATH += /opt/electronique/pi4TpInfo/sysroot/rplidar/rplidar_sdk/sdk/include
INCLUDEPATH += /opt/electronique/pi4TpInfo/sysroot/rplidar/rplidar_sdk/sdk/src
DEPENDPATH += /opt/electronique/pi4TpInfo/sysroot/rplidar/rplidar_sdk/sdk/include
unix:!macx: PRE_TARGETDEPS += /opt/electronique/pi4TpInfo/sysroot/rplidar/rplidar_sdk/output/Linux/Release/libsl_lidar_sdk.a
Initialisation :
// fichier .h
#include "sl_lidar_driver.h"
using namespace std;
using namespace sl;
ILidarDriver * drv;
// fichier .cpp
#include <QtMath>
#ifndef _countof
#define _countof(_Array) (int)(sizeof(_Array) / sizeof(_Array[0]))
#endif
drv = *createLidarDriver();
if (!drv) {
qDebug()<<"erreur";
}
else
{
qDebug()<<"driver ok";
}
IChannel* _channel;
_channel = (*createSerialPortChannel("/dev/ttyUSB0", 115200));
sl_result op_result;
sl_lidar_response_device_info_t devinfo;
bool connectSuccess = false;
if (SL_IS_OK((drv)->connect(_channel))) {
op_result = drv->getDeviceInfo(devinfo);
if (SL_IS_OK(op_result))
{
connectSuccess = true;
qDebug()<<"connecté sur le lidar";
}
else{
delete drv;
drv = NULL;
}
qDebug()<<"SLAMTEC LIDAR S/N: "<<devinfo.serialnum;
qDebug()<<"Firmware Ver: "<<(devinfo.firmware_version>>8)<<"."<<(devinfo.firmware_version & 0xFF)
<<"Hardware Rev: "<<(int)devinfo.hardware_version;
}
drv->setMotorSpeed();
drv->startScan(0,1);
Lecture des données (utiliser un QTimer, toutes les 50ms par ex):
sl_lidar_response_measurement_node_hq_t nodes[8192];
size_t count = _countof(nodes);
sl_result op_result = drv->grabScanDataHq(nodes, count);
if (SL_IS_OK(op_result))
{
distances.fill(0);
for (int i=0;i<(int)count;i++)
{
int angle=round((nodes[i].angle_z_q14 * 90.f) / 16384.f);
if (angle>=180) angle=angle-360;
if ((angle>=-180)and(angle<180))
{
int d=nodes[i].dist_mm_q2/4.0;
if (d>0) distances.at(angle+180)=d;
}
}
for (int i=0;i<360;i++)
{
if (distances.at(i)==0)
{
for (int j=1;j<10;j++)
{
int pos=(i+j)%360;
if (distances.at(pos)!=0) distances.at(i)=distances.at(pos);
}
}
}
}
pi5 et gpio
cat /sys/kernel/debug/gpio
utiliser libgpiod !!
pi5 et pwm
- config : modifier le fichier /boot/firmware/config.txt
dtoverlay=pwm-2chan,pin=18,pin2=19
- vérif :
dtoverlay=pwm-2chan,pin=18,pin2=19
- https://gist.github.com/Gadgetoid/b92ad3db06ff8c264eef2abf0e09d569
- https://community.element14.com/products/raspberry-pi/m/files/148385
- https://forums.raspberrypi.com/viewtopic.php?t=359251
- pwmchip2
- channel 2 => gpio18
- echo 2 > /sys/class/pwm/pwmchip2/export
- modifier duty_cyle et period
- channel 3 => gpio19
- echo 3 > /sys/class/pwm/pwmchip2/export
- modifier duty_cyle et period
- channel 2 => gpio18