11 KiB
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) |
|
draft | concepts/picking.md |
|
|
2026-05-12 | 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.
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 ES1–ES16, 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
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.CstAttcroissant (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.
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) | — |
Points d'attention
⚠️ 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
(Aucune identifiée — algorithme V1.0 complet)
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 |
Références
| Source | Type | Date |
|---|---|---|
| Logique combinatoire picking - PS vers PK - V1.0 | Spécification technique | 27/04/2026 |
| LIM-69 | Ticket Jira (modes PK) | 2026 |
| LIM-70 | Ticket Jira (Mega Job) | 2026 |