Files
arthur 7496aafe64 lint(limagrain): corrections completes Phase 1+2
- Bloquants: mermaid 03-picking/_index reconstitue (archive 11-05), 13 liens vers pages squelette retires, 2 liens recibles (anoxie, application-dictionary)
- Conventions: 910 em dashes -> tirets simples, 145 checklists -> puces question, 13 questions resolues barrees
- Liens: 9 ancres reparees (slugs GitHub)
- Delta: 12 standard_ref remappes, blocs Standard EasyWMS + sections References ajoutes, front matter complete
- Glossaire: 15 termes standard deplaces en section rappel avec renvoi
- Rapport: limagrain/_lint_report.md (Phase 1 + Phase 2 + re-scan final)
- Inclut les pages des sessions precedentes non commitees + CLAUDE.md et consume.log en l'etat
2026-07-20 12:56:42 +02:00

20 KiB
Raw Permalink Blame History

title, tags, status, standard_ref, jira_refs, confluence_refs, sources, last_updated, author
title tags status standard_ref jira_refs confluence_refs sources last_updated author
Placement des palettes PS → PK (choix de table)
picking
placement
table
buffer
ping-pong
algorithme
draft concepts/picking.md
LIM-82
LIM-84
LIM-91
LIM-95
LIM-116
Logique combinatoire picking - PS vers PK - V1.0.md
Jira LIM-82 (commentaires revue de code)
Jira LIM-95 (Annulé, mergé dans LIM-82)
Jira LIM-116 (capacité buffers PK → PK)
2026-07-20 Arthur

Placement des palettes PS → PK (choix de table)

Résumé : algorithme exécuté par le WMS lorsqu'une palette source arrive au poste de sortie (PS). Il décide sur quelle table du PK la poser, ou la redirige vers un buffer ES. Ce process s'exécute en aval du séquençage TK → PS : les palettes arrivent au PS déjà triées.

Standard EasyWMS : → voir Picking Ce qui suit documente les spécificités Limagrain par rapport au standard.

Statut (LIM-82) : dev terminé, en attente de déploiement pour test. Livré en préprod le 25/06/2026, revue de code validée le 03/07/2026 (après une itération NOK le 02/07). Ce ticket est la reprise de LIM-75 (V1 annulé). Positionnement dans la chaîne : LIM-80 assignation → LIM-84 séquençage TK → PS → LIM-82 placement PS → PKProcess picking au PK (LIM-91).

⚠️ LIM-95 (Annulé) mergé ici : le ticket LIM-95 « [JOB] génération des mouvements depuis les buffers » est Annulé(e) ; ses modifications ont été intégrées à LIM-82 (commentaire Maxime Halgand, 26/06). Ses deux demandes sont couvertes ici : (1) ne pas générer le mouvement d'une palette si une autre tâche du même OS a une séquence prioritaire → voir Gate de séquence (critère B) ; (2) contrôler la capacité de la TP (sous-emplacement) en plus de celle du PK → voir la note ci-dessous.

Contexte projet

Chaque PK dispose de 3 tables soumises à une contrainte d'adjacence stricte :

TABLE_GAUCHE ←→ TABLE_CENTRE ←→ TABLE_DROITE
     ✅ adjacentes       ✅ adjacentes

TABLE_GAUCHE ←----------------→ TABLE_DROITE
                 ❌ INTERDIT

Règles de mouvement :

  • Le stock est toujours sur une palette, jamais posé directement sur la table
  • L'opérateur peut déplacer du stock (sacs, colis) d'une palette à une autre uniquement entre deux tables adjacentes
  • Il est interdit de déplacer une palette d'une table à une autre - ni par l'opérateur, ni par l'AGV. Une palette arrive sur une table et ne peut que repartir (évacuation)
  • TABLE_CENTRE est le pivot : seule table adjacente aux deux autres

Déclenchement

L'algorithme est appelé à chaque arrivée physique d'une palette au PS. Le PS interroge le WMS qui retourne une réponse parmi :

  • TABLE_GAUCHE, TABLE_CENTRE ou TABLE_DROITE → la palette est envoyée sur cette table
  • Buffer ESx → aucune table n'est disponible, la palette est redirigée vers un emplacement buffer
  • Attente → ni table ni buffer disponible, la palette reste au PS

Entrées de l'algorithme

Donnée Source
Tâche courante : palette source, article, quantité, type de picking (NÉGATIF / DIRECT), Line.CstAtt (séquence) Tâche associée à la palette
État des 3 tables du PK : VIDE, PALETTE_FILLE_ACTIVE, PALETTE_FILLE_EN_ATTENTE, PALETTE_SOURCE_EN_PICKING, PALETTE_SOURCE_EN_ATTENTE, EN_ATTENTE_EVACUATION État temps réel du PK
Tâches suivantes de l'OS (triées par Line.CstAtt croissant) OS en base
Buffers ES disponibles : parmi ES1ES16, ceux non occupés ni ciblés État temps réel des buffers
Nombre de buffers déjà affectés à ce PK vs MAX_PRELOAD_PAR_PK (défaut : 3) Compteur par PK

Décision niveau 1 : table du PK ou buffer ?

FONCTION décider_destination(palette, PK) :

    table_cible ← choisir_table(palette, PK)

    SI table_cible ≠ NULL :
        RETOURNER table_cible

    // Aucune table disponible → tenter un buffer
    SI nb_buffers_affectés(PK) < MAX_PRELOAD_PAR_PK :
        buffer ← premier ES libre
        SI buffer existe :
            RETOURNER buffer

    // Ni table ni buffer disponible
    RETOURNER ATTENTE

[CUSTOM] Capacité TP (LIM-95) : dans tous les flux qui vérifient la capacité du PK, la capacité de la TP (sous-emplacement de la table) doit aussi être contrôlée. Attention : aucun capteur de présence n'est relié à Galileo - la capacité est donc suivie logiquement par le WMS, pas par un signal physique.

Décision niveau 2 : choix de la table

Le choix dépend du type de picking de la tâche associée.

Cas PICKING_NÉGATIF

En picking négatif, la palette source arrive sur une table, l'opérateur retire l'excédent sur une palette posée sur une table adjacente, puis échange d'étiquettes. La palette a besoin de 2 tables : une pour elle, une adjacente libre pour l'excédent.

FONCTION choisir_table_picking_négatif(PK) :

    // Priorité 1 : centre + un côté libre
    SI TABLE_CENTRE == VIDE ET (TABLE_GAUCHE == VIDE
                                OU TABLE_DROITE == VIDE) :
        RETOURNER TABLE_CENTRE

    // Priorité 2 : côté + centre libre
    SI (TABLE_GAUCHE == VIDE OU TABLE_DROITE == VIDE)
       ET TABLE_CENTRE == VIDE :
        RETOURNER côté vide

    // Priorité 3 : centre libre + un côté libérable
    SI TABLE_CENTRE == VIDE ET un côté est libérable :
        évacuer(côté libérable)
        RETOURNER TABLE_CENTRE

    // Priorité 4 : un côté libre + centre libérable
    SI un côté == VIDE ET TABLE_CENTRE est libérable :
        évacuer(TABLE_CENTRE)
        RETOURNER côté vide

    // Dernier recours : évacuation forcée
    évacuer_table_prioritaire(PK)
    RETOURNER choisir_table_picking_négatif(PK)  // rappel

Cas PICKING_DIRECT

La palette source doit être posée sur une table adjacente à la palette fille active. Le choix se fait en fonction de l'emplacement de la palette fille.

FONCTION choisir_table_picking_direct(tâche, PK) :

    // Étape 1 : localiser la palette fille compatible
    table_fille ← localiser_palette_fille(tâche, PK)

    SI table_fille == NULL :
        table_fille ← choisir_table_nouvelle_palette_fille(PK)

    // Étape 2 : choisir une table adjacente
    tables_adj ← tables_adjacentes(table_fille)

    // Prio A : palette source déjà sur une adjacente
    //   (multi-tâches même palette)
    POUR chaque t DANS tables_adj :
        SI t contient tâche.PALETTE_SOURCE :
            RETOURNER t

    // Prio B : adjacente VIDE
    //   Si 2 adjacentes libres (PF au centre) → ping-pong
    adjacentes_vides ← [t POUR t DANS tables_adj SI t == VIDE]
    SI len(adjacentes_vides) == 2 :
        RETOURNER choisir_côté_ping_pong(PK)
    SI len(adjacentes_vides) == 1 :
        RETOURNER adjacentes_vides[0]

    // Prio C : adjacente en cours d'évacuation (AGV en route)
    POUR chaque t DANS tables_adj :
        SI t == EN_ATTENTE_EVACUATION :
            RETOURNER t

    // Prio D : forcer l'évacuation d'une adjacente
    t_à_libérer ← choisir_table_à_évacuer(tables_adj)
    évacuer(t_à_libérer)
    RETOURNER t_à_libérer

Localisation de la palette fille compatible

FONCTION localiser_palette_fille(tâche, PK) :

    // Parmi les PF actives
    POUR chaque table :
        SI table.état == PALETTE_FILLE_ACTIVE :
            RETOURNER table
            // Note : CONTROLE_TRAITEMENT_COMMERCIAL = false,
            // donc pas de filtre TC

    // Puis parmi les PF en attente
    POUR chaque table :
        SI table.état == PALETTE_FILLE_EN_ATTENTE :
            RETOURNER table

    RETOURNER NULL

Choix de table pour une nouvelle palette fille

FONCTION choisir_table_nouvelle_palette_fille(PK) :

    // TABLE_CENTRE = pivot → maximise la flexibilité
    SI TABLE_CENTRE == VIDE : RETOURNER TABLE_CENTRE
    SI TABLE_GAUCHE == VIDE : RETOURNER TABLE_GAUCHE
    SI TABLE_DROITE == VIDE : RETOURNER TABLE_DROITE

    // Aucune table vide → forcer une évacuation
    évacuer_table_prioritaire(PK)
    RETOURNER choisir_table_nouvelle_palette_fille(PK)

Optimisation ping-pong

Le ping-pong est l'optimisation principale pour le débit. Il n'est possible que lorsque la palette fille est au centre : les palettes sources alternent alors entre TABLE_GAUCHE et TABLE_DROITE, de sorte que la palette suivante est déjà en place quand l'opérateur termine.

FONCTION choisir_côté_ping_pong(PK) :

    SI TABLE_GAUCHE.état ∈ {PALETTE_SOURCE_EN_PICKING,
                            PALETTE_SOURCE_EN_ATTENTE} :
        RETOURNER TABLE_DROITE

    SI TABLE_DROITE.état ∈ {PALETTE_SOURCE_EN_PICKING,
                            PALETTE_SOURCE_EN_ATTENTE} :
        RETOURNER TABLE_GAUCHE

    // Aucun côté occupé → choix arbitraire
    RETOURNER TABLE_GAUCHE

Recentrage : si la palette fille est sur un côté (issue d'un picking négatif), le ping-pong est impossible. Si le nombre de PICKING_DIRECT restants ≥ SEUIL_RECENTRAGE_PF (défaut : 3), le WMS peut déclencher un mouvement AGV pour recentrer la PF sur TABLE_CENTRE.

Évacuation des tables - Priorité

Lorsqu'aucune table n'est libre et qu'il faut en libérer une :

FONCTION évacuer_table_prioritaire(PK) :

    // 1. Palette vide → retrait manuel (pas d'AGV)
    // 2. Table déjà en attente d'évacuation → attendre AGV
    // 3. Palette source en attente, non réutilisée par
    //    la prochaine tâche → AGV vers buffer/ASRS
    // 4. Palette fille en attente → AGV vers image de quai
    // 5. Palette source en attente (même si réutilisée)
    //    → AGV vers buffer ES

Gestion des buffers ES → PK

Quand une table se libère au PK, le WMS choisit parmi les palettes en buffer affectées à ce PK :

  • Tri par Line.CstAtt croissant (plus petit = plus prioritaire)
  • La première palette compatible avec la table libérée est envoyée

Règle critique : l'ordre de sortie des buffers est dicté par Line.CstAtt, pas par l'ordre d'arrivée physique en buffer.

[CUSTOM] Capacité buffers PK → PK (LIM-116) : la génération de mouvement depuis le picking (Task_GenerateMovement_PR_V2) contrôle la capacité des buffers lorsqu'une palette va d'un poste de picking à un autre. Les mouvements manuels du poste (appeler / renvoyer, filmage au retour) sont détaillés dans Process picking au PK.

Palettes multi-commandes

Une palette source peut être assignée à plusieurs OS.

Après picking de la commande en cours :

  • Si la palette a encore des tâches pour d'autres OS → marquée MULTI_COMMANDE, envoyée vers un buffer ES libre
  • Elle reste en buffer jusqu'au lancement de l'OS suivant
  • Une palette multi-commande au PK ou en mouvement compte comme une place buffer occupée dans le calcul de MAX_PRELOAD_PAR_PK

Priorité d'accès aux buffers entre PK

Lorsque les buffers ES sont saturés, la priorité est définie par la séquence du mode "Picking" dans MODES_PKxx (voir Modes de travail PK) :

  • Séquence 1 = priorité la plus haute
  • Quand un buffer se libère → affecté en priorité au PK avec la séquence la plus basse parmi ceux qui ont des palettes en attente

Paramètres WMS

Paramètre Description Défaut
MAX_PRELOAD_PAR_PK Nombre max de palettes pré-chargées en buffer ES par PK 3
SEUIL_RECENTRAGE_PF Nombre min de PICKING_DIRECT restants pour recentrer la PF au centre 3
CONTROLE_TRAITEMENT_COMMERCIAL Séparer ou non les articles par TC sur les palettes filles false (V1.1)
MODES_PKxx Modes autorisés + priorité par PK (LIM-69) -
PK_BIGBAG Autorise ou non les big-bags par PK (LIM-70) -

Implémentation définitive (LIM-82)

Cette section reflète le code livré et validé (revue de code du 03/07/2026). Elle prime sur l'algorithme V1.0 ci-dessus en cas d'écart - ce dernier reste documenté comme référence de conception.

Records et workflows

Élément AD Type Rôle
TaskWF Record Ajout d'un CstAtt de tâche (dont CstAtt3, flag « palette passée au shuttle »).
CST_ChooseDestinationFromPS Workflow Décision principale : table de picking (avec choix de la position), buffer ES si aucune place, ou attente au PS s'il n'y a plus de place (selon MAX_PRELOAD_PAR_PK).
Container_MovedEventHandler_PS_PR Workflow À l'arrivée d'une palette de tâche picking au PS, appelle CST_ChooseDestinationFromPS.
Container_MovedEventHandler_ET_PR Workflow Passe CstAtt3 de la tâche à True après que la palette a quitté le shuttle, pour autoriser la sortie des palettes suivantes du TK.
Container_MovedEventHandler_MS_PR Workflow Idem : passe CstAtt3 à True quand une palette atteint TS_12 (sortie du TK_01, qui ne passe pas par le shuttle).
CST_Job_CheckPSBufferContainers Job Ré-évalue les palettes en attente au PS et en buffer : quand une place picking se libère, envoie la bonne palette au picking.

Queries

Query Rôle
CST_Picking_GetSiblingTasks Récupère les tâches de picking du même ordre de sortie (OS).
CST_GetTasksWaitingOnPSAndBufffer Récupère toutes les tâches sans mouvement présentes sur un PS ou un buffer (en attente de picking ou de stage).
CST_GetStationRoutes_ToDisable Récupère les routes à désactiver pour le mouvement PS : route PS → PK, et routes PS → buffer plein.

Gate de séquence (critère B)

Avant toute pose sur une table, le WMS vérifie via CST_Picking_GetSiblingTasks s'il existe une autre palette du même OS avec un Line.CstAtt (séquence, écrit par LIM-84) inférieur encore à traiter en amont (buffer / shuttle). Si oui, la palette qui arrive n'est pas posée sur une table : elle part en buffer ES (ou en attente si buffer indisponible).

Cette règle correspond à la 1re demande de LIM-95 (Annulé, mergé ici) : « le job traite chaque tâche une par une ; si une autre tâche de l'OS a une séquence prioritaire (Task.CstAtt01 plus faible), ne pas générer le mouvement ». Task.CstAtt01 et Line.CstAtt désignent la même séquence de picking (voir ad-customs, CstAtt Tâche 01).

⚠️ Correction revue de code (02→03/07) : le contrôle portait initialement sur les tâches de la route ; il a été ramené au périmètre de l'OS. Vérifier sur la route provoquait un faux blocage quand deux OS d'une même route étaient préparés simultanément sur deux PK différents.

Gating shuttle (CstAtt3)

Le shuttle est le goulot d'ordonnancement entre le TK et les PS. Le flag CstAtt3 de la tâche est mis à True une fois la palette sortie du shuttle (handler ET) ou arrivée à TS_12 pour le TK_01 qui ne passe pas par le shuttle (handler MS). Ce flag conditionne la sortie des palettes suivantes du TK, garantissant l'ordre de passage (cf. ad-customs CstAtt Tâche 03).

Écarts avec l'algorithme V1.0

  • Les états EN_ATTENTE_EVACUATION et la « réactivation » d'une PALETTE_FILLE_EN_ATTENTE sont abandonnés dans LIM-82 (barrés dans la description du ticket). Les priorités V1.0 qui s'y réfèrent (ex. cas picking direct « adjacente en cours d'évacuation ») ne sont donc plus applicables.
  • Picking négatif (critère C) : TABLE_CENTRE libre ET au moins une table de côté adjacente libre → palette source sur TABLE_CENTRE ; sinon buffer ES. Une seule palette négative à la fois par PK.
  • Picking direct (critère D) : table de côté libre adjacente à la PALETTE_FILLE_ACTIVE ; en cas de double disponibilité, TABLE_GAUCHE prioritaire sur TABLE_DROITE ; sinon buffer ES.
  • Les mécanismes SEUIL_RECENTRAGE_PF (recentrage AGV) et CONTROLE_TRAITEMENT_COMMERCIAL proviennent de la spec V1.0 et ne figurent pas dans les critères validés de LIM-82. → ⚠️ À confirmer côté implémentation.

Points d'attention

⚠️ L'implémentation livrée (LIM-82) prime sur l'algorithme V1.0 ci-dessus : voir Implémentation définitive (LIM-82) (états EN_ATTENTE_EVACUATION / réactivation abandonnés, gate de séquence OS, gating shuttle CstAtt3).

⚠️ La contrainte d'adjacence est physique : l'opérateur ne peut pas déplacer de sacs entre TABLE_GAUCHE et TABLE_DROITE directement.

⚠️ Le picking négatif nécessite 2 tables (palette source + adjacente pour l'excédent), ce qui complique la gestion des cas saturés.

⚠️ Le recentrage de la palette fille (AGV) n'est déclenché que si suffisamment de tâches de picking direct restent (≥ SEUIL_RECENTRAGE_PF).

⚠️ L'ordre de sortie des buffers suit Line.CstAtt, pas l'ordre FIFO d'entrée en buffer.

Questions ouvertes

  • Big-bag : comportement attendu si une palette big-bag arrive et qu'aucun PK PK_BIGBAG autorisé n'est disponible (attente dédiée, refus, autre file) ? (question ouverte LIM-82)
  • Confirmer si les mécanismes V1.0 SEUIL_RECENTRAGE_PF (recentrage AGV) et CONTROLE_TRAITEMENT_COMMERCIAL sont réellement implémentés (absents des critères validés LIM-82).
  • LIM-75 est cité comme pré-requis « Mini Job picking négatif » (évaluation du TaskType OrdinaryPicking/NegativePicking) alors qu'il est confirmé Annulé → LIM-82 : clarifier où le TaskType est réellement écrit.

Historique des modifications

Date Auteur Modification
2026-05-12 Arthur Création depuis spec "Logique combinatoire picking - PS vers PK - V1.0"
2026-05-13 Arthur Correction règle déplacement palette (jamais déplacée, ni AGV ni opérateur), ajout jira_ref LIM-82
2026-07-17 Arthur Relecture revue de code LIM-82 (préprod, validée 03/07) : ajout section « Implémentation définitive » (WF CST_ChooseDestinationFromPS, Container_MovedEventHandler_PS/ET/MS_PR, job CST_Job_CheckPSBufferContainers, queries CST_Picking_GetSiblingTasks / CST_GetTasksWaitingOnPSAndBufffer / CST_GetStationRoutes_ToDisable) ; gate de séquence OS (correction route → OS) ; gating shuttle CstAtt3 ; abandon états EN_ATTENTE_EVACUATION + réactivation PF ; statut préprod ; questions big-bag / recentrage / TaskType LIM-75
2026-07-17 Arthur LIM-95 confirmé Annulé(e) → mergé dans LIM-82 (pattern V1/V2, pas de duplication) : note de supersession (chaîne), rattachement des 2 demandes (gate de séquence Task.CstAtt01=Line.CstAtt ; note capacité TP + absence capteurs Galileo), jira_refs/sources/Références
2026-07-20 Arthur Note capacité buffers PK → PK (LIM-116, Task_GenerateMovement_PR_V2) + renvoi vers les mouvements manuels du poste (process-picking-pk.md) ; jira_refs +LIM-116, sources, last_updated, Références

Références

Source Type Date
Logique combinatoire picking - PS vers PK - V1.0 Spécification technique 27/04/2026
LIM-82 Ticket Jira (placement PS → PK, 5 commentaires, préprod) 2026-06 → 07
LIM-84 Ticket Jira (séquençage TK → PS, écrit Line.CstAtt) 2026
LIM-75 Ticket Jira (picking négatif TaskType, Annulé → LIM-82) 2026
LIM-95 Ticket Jira ([JOB] mouvements depuis buffers, Annulé → mergé LIM-82) 2026
LIM-91 Ticket Jira (workflow opérateur au PK) 2026
LIM-116 Ticket Jira (LOT 3, mouvements manuels station picking - capacité buffers PK → PK Task_GenerateMovement_PR_V2) 2026-07
LIM-69 Ticket Jira (modes PK) 2026
LIM-70 Ticket Jira (Mega Job) 2026