Limelight Lib Python
limelightlib-python est le moyen le plus simple d'interfacer avec les appareils Limelight. Il fonctionne sur tous les systèmes d'exploitation (MacOS, Windows, Linux) et architectures (x86, ARM).
- https://github.com/LimelightVision/limelightlib-python
 - https://pypi.org/project/limelightlib-python/
 
Installation
pip install limelightlib-python
Utilisation
import limelight
import limelightresults
import json
import time
discovered_limelights = limelight.discover_limelights(debug=True)
print("limelights découverts:", discovered_limelights)
if discovered_limelights:
    limelight_address = discovered_limelights[0] 
    ll = limelight.Limelight(limelight_address)
    results = ll.get_results()
    status = ll.get_status()
    print("-----")
    print("résultats de ciblage:", results)
    print("-----")
    print("statut:", status)
    print("-----")
    print("température:", ll.get_temp())
    print("-----")
    print("nom:", ll.get_name())
    print("-----")
    print("fps:", ll.get_fps())
    print("-----")
    print("rapport matériel:", ll.hw_report())
    ll.enable_websocket()
   
    # afficher les paramètres actuels du pipeline
    print(ll.get_pipeline_atindex(0))
    # mettre à jour le pipeline actuel et enregistrer sur le disque
    pipeline_update = {
    'area_max': 98.7,
    'area_min': 1.98778
    }
    ll.update_pipeline(json.dumps(pipeline_update),flush=1)
    print(ll.get_pipeline_atindex(0))
    # passer au pipeline 1
    ll.pipeline_switch(1)
    # mettre à jour les données utilisateur personnalisées
    ll.update_python_inputs([4.2,0.1,9.87])
    
    
    try:
        while True:
            result = ll.get_latest_results()
            parsed_result = limelightresults.parse_results(result)
            if parsed_result is not None:
                print("cibles valides: ", parsed_result.validity, ", pipelineIndex: ", parsed_result.pipeline_id,", Latence de ciblage: ", parsed_result.targeting_latency)
                #for tag in parsed_result.fiducialResults:
                #    print(tag.robot_pose_target_space, tag.fiducial_id)
            time.sleep(1)  # Mettre à 0 pour un fps maximal
    except KeyboardInterrupt:
        print("Programme interrompu par l'utilisateur, arrêt en cours.")
    finally:
        ll.disable_websocket()
                
Méthodes
Basées sur REST
- get_results(): Récupère les derniers résultats via HTTP GET.
 - capture_snapshot(snapname): Capture un instantané avec un nom donné.
 - upload_snapshot(snapname, image_path): Télécharge un instantané avec un nom et un fichier image donnés.
 - snapshot_manifest(): Récupère le manifeste des instantanés via HTTP GET.
 - delete_snapshots(): Supprime tous les instantanés via HTTP GET.
 - upload_neural_network(nn_type, file_path): Télécharge un fichier de réseau neuronal avec un type spécifié.
 - hw_report(): Récupère le rapport matériel via HTTP GET.
 - cal_default(): Récupère les données de calibration par défaut via HTTP GET.
 - cal_file(): Récupère les données de calibration depuis un fichier via HTTP GET.
 - cal_eeprom(): Récupère les données de calibration depuis l'EEPROM via HTTP GET.
 - cal_latest(): Récupère les dernières données de calibration via HTTP GET.
 - update_cal_eeprom(cal_data): Met à jour les données de calibration dans l'EEPROM via HTTP POST.
 - update_cal_file(cal_data): Met à jour les données de calibration dans un fichier via HTTP POST.
 - delete_cal_latest(): Supprime les dernières données de calibration via HTTP DELETE.
 - delete_cal_eeprom(): Supprime les données de calibration de l'EEPROM via HTTP DELETE.
 - delete_cal_file(): Supprime les données de calibration du fichier via HTTP DELETE.
 
Basées sur WebSocket
- enable_websocket(): Initialise et démarre une connexion WebSocket dans un autre thread.
 - disable_websocket(): Ferme la connexion WebSocket et rejoint le thread.
 - get_latest_results(): Renvoie les derniers résultats reçus du WebSocket.
 
Analyse
- limelightresults.parse_results(): Analyse les résultats et renvoie un objet GeneralResult
 
Spécification de la classe Result
class GeneralResult:
    def __init__(self, results):
        self.barcode = results.get("Barcode", [])
        self.classifierResults = [ClassifierResult(item) for item in results.get("Classifier", [])]
        self.detectorResults = [DetectorResult(item) for item in results.get("Detector", [])]
        self.fiducialResults = [FiducialResult(item) for item in results.get("Fiducial", [])]
        self.retroResults = [RetroreflectiveResult(item) for item in results.get("Retro", [])]
        self.botpose = results.get("botpose", [])
        self.botpose_wpiblue = results.get("botpose_wpiblue", [])
        self.botpose_wpired = results.get("botpose_wpired", [])
        self.capture_latency = results.get("cl", 0)
        self.pipeline_id = results.get("pID", 0)
        self.robot_pose_target_space = results.get("t6c_rs", [])
        self.targeting_latency = results.get("tl", 0)
        self.timestamp = results.get("ts", 0)
        self.validity = results.get("v", 0)
        self.parse_latency = 0.0
class RetroreflectiveResult:
    def __init__(self, retro_data):
        self.points = retro_data["pts"]
        self.camera_pose_target_space = retro_data["t6c_ts"]
        self.robot_pose_field_space = retro_data["t6r_fs"]
        self.robot_pose_target_space = retro_data["t6r_ts"]
        self.target_pose_camera_space = retro_data["t6t_cs"]
        self.target_pose_robot_space = retro_data["t6t_rs"]
        self.target_area = retro_data["ta"]
        self.target_x_degrees = retro_data["tx"]
        self.target_x_pixels = retro_data["txp"]
        self.target_y_degrees = retro_data["ty"]
        self.target_y_pixels = retro_data["typ"]
class FiducialResult:
    def __init__(self, fiducial_data):
        self.fiducial_id = fiducial_data["fID"]
        self.family = fiducial_data["fam"]
        self.points = fiducial_data["pts"]
        self.skew = fiducial_data["skew"]
        self.camera_pose_target_space = fiducial_data["t6c_ts"]
        self.robot_pose_field_space = fiducial_data["t6r_fs"]
        self.robot_pose_target_space = fiducial_data["t6r_ts"]
        self.target_pose_camera_space = fiducial_data["t6t_cs"]
        self.target_pose_robot_space = fiducial_data["t6t_rs"]
        self.target_area = fiducial_data["ta"]
        self.target_x_degrees = fiducial_data["tx"]
        self.target_x_pixels = fiducial_data["txp"]
        self.target_y_degrees = fiducial_data["ty"]
        self.target_y_pixels = fiducial_data["typ"]
class DetectorResult:
    def __init__(self, detector_data):
        self.class_name = detector_data["class"]
        self.class_id = detector_data["classID"]
        self.confidence = detector_data["conf"]
        self.points = detector_data["pts"]
        self.target_area = detector_data["ta"]
        self.target_x_degrees = detector_data["tx"]
        self.target_x_pixels = detector_data["txp"]
        self.target_y_degrees = detector_data["ty"]
        self.target_y_pixels = detector_data["typ"]
class ClassifierResult:
    def __init__(self, classifier_data):
        self.class_name = classifier_data["class"]
        self.class_id = classifier_data["classID"]
        self.confidence = classifier_data["conf"]