Capteurs IoT et orientation - Technologie embarquée

Détection d'orientation IoT par IMU

Système IoT pour détecter l'état d'emballages pliables via capteurs inertiels et transmission LPWAN optimisée.

IoT Capteurs inertiels (IMU) LPWAN (Sigfox) C embarqué Optimisation énergétique Algèbre vectorielle

Le défi de la logistique intelligente

Un client spécialisé dans la logistique industrielle utilisait des caisses en bois pliables pour optimiser le transport et le stockage de marchandises. Ces emballages intelligents peuvent prendre trois configurations distinctes :

  • Fermée : prête pour le transport
  • Ouverte : en cours d'utilisation
  • Pliée : optimisation de l'espace de stockage
Caisse pliable en bois similaire au projet
Exemple de caisse pliable similaire à celle du projet

L'objectif était de développer un système IoT capable de détecter automatiquement l'état de chaque caisse et de transmettre cette information via un réseau LPWAN (Sigfox) avec une consommation énergétique minimale.

Principe de détection par orientation

La solution repose sur un principe élégant : en fixant un capteur inertiel (IMU) sur le couvercle de la caisse, il devient possible de détecter l'état uniquement en mesurant l'orientation du capteur dans l'espace.

Les trois orientations possibles de l'IMU selon l'état de la caisse
Dans chaque configuration, l'IMU adopte une orientation différente dans l'espace

Cette approche présente plusieurs avantages techniques majeurs :

  • Simplicité du capteur : Un simple accéléromètre 3 axes suffit
  • Robustesse : Pas de pièces mécaniques mobiles
  • Faible consommation : Transmissions ponctuelles uniquement

Optimisation de la transmission LPWAN

Un défi majeur était l'optimisation de la bande passante pour les réseaux LPWAN comme Sigfox, qui sont limités en débit et en nombre de messages quotidiens. Avec trois états possibles plus un état d'erreur, l'encodage optimal nécessite seulement 2 bits :

Code binaire État détecté
00 Fermé
01 Ouvert
10 Plié
11 État inconnu / Erreur

Mesure et analyse du vecteur gravité

Le principe de détection repose sur l'analyse du vecteur gravité mesuré par l'accéléromètre. Dans chaque configuration, ce vecteur pointe vers le centre de la Terre mais son orientation relative dans le repère du capteur change selon l'état de la caisse.

Pour mesurer l'orientation, il suffit de mesurer le vecteur gravité qui est différent dans les trois positions. Un accéléromètre au repos ne mesure que l'accélération due à la gravité terrestre (environ 9,81 m/s²), qui constitue une référence d'orientation absolue parfaite.

Orientation du vecteur gravité dans le repère du capteur
Le vecteur gravité dans le repère du capteur est différent dans les trois configurations

En deux dimensions, l'exemple serait assez simple à résoudre, mais en réalité nous travaillons avec trois axes et nous pouvons être amenés à identifier des orientations dans toutes les directions de l'espace. Cette complexité tridimensionnelle nécessite une approche algorithmique robuste basée sur l'algèbre vectorielle.

Algorithme de reconnaissance d'orientation

L'algorithme développé suit une approche en plusieurs étapes pour identifier de manière robuste l'orientation du capteur :

1. Mesure expérimentale des vecteurs de référence

La première étape consiste à déterminer expérimentalement un vecteur gravité pour chaque orientation possible de la caisse. Pour cela, on place physiquement la caisse dans chacune des trois configurations (fermée, ouverte, pliée) et on enregistre les mesures de l'accéléromètre.

Ces mesures sont ensuite normalisées pour obtenir des vecteurs unitaires qui serviront de références. Cette calibration empirique garantit que l'algorithme s'adapte aux conditions réelles d'installation du capteur.

2. Définition des structures de données

Une fois les vecteurs de référence déterminés, nous définons les structures nécessaires pour représenter les vecteurs 3D et les états d'orientation :

// Structure pour représenter un vecteur 3D
typedef struct {
    float x;    // Composante X (axe avant/arrière)
    float y;    // Composante Y (axe gauche/droite) 
    float z;    // Composante Z (axe haut/bas)
} Vector3D_t;

// Vecteurs de référence pour chaque orientation (normalisés)
// Ces valeurs sont mesurées expérimentalement lors de la phase de calibration
// en plaçant physiquement la caisse dans chaque configuration
Vector3D_t orientationVectors[] = {
    {0.0f, 0.0f, -1.0f},  // Fermé : gravité vers le bas du capteur
    {0.9f, 0.0f, 0.44f},  // Ouvert : capteur incliné ~26° (mesuré)
    {0.31f, 0.0f, 0.95f}, // Plié : capteur incliné ~72° (mesuré)
};

// Nombre de vecteurs de référence définis
const int n_vectors = sizeof(orientationVectors) / sizeof(orientationVectors[0]);

// Énumération des états possibles
typedef enum {
    CLOSED  = 0b00,  // Caisse fermée
    OPEN    = 0b01,  // Caisse ouverte
    FOLDED  = 0b10,  // Caisse pliée
    UNKNOWN = 0b11   // État indéterminé
} Orientation_t;

3. Mathématiques du produit scalaire

La reconnaissance d'orientation utilise le produit scalaire entre le vecteur gravité mesuré et les vecteurs de référence. Cette approche exploite une propriété fondamentale de l'algèbre vectorielle :

\[\vec{a} \cdot \vec{b} = |\vec{a}| \cdot |\vec{b}| \cdot \cos(\theta)\]

θ est l'angle entre les deux vecteurs

Comme nos vecteurs sont normalisés (norme = 1), le produit scalaire nous donne directement cos(θ), permettant une mesure simple et efficace de l'angle entre les orientations.

4. Implémentation de l'algorithme

L'algorithme final combine normalisation vectorielle et comparaison par produit scalaire avec seuillage adaptatif :

// Configuration du seuil de tolérance angulaire
#define MAX_ANGLE_DEGREES 10.0f           // Tolérance maximale en degrés
#define DEG_TO_RAD (3.14159265f / 180.0f) // Conversion degrés -> radians

// Calcul du seuil : cos(angle_max)
// Plus l'angle autorisé est petit, plus le seuil est proche de 1
const float threshold = cos(MAX_ANGLE_DEGREES * DEG_TO_RAD);

/**
 * Détermine l'orientation de la caisse à partir du vecteur gravité mesuré
 * 
 * @param gravity Vecteur gravité brut de l'accéléromètre
 * @return État détecté (CLOSED, OPEN, FOLDED, ou UNKNOWN)
 */
Orientation_t getOrientation(Vector3D_t gravity) {
    // Étape 1: Normalisation du vecteur gravité mesuré
    float norm = sqrt(gravity.x * gravity.x + 
                     gravity.y * gravity.y + 
                     gravity.z * gravity.z);
    
    // Vérification de la validité de la mesure
    if (norm == 0.0f) {
        return UNKNOWN;  // Évite la division par zéro
    }
    
    // Création du vecteur normalisé
    Vector3D_t normGravity = { 
        gravity.x / norm, 
        gravity.y / norm, 
        gravity.z / norm 
    };

    // Étape 2: Comparaison avec chaque vecteur de référence
    for (int i = 0; i < n_vectors; i++) {
        // Calcul du produit scalaire = cos(θ)
        float dotProduct = normGravity.x * orientationVectors[i].x +
                          normGravity.y * orientationVectors[i].y +
                          normGravity.z * orientationVectors[i].z;
        
        // Si l'angle est suffisamment petit (cos(θ) > threshold)
        if (dotProduct > threshold) {
            return (Orientation_t)i;  // Orientation reconnue
        }
    }
    
    // Aucune orientation reconnue avec la tolérance définie
    return UNKNOWN;
}

Avantages et inconvénients de la solution

Cette approche basée sur l'algèbre vectorielle présente plusieurs avantages significatifs :

  • Simplicité algorithmique : Opérations arithmétiques légères, parfaitement adaptées aux microcontrôleurs basse consommation
  • Pas d'apprentissage requis : Algorithme déterministe sans phase d'entraînement, calibration directe par mesure physique
  • Transmission ultra-optimisée : Seulement 2 bits par message sur les réseaux LPWAN contraints
  • Configuration simplifiée : Seulement un seuil angulaire en degrés à configurer pour la sensibilité
  • Compatible avec calibration automatique : Cette solution se combine parfaitement avec les méthodes de calibration automatique d'IMU si l'orientation de fixation de l'équipement n'est pas connue précisément

Le principe développé est facilement extensible à d'autres cas d'usage comme par exemple la détection d'un changement d'orientation sans nécessairement identifier d'orientations prédéfinies pour détecter une chute, un mouvement anormal, etc.

Démonstration interactive : Détection d'orientation par IMU

Simulation interactive de la détection d'orientation d'un capteur IMU. Vous pouvez ajuster l'angle du capteur et voir en temps réel comment l'algorithme détecte les orientations de référence configurées.

Expérience optimale sur ordinateur
Cette démonstration interactive est conçue pour être utilisée sur un écran d'ordinateur avec une souris ou un trackpad.

Les interactions tactiles peuvent ne pas fonctionner correctement sur cette démonstration.

Un projet IoT similaire vous intéresse ?

Discutons de vos besoins en instrumentation IoT et capteurs intelligents.