Skip to content
Open
Show file tree
Hide file tree
Changes from 100 commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
603a4e7
feat: rajout de lidar.stop dans car.stop() et de multiprocessus dans …
Cbampeta Nov 1, 2025
772314b
Merge branch 'main' into main-manager
Cbampeta Nov 5, 2025
dece7b4
Ajout du serveur a la branch main manager. Attention pas encore eu la…
ExoRoy Nov 5, 2025
923856a
Merge remote-tracking branch 'refs/remotes/origin/main-manager' into …
Cbampeta Nov 5, 2025
9188d3a
creation de test_serveur pour tester la communication zerorpc
Cbampeta Nov 6, 2025
895f19b
feat: rajout des constantes vitesse et direction dans la classe apivo…
Cbampeta Nov 12, 2025
c2e72cb
fix : journal handler name
Cbampeta Nov 12, 2025
caacc48
feat: rajout des dépendence dans le Serveur en attendant de le rajout…
Cbampeta Nov 12, 2025
2a05b38
feat : rajout de test pour vérifier si le serveur est lancé
Cbampeta Nov 12, 2025
f536c1a
fix : self.cam.start
Cbampeta Nov 12, 2025
ed66194
rajouut de try et de exception pour voir les erreur
Cbampeta Nov 12, 2025
3a9d1e3
rajout de test au début
Cbampeta Nov 12, 2025
d0116d1
test
Cbampeta Nov 12, 2025
7cdc0e2
fix : enlevage de system car pas important pour l'instant
Cbampeta Nov 13, 2025
12b0e4d
fix : enlevage de picamera en attendant de test zerorpc
Cbampeta Nov 13, 2025
d0597c0
test
Cbampeta Nov 13, 2025
583775b
test
Cbampeta Nov 13, 2025
7bd7118
fix: on passe a une meilleur structure de read_data fait par l'asserv…
Cbampeta Nov 13, 2025
88a16ce
changement dans test_serveur
Cbampeta Nov 13, 2025
b16f35f
fix: dans read_data oublie de self et rajout de la mise à jour de la …
Cbampeta Nov 13, 2025
9556f2b
feat : enlevage des print inutile et rajout de variable pour enregist…
Cbampeta Nov 13, 2025
728d40d
feat : rajout de test serveru avec la nouvelle structure de zeromq
Cbampeta Nov 15, 2025
27d9f4d
fix: fix dans serveur_mq et test_serveur
Cbampeta Nov 15, 2025
6ee55a0
fix
Cbampeta Nov 15, 2025
3c03eec
fix: ça marche le serveur_mq et le test_serveur
Cbampeta Nov 15, 2025
5fff2b0
rajout de sécurité pour Serveur_mq et l'envoie par i2c
Cbampeta Nov 15, 2025
5257fc3
fix: erreur de syntaxe
Cbampeta Nov 15, 2025
4ff0624
rajout de smbus et zmq dans les dépendance et code test_serveur et Se…
Cbampeta Nov 15, 2025
7c8225f
test de rajoue d'information dans Serveur_mq
Cbampeta Nov 15, 2025
1762638
rajout de l'idle pour test
Cbampeta Nov 15, 2025
cdbcf48
fix
Cbampeta Nov 15, 2025
79550b3
fix : changement dans Serveur_mq et creation d'un main dans Serveur_mq
Cbampeta Nov 16, 2025
f4efd9e
feat : its working (i thnils)
Cbampeta Nov 16, 2025
ad7f2c0
feat : commit (rajout de test pour le chunk de idiams
Cbampeta Nov 17, 2025
4906d16
Merge branch 'main' into main-manager
Cbampeta Nov 17, 2025
8a55a2b
fix : changement dans commande_PS4 pour marcher avec zmq
Cbampeta Nov 17, 2025
746b2c6
feat: on peu maintenant lancer commande ps4 depuis la voiture avec le…
Cbampeta Nov 17, 2025
96faa64
changemnet et rajout d'un afffichage de running et de capacinbilité d…
Cbampeta Nov 17, 2025
599ba8e
feat: suppression des prints incessant
Cbampeta Nov 17, 2025
ffed0fe
feat : cela marche
Cbampeta Nov 17, 2025
a594278
feat: rajout de la possibilité de prendre le control de la voiture a …
Cbampeta Nov 18, 2025
9bfa002
fix : on essaye de connecter le reste à la pi
Cbampeta Nov 18, 2025
06b8ff1
feat : passage en sub/pub pour soucis de vitesse
Cbampeta Nov 18, 2025
2fc2883
feat : mise a jour de commande_PS4 pour marcher avec la nouvelle stru…
Cbampeta Nov 18, 2025
e71c658
feat : utilisation de udp pour controller la voiture a distance
Cbampeta Nov 18, 2025
f73035f
fix: commande ps4 et serveur pour bien ensemble marcher
Cbampeta Nov 18, 2025
b120946
fix : reimplementation de l'envoie d'info par Serveur_mq
Cbampeta Nov 18, 2025
f6928f9
fix: chnaghement de non dans switch_remote_control
Cbampeta Nov 18, 2025
e04f42a
rajout de bouton reboot
Cbampeta Nov 18, 2025
5cdb8be
feat :rajout de bouton reboot
Cbampeta Nov 18, 2025
45045be
fix : on a serveur_mq et remote_controle et test_serveur qui marche bien
Cbampeta Nov 19, 2025
2d08d23
fix : reduction du lag dans la direction en envoie (j'ai supprimer le…
Cbampeta Nov 19, 2025
c4f8de6
rajout de la récupération des donnée du lidar
Cbampeta Nov 19, 2025
b5df107
fix : enleve le raise si on trouve pas le lidar
Cbampeta Nov 19, 2025
4b16f50
fix : changement dans startup pour lancer Serveur_mq avec uv
Cbampeta Nov 19, 2025
0109b51
fix : enlevage de l'affichage de no de info
Cbampeta Nov 19, 2025
0a76891
fix: résolution de l'appel de uv directement dans startup
Cbampeta Nov 19, 2025
01df9b4
feat: passage a l'utilisatinon de when_pressed
Cbampeta Nov 20, 2025
2fb2063
feat : rajout de lgpio dans les dépendances
Oct 6, 2025
89c90ab
feat: suppression de kill all dans les options et rajout que si un pr…
Cbampeta Nov 20, 2025
459274b
fix: on fait en sorte que lorsque l'on reapuiille sur le bouton cela …
Cbampeta Nov 20, 2025
c46ad65
fix : petit changement dans lorganisation des fonction
Cbampeta Nov 20, 2025
20b95a2
feat : rajout de fonction pas utiliser
Cbampeta Nov 21, 2025
899618c
feat: mise en classe le serveur
Cbampeta Nov 21, 2025
48117f7
fix : dans uv avec les bonne dépendance
Cbampeta Nov 21, 2025
967d232
feat : Serveur_mq slef en alerte
Cbampeta Nov 22, 2025
e4e0d31
correction des selfs du C
ExoRoy Nov 22, 2025
8a00574
feat: rajout de la prise de video en sortie par serveur_mq et entrée …
Cbampeta Nov 22, 2025
77a7eba
rajout de Camera_serv qui lance sur un lien la camera en temps réel
Cbampeta Nov 30, 2025
ebb85a9
changement du thread de camera_serv dans serveur_mq
Cbampeta Nov 30, 2025
8606da1
modification pour que Camera utilise Camera_serv pour récupéré les in…
Cbampeta Nov 30, 2025
459e5e0
changement en uv sync et rajout de opencv dans les dependance
Cbampeta Dec 1, 2025
5b6d3ff
rajouut de scipy en temps que dependance
Cbampeta Dec 1, 2025
0a7e74f
feat: rajout de la fonctionnabilité de toggle le lancement du stream …
Cbampeta Dec 2, 2025
4a0d602
fix: petit fix sur coment son lancé les fonctions depuis le menu
Cbampeta Dec 2, 2025
0e2a082
fix: kill du thread de remote control maintenant opérationnelle
Cbampeta Dec 2, 2025
298e430
fix : diminution du nombre de thread actif.
Cbampeta Dec 2, 2025
dc5b418
rajout, d'information a envoyé.
Cbampeta Dec 2, 2025
073cdae
z
Cbampeta Dec 2, 2025
574293e
fix: optimistion de Camera_serv et Camera pour avoir un flux video pl…
Cbampeta Dec 2, 2025
aac925b
feat: utilisation du nouveau system de programme en passant tout par …
Cbampeta Dec 4, 2025
0ce59a1
fix: fix plusiseur programme pour que cela marche
Cbampeta Dec 4, 2025
89666e8
fix: petit embélissement et suppression de chose inutile
Cbampeta Dec 4, 2025
2126db6
fix: dans remote control import time
Cbampeta Dec 4, 2025
68c134b
Merge branch 'main' into main-manager
Cbampeta Dec 4, 2025
1d1218b
feat : rajout d'information pour mes fonction
Cbampeta Dec 4, 2025
f335843
fix : rajout de la possibilité de mettre la voiture en stand by.
Cbampeta Dec 4, 2025
c3212b6
feat : rajout de commantaire pour plus de visibilité
Cbampeta Dec 4, 2025
c1e92e5
feat : rajout Car pour qu'il soit utiliser dans la nouvelle structure
Cbampeta Dec 11, 2025
863741d
test: rajout d'un programme pour les module externe
Cbampeta Dec 16, 2025
f76afa7
feat: uniformisation direction_d et rajout d'un module pour initialis…
Cbampeta Dec 16, 2025
61a34f2
fix: petit soucis
Cbampeta Dec 16, 2025
e4b21ec
fix: rajout de l'import os dans poweroff
Cbampeta Dec 16, 2025
b7af974
fix : suppression de fichier inutile
Cbampeta Dec 16, 2025
0d15e34
feat : changement de dans module_initialisation pour l'affichage (plu…
Cbampeta Dec 17, 2025
d1d32ea
fix: soucis oublie de self dans poweroff
Cbampeta Dec 17, 2025
0525d89
fix: revue de la structure du code (en terme de architecture des fich…
Cbampeta Dec 19, 2025
8a7aeae
fix: resolution de chemin de dependance pour les import (et aussi que…
Cbampeta Dec 19, 2025
1efb726
fix: toujours changement relatif au import
Cbampeta Dec 19, 2025
d61c722
fix: toujours changement relatif au import
Cbampeta Dec 19, 2025
752b677
feat: rajout de log partout
Cbampeta Dec 19, 2025
168f5bd
feat: rajout de log partout
Cbampeta Dec 19, 2025
8eaf919
feat: rajout de log partout
Cbampeta Dec 19, 2025
73d7321
feat: suppression d'un import dans serveur_mq qui servai a rien (np) …
Cbampeta Dec 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pourquoi preciser une partie et pas tout? Pas sure qu'on precis ici car il faudrais le tenir a jour en plus du pyproject.tml

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

je voulais préciser car se sont des dépendance qu'il faut installer pas sur uv. le reste est dans le uv sync --rpi

Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ For detailed information on architecture, hardware specifics and technical choic

(Note: The Wiki is currently private and reserved to INTech members)


# some dependencies needed
libcap-dev
python3-libcamera

# License

This project is distributed under the MIT License. See the Licence file for details.
5 changes: 4 additions & 1 deletion UV_USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ This project now uses [UV](https://github.com/astral-sh/uv) for fast, reliable P
curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.cargo/env
```

## Initialise uv for using external dependencies not installable in uv
```bash
uv venv --system-site-packages
```
### Install Project Dependencies
```bash
# Install all runtime dependencies
Expand Down
11 changes: 5 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,28 +41,27 @@ rpi = [
# Note: picamera2 causes UV to auto-include rpi extras even when not requested
# This is likely a UV bug. Add back when needed:
# "picamera2>=0.3.0",

# AI Inference
"onnxruntime>=1.8.0",

# Raspberry Pi specific hardware control
"rpi-hardware-pwm>=0.1.0",
"RPi.GPIO>=0.7.1",
"gpiozero>=1.6.0",

# I2C and SPI communication (Linux specific)
"smbus>=1.1.post2",
"spidev>=3.5",

# OLED display support
"luma.oled>=3.8.0",
"luma.core>=2.3.0",
"Adafruit-SSD1306>=1.6.0",

# Time-of-Flight sensor support
"adafruit-circuitpython-vl53l0x>=3.6.0",
"adafruit-blinka>=8.0.0",

# PS4 controller support
"pyPS4Controller>=1.2.0",
"zmq>=0.0.0",
"netifaces>=0.11.0",
"matplotlib>=3.10.5",
"opencv-python>=4.12.0.88",
"scipy>=1.15.3",
]
2 changes: 1 addition & 1 deletion scripts/bluetooth_auto/bluethootconnect.sh
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C'est quoi la logique derriere avoir celui la dans sont propre dossier?

Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ while read -r line; do
bluetoothctl connect "$mac"

echo
done < ./bluethoot_mac.txt
done < ./scripts/bluetooth_auto/bluethoot_mac.txt
177 changes: 100 additions & 77 deletions scripts/commande_PS4.py
Original file line number Diff line number Diff line change
@@ -1,133 +1,156 @@
from pyPS4Controller.controller import Controller
import time
import os
from threading import Thread

#Pour le protocole I2C de communication entre la rasberie Pi et l'arduino
import smbus #type: ignore #ignore the module could not be resolved error because it is a linux only module
import numpy as np
import struct

from src.HL.programme.programme import Program
from src.HL.Autotech_constant import MAX_ANGLE
###################################################
#Intialisation du protocole I2C
#Intialisation du protocole zmq
##################################################

# Create an SMBus instance
bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1

# I2C address of the slave
SLAVE_ADDRESS = 0x08

def write_vitesse_direction(vitesse,direction):
# Convert string to list of ASCII values
data = struct.pack('<ff', float(vitesse), float(direction))
bus.write_i2c_block_data(SLAVE_ADDRESS, 0, list(data))
def envoie_donnee(Voiture): #si utilisation de la voiture directement
print("lancement de l'i2c")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use logging

import smbus
import struct
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moyen fan des import ici mais ca ce defend

from src.HL.Autotech_constant import SLAVE_ADDRESS

###################################################
#Intialisation des moteurs
##################################################
bus = smbus.SMBus(1)
while True:
try :
data = struct.pack('<ff', float(round(Voiture.vitesse_mms)), float(round(Voiture.direction_d)))
bus.write_i2c_block_data(SLAVE_ADDRESS, 0, list(data))
#time.sleep(0.00005)
except Exception as e:
print("i2c mort" + str(e))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use logging

time.sleep(1)

direction_d = 0 # angle initiale des roues en degrés
vitesse_m = 0 # vitesse initiale en métre par milliseconde

#paramètres de la fonction vitesse_m_s, à étalonner
vitesse_max_m_s_hard = 8 #vitesse que peut atteindre la voiture en métre
vitesse_max_m_s_soft = 2 #vitesse maximale que l'on souhaite atteindre en métre par seconde
vitesse_min_m_s_soft = -2 #vitesse arriere que l'on souhaite atteindre en métre

angle_degre_max = +18 #vers la gauche


MAX_LEFT = -32767 + 3000 # deadzone 3000

# fonction naturel map de arduino pour plus de lisibilité
def map_range(x, in_min,in_max, out_min, out_max):
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min


class PS4ControllerProgram(Program):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

t'utilise jamais cette class si?


def __init__(self):
super().__init__()
self.name = "PS4 Controller"
self.running = False
self.controls_car = True

#initialisation
self.controller = MyController(interface="/dev/input/js0", connecting_using_ds4drv=False)
self.controller.stop = True

def set_direction_degre(angle_degre) :
global direction_d
direction_d = angle_degre
print("angle_degré: ",direction_d,"vitesse: ",vitesse_m)

def set_vitesse_m_ms(vitesse_m_ms):
global vitesse_m
vitesse_m = vitesse_m_ms
print("angle_degré: ",direction_d,"vitesse: ",vitesse_m)

def recule(): #actuellement ne sert a rien car on peux juste envoyer une vitesse négative
global vitesse_m
vitesse_m = -2000

def start(self):
self.running = True
self.controller.stop = False
self.thread = Thread(
target=self.controller.listen, kwargs=dict(timeout=60),
daemon=True
)
self.thread.start()

def kill(self):
self.controller.stop = True
self.running = False

@property
def vitesse_d(self):
return self.controller.vitesse_mms

@property
def direction_d(self):
return self.controller.direction_d

class MyController(Controller):

def __init__(self, **kwargs):
Controller.__init__(self, **kwargs)
super().__init__(**kwargs)
self.vitesse_mms = 0 # vitesse initiale en métre par milliseconde
self.direction_d = 0 # angle initiale des roues en degrés
self.filtered = 0
self.alpha = 0.3
self.running = 0

def stable_direction(self,value):

# Deadzone
if value < MAX_LEFT:
target = -MAX_ANGLE
else:
target = map_range(value, -32767, 0, -MAX_ANGLE, 0)

# Low-pass filtering
self.filtered = self.filtered * (1 - self.alpha) + target * self.alpha
return self.filtered


def on_R2_press(self,value):
vit = map_range(value,-32252,32767,0,vitesse_max_m_s_soft*1000)
if (vit < 0):
set_vitesse_m_ms(0)
self.vitesse_mms = 0
else:
set_vitesse_m_ms(vit)
self.vitesse_mms = vit
def on_R2_release(self): # arrete la voiture lorsque L2 est arrété d'étre préssé.
set_vitesse_m_ms(0)
self.vitesse_mms = 0



def on_L3_x_at_rest(self):
set_direction_degre(0)
self.direction = 0

def on_R1_press(self): #arret d'urgence
set_vitesse_m_ms(0)
self.vitesse_mms = 0

def on_R1_release(self):
set_vitesse_m_ms(0)
self.vitesse_mms = 0

def on_L3_up(self,value):
pass
def on_L3_down(self,value):
pass


def on_L3_right(self,value):
# print("x_r :", value, "degré : ",map_range(value,-32767, 32767, 60, 120))
dir = map_range(value, 0, 32767, 0, angle_degre_max)
set_direction_degre(dir)
dir = map_range(value, 0, 32767, 0, MAX_ANGLE)
self.direction_d = dir

def on_L3_left(self,value):
print("x_r :", value, "degré : ",map_range(value,-32767, 0, -angle_degre_max, 0 ))
dir = map_range(value,-32767, 0, -angle_degre_max, 0 )
set_direction_degre(dir)
#print("x_r :", value, "degré : ",map_range(value,-32767, 0, -MAX_ANGLE, 0 ))
dir = self.stable_direction(value)
self.direction_d = dir


def on_L2_press(self, value):
print("x_r :", value, "degré : ",map_range(value,-32767, 32767, 60, 120))
#print("x_r :", value, "degré : ",map_range(value,-32767, 32767, 60, 120))
vit = map_range(value,-32252,32767,0,vitesse_min_m_s_soft*1000)
if (vit > 0):
set_vitesse_m_ms(0)
self.vitesse_mms = 0
else:
set_vitesse_m_ms(vit)
self.vitesse_mms = vit

def on_L2_release(self): #arrete la voiture lorsque L2 est arrété d'étre préssé.
set_vitesse_m_ms(0)

#envoie de la direction et de l'angle toute les millisecondes
def envoie_direction_degre():
while True :
write_vitesse_direction(int(vitesse_m), int(direction_d))
time.sleep(0.001)


# boucle principal
controller = MyController(interface="/dev/input/js0", connecting_using_ds4drv=False)
try:
Thread(target = envoie_direction_degre, daemon=True).start()
controller.listen(timeout=60)

except KeyboardInterrupt:
print("Arrêt du programme")
controller.stop()
exit(0)
self.vitesse_mms = 0

def on_L3_up(self,value):
pass
def on_L3_down(self,value):
pass
def on_L3_y_at_rest(self):
pass

if __name__ == "__main__":
controller = MyController(interface="/dev/input/js0", connecting_using_ds4drv=False)
try:
Thread(target = envoie_donnee,args=(controller,), daemon=True).start()
controller.listen(timeout=60)

except KeyboardInterrupt:
print("Arrêt du programme")
controller.stop()
exit(0)
97 changes: 97 additions & 0 deletions scripts/envoie_camera_sur_web.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import io
import logging
import socketserver
from http import server
from threading import Condition

from picamera2 import Picamera2
from picamera2.encoders import JpegEncoder
from picamera2.outputs import FileOutput

# HTML page for the MJPEG streaming demo
PAGE = """\
<html>
<head>
<title>RaspberryTips Pi Cam Stream</title>
</head>
<body>
<h1>Raspberry Tips Pi Camera Live Stream Demo</h1>
<img src="stream.mjpg" width="640" height="480" />
</body>
</html>
"""

# Class to handle streaming output
class StreamingOutput(io.BufferedIOBase):
def __init__(self):
self.frame = None
self.condition = Condition()

def write(self, buf):
with self.condition:
self.frame = buf
self.condition.notify_all()

# Class to handle HTTP requests
class StreamingHandler(server.BaseHTTPRequestHandler):
def do_GET(self):
if self.path == '/':
# Redirect root path to index.html
self.send_response(301)
self.send_header('Location', '/index.html')
self.end_headers()
elif self.path == '/index.html':
# Serve the HTML page
content = PAGE.encode('utf-8')
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.send_header('Content-Length', len(content))
self.end_headers()
self.wfile.write(content)
elif self.path == '/stream.mjpg':
# Set up MJPEG streaming
self.send_response(200)
self.send_header('Age', 0)
self.send_header('Cache-Control', 'no-cache, private')
self.send_header('Pragma', 'no-cache')
self.send_header('Content-Type', 'multipart/x-mixed-replace; boundary=FRAME')
self.end_headers()
try:
while True:
with output.condition:
output.condition.wait()
frame = output.frame
self.wfile.write(b'--FRAME\r\n')
self.send_header('Content-Type', 'image/jpeg')
self.send_header('Content-Length', len(frame))
self.end_headers()
self.wfile.write(frame)
self.wfile.write(b'\r\n')
except Exception as e:
logging.warning(
'Removed streaming client %s: %s',
self.client_address, str(e))
else:
# Handle 404 Not Found
self.send_error(404)
self.end_headers()

# Class to handle streaming server
class StreamingServer(socketserver.ThreadingMixIn, server.HTTPServer):
allow_reuse_address = True
daemon_threads = True

# Create Picamera2 instance and configure it
picam2 = Picamera2()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use a if name = main block

picam2.configure(picam2.create_video_configuration(main={"size": (640, 480)}))
output = StreamingOutput()
picam2.start_recording(JpegEncoder(), FileOutput(output))

try:
# Set up and start the streaming server
address = ('', 8000)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C'est quoi ''? une ip? si oui utilise localhost ou 0.0.0.0

server = StreamingServer(address, StreamingHandler)
server.serve_forever()
finally:
# Stop recording when the script is interrupted
picam2.stop_recording()
Loading