Files
mcp-wms-wiki/wiki/sources/archives/Logique combinatoire picking - TK vers PS - V1.1.md
2026-05-20 09:41:27 +02:00

18 KiB
Raw Permalink Blame History

LIM-84 — Algorithme de séquençage des palettes (TK → PS)

Ordonnancement des tâches de picking avant sortie de l'ASRS

Version 1.1 — 11 mai 2026

Ce document décrit l'algorithme de séquençage qui définit dans quel ordre les palettes sources doivent sortir de l'ASRS (TK) à destination du poste de sortie (PS). Il s'exécute en amont de l'algorithme de placement PS → table PK Logique combinatoire picking - PS vers PK - V1.0.

Le résultat de cet algorithme est l'écriture des numéros de séquence Line.CstAtt sur chaque tâche de picking, et le positionnement de OS.CstAtt = true pour autoriser le stacker_crane à consommer les tâches.

Changelog V1.1 (11/05/2026)

Modifications issues de la réunion Arthur + Justine (MECALUX) — Olivier (LIMAGRAIN), croisées avec l'AF et le DevOps #64854.

  • Hiérarchie des règles : nouvel ordre de priorité validé (§3). La complétude palette et l'anti-split de lignes de stock sont désormais des contraintes amont prioritaires sur les règles de tri.
  • Picking négatif : ajout d'une condition cumulative de poids ≥ 7 kg (§3.1 + §6.3).
  • Traitement commercial : critère de regroupement par TC supprimé (CONTROLE_TRAITEMENT_COMMERCIAL = false). Le critère 3 de la V1.0 est retiré du tri.
  • Calcul de remplissage : méthode pro rata Bag/pal validée, remplace la logique DevOps "Bag/pal max" (§3 — contrainte amont C1).
  • Poids max palette : 1 250 kg (l'AF fait foi, corrige les 1 200 kg du DevOps).
  • Règles confirmées : mélange d'espèces OK, pas de gerbage, hauteur max 1,90 m, séparateurs inter-lots hors WMS.

0. Glossaire rapide

Terme Définition
TK Transtockeur / sortie ASRS (origine physique de la palette)
PS Poste de sortie (point d'arrivée de la palette, avant placement sur table PK)
OS Ordre de sortie (commande)
OS.CstAtt Flag booléen sur l'OS. false = séquences non calculées, stacker_crane ignore. true = séquences prêtes, stacker_crane peut consommer.
Line.CstAtt Numéro de séquence (entier) sur chaque tâche de picking. Définit l'ordre de sortie ASRS. Plusieurs tâches peuvent partager la même valeur (ex-aequo).
TC Traitement commercial — attribut article. Supprimé V1.1 : CONTROLE_TRAITEMENT_COMMERCIAL = false. L'entrepôt ne fait pas de bio. Paramètre réactivable si besoin futur.
Bag/pal Nombre de sacs par palette pour un lot donné. Sert au calcul de remplissage pro rata.

1. Déclenchement

L'algorithme est déclenché sur deux événements :

1.1. TaskCreatedEvent

Une nouvelle tâche de picking vient d'être créée (par le MINI JOB Picking LIM-75, ou suite à une réassignation de stock).

SI événement.type == TaskCreatedEvent :
    SI tâche.type == PICKING ET tâche.OS.statut == Released :
        traiter_séquençage(tâche.OS)

1.2. OutboundOrderReleasedEvent

Un OS passe au statut Released (première mise en service, ou relance après un arrêt).

SI événement.type == OutboundOrderReleasedEvent :
    traiter_séquençage(OS)

2. Process principal

FONCTION traiter_séquençage(OS) :

    // ─── Étape 1 : verrouiller l'OS ───
    OS.CstAtt ← false

    // ─── Étape 2 : récupérer les tâches ───
    toutes_tâches ← récupérer_tâches_picking(OS)

    // ─── Étape 3 : filtrer ───
    tâches_à_séquencer ← [t POUR t DANS toutes_tâches SI t.statut == EN_ATTENTE]

    SI tâches_à_séquencer est vide :
        OS.CstAtt ← true
        RETOURNER

    // ─── Étape 4 : trier ───
    tâches_triées ← trier_tâches(tâches_à_séquencer)   // cf. §3

    // ─── Étape 5 : écrire les séquences ───
    écrire_séquences(tâches_triées)                      // cf. §4

    // ─── Étape 6 : libérer l'OS ───
    OS.CstAtt ← true

3. Contraintes amont et règles de tri

V1.1 — La hiérarchie ci-dessous remplace toute hiérarchie antérieure. Elle distingue les contraintes amont (appliquées avant/pendant la constitution des palettes filles) et les règles de tri (appliquées au séquençage des tâches de picking).

Contraintes amont (constitution des palettes filles)

Ces contraintes orientent le regroupement des lignes sur les palettes filles avant que l'algorithme de tri ne séquence les sorties ASRS. Elles ne sont pas des critères de tri à proprement parler, mais l'algorithme de séquençage doit les respecter : l'ordre de sortie doit être compatible avec la constitution de palettes conformes à ces règles.

C1. Palettes les plus complètes possible

Objectif premier — optimisation transport. Seuil de remplissage ~95% (marge de sécurité).

Calcul : pro rata Bag/pal. Chaque sac consomme 1/Bag_pal de son lot. Le calcul est additif et gère nativement des lots avec des Bag/pal différents sur une même palette.

Exemple :
  16 sacs d'un lot Bag/pal 20 + 7 sacs d'un lot Bag/pal 50
  = 16/20 + 7/50
  = 0,80 + 0,14
  = 94%

Regrouper les lots de même Bag/pal sur une même palette fille facilite la complétude.

Note : cette méthode remplace la logique DevOps #64854 de "prendre le Bag/pal max entre lots" (V1.0 implicite). Le pro rata est plus précis et ne nécessite pas de Bag/pal de référence unique.

C2. Ne pas splitter les lignes de stock

Éviter de répartir les sacs d'une même ligne de stock sur plusieurs palettes. Cette contrainte est prioritaire sur les règles de tri : si respecter "Maïs first" implique de splitter une ligne, on regroupe la ligne complète quitte à décaler le maïs.

Autres contraintes palette

Contrainte Valeur Source
Poids max palette 1 250 kg AF (corrige 1 200 kg du DevOps)
Hauteur max palette 1,90 m AF — rejet au PIE si dépassement
Gerbage Interdit
Mélange d'espèces Autorisé sur une même palette fille
Différenciation de marque Aucune dans une même expédition
Séparateurs (intercalaires) entre lots Règle opérateur, hors WMS

Règles de tri (séquençage des sorties ASRS)

Les tâches de picking d'un même OS sont triées selon les critères suivants, par ordre de priorité décroissante :

3.1. Critère 1 — Picking négatif en premier

Les tâches de type PICKING_NÉGATIF passent avant les tâches de type PICKING_DIRECT.

Le picking négatif est prioritaire sur toutes les règles de tri suivantes, y compris Maïs first : si une tâche négatif concerne du tournesol, elle passe avant une tâche maïs classique.

V1.1 — Condition cumulative ajoutée pour la détermination NÉGATIF/DIRECT (cf. §6.3) : pourcentage quantité > seuil fiche article (défaut 55%) ET poids unitaire sac ≥ 7 kg. En dessous de 7 kg, pas de picking négatif (raison : instabilité palette si gros sacs ramenés sur petits sacs).

tri_1(tâche) → 0 si PICKING_NÉGATIF, 1 si PICKING_DIRECT

3.2. Critère 2 — Espèce Maïs en premier

Les tâches portant sur l'espèce Maïs passent avant les autres espèces (si la commande contient du maïs).

Raison : le maïs est lourd/stable, il constitue la base de la palette fille.

tri_2(tâche) → 0 si espèce == MAÏS, 1 sinon

3.3. Critère 3 — Regroupement par traitement commercial (TC) SUPPRIMÉ V1.1

CONTROLE_TRAITEMENT_COMMERCIAL = false. L'entrepôt ne fait pas de bio. Réactivable si besoin futur.

3.3. Critère 3 — Espèce avec la plus grande quantité totale dans la commande

(anciennement critère 4 en V1.0)

Les tâches sont regroupées par espèce, et l'espèce ayant la plus grande quantité totale de sacs dans l'OS passe en premier.

Raison : commencer par l'espèce la plus volumineuse permet de constituer rapidement la base de la palette fille.

tri_3(tâche) → -quantité_totale_espèce(tâche.espèce, OS)
               // négatif pour tri décroissant

3.4. Critère 4 — Article/lot le plus lourd en base

(anciennement critère 5 en V1.0)

À espèce égale, les tâches portant sur les articles/lots les plus lourds passent en premier.

Corollaire : les semences essais, très légères, se retrouvent naturellement en haut de palette.

tri_4(tâche) → -tâche.article.poids
               // négatif pour tri décroissant

3.5. Critère 5 — Regroupement par palette source

(anciennement critère 6 en V1.0)

Toutes les tâches portant sur la même palette source sont consécutives.

Raison : l'opérateur enchaîne toutes les tâches d'une palette source avant de la libérer.

tri_5(tâche) → tâche.PALETTE_SOURCE.identifiant

Récapitulatif du tri multi-critères (V1.1)

FONCTION trier_tâches(tâches) :

    RETOURNER tâches.trier_par(
        (1) type_picking        ASC    // NÉGATIF (0) avant DIRECT (1)
        (2) espèce_maïs        ASC    // MAÏS (0) avant autres (1)
        (3) quantité_espèce    DESC   // espèce la + volumineuse en premier
        (4) poids_article      DESC   // article le + lourd en premier
        (5) palette_source            // regroupement par palette source
    )

    // Note V1.1 : le critère TC (V1.0 §3.3) est supprimé.
    // La contrainte anti-split lignes de stock (C2) est gérée
    // en amont lors de la constitution des palettes filles,
    // pas dans ce tri.

4. Écriture des séquences (Line.CstAtt)

Une fois les tâches triées, on attribue un numéro de séquence à chacune.

4.1. Règle des ex-aequo

Quand deux tâches consécutives dans le tri sont interchangeables (l'ordre entre elles n'a aucun impact fonctionnel), elles reçoivent le même numéro de séquence. Cela laisse de la flexibilité au stacker_crane pour optimiser son débit.

4.2. Critères d'interchangeabilité

Deux tâches A et B sont interchangeables si :

  • Elles portent sur la même palette source, OU
  • Elles portent sur des palettes sources différentes mais tous les critères de tri sont identiques : même type de picking, même espèce, même quantité espèce, même poids article. Rien ne les départage fonctionnellement.

Note V1.1 : le TC n'entre plus dans les critères d'interchangeabilité.

4.3. Algorithme d'écriture

FONCTION écrire_séquences(tâches_triées) :

    séquence_actuelle ← max(Line.CstAtt des tâches en cours) + 1
    SI aucune tâche en cours :
        séquence_actuelle ← 1

    POUR i DE 0 À len(tâches_triées) - 1 :

        tâche ← tâches_triées[i]
        tâche.Line.CstAtt ← séquence_actuelle

        SI i < len(tâches_triées) - 1 :
            tâche_suivante ← tâches_triées[i + 1]

            SI interchangeables(tâche, tâche_suivante) :
                CONTINUER
            SINON :
                séquence_actuelle ← séquence_actuelle + 1

4.4. Exemple

Commande avec 5 tâches, après tri :

    Tâche 1 : Palette A, Maïs,  500kg  →  séq 1
    Tâche 2 : Palette B, Maïs,  500kg  →  séq 1  (interchangeable avec 1)
    Tâche 3 : Palette C, Maïs,  500kg  →  séq 1  (interchangeable)
    Tâche 4 : Palette D, Blé,   300kg  →  séq 2  (espèce différente)
    Tâche 5 : Palette E, Blé,   300kg  →  séq 2  (interchangeable avec 4)

Résultat Line.CstAtt : [1, 1, 1, 2, 2]

Le stacker_crane peut sortir les palettes A, B, C dans n'importe quel ordre,
puis D ou E dans n'importe quel ordre.

Note V1.1 : l'exemple V1.0 avec TC différent (tâche 6) est retiré car le critère TC est désactivé.


5. Comportement du stacker_crane après séquençage

Ce n'est pas le périmètre de cet algorithme, mais pour mémoire :

Le stacker_crane :
    - IGNORE les tâches dont OS.CstAtt == false
    - Consomme les tâches dont OS.CstAtt == true
    - Respecte l'ordre croissant des Line.CstAtt
    - Entre tâches à séquence égale : libre d'optimiser (proximité ASRS, charge TK)
    - Crée les tâches de mouvement TK → PS

Les palettes arrivent ensuite au PS, où l'algorithme de placement (document dédié) décide sur quelle table du PK les poser.


6. Cas particuliers

6.1. Recalcul suite à une nouvelle tâche (réassignation de stock)

Si une tâche est créée après que l'OS a déjà été séquencé, le TaskCreatedEvent déclenche un recalcul :

1. OS.CstAtt ← false
2. Filtrer : tâches EN_ATTENTE uniquement
3. Re-trier et réécrire les Line.CstAtt
   (en commençant après le dernier numéro des tâches en cours)
4. OS.CstAtt ← true

6.2. Relance d'un OS arrêté

Si un OS est arrêté puis relancé (OutboundOrderReleasedEvent), le même process s'applique. Les tâches déjà en cours conservent leur séquence, les tâches en attente sont re-séquencées.

6.3. Picking négatif et détermination du type

Le type de picking (NÉGATIF ou DIRECT) est déterminé par tâche au moment de la création des tâches par le MINI JOB Picking (LIM-75), selon la règle :

SI quantité_à_prélever > seuil_article × quantité_palette_source
   ET article unique dans la palette source
   ET pas d'attribut logistique à capturer
   ET poids_unitaire_sac ≥ 7 kg                          // ← AJOUT V1.1
ALORS → PICKING_NÉGATIF
SINON → PICKING_DIRECT

V1.1 — La condition de poids ≥ 7 kg est ajoutée comme condition cumulative (ET). En dessous de 7 kg, pas de picking négatif même si le % dépasse le seuil. Raison : instabilité palette (gros sacs ramenés sur petits sacs).

Le seuil % reste paramétrable par fiche article (champ "Complete quantity percent excess for negative picking", défaut : 55%).

La détermination négatif/direct se fait en amont (MINI JOB Picking, LIM-75), avant l'algorithme de séquençage. L'algorithme de séquençage lit ce type mais ne le calcule pas.


7. Paramètres WMS utilisés

Paramètre Description Défaut Statut V1.1
CONTROLE_TRAITEMENT_COMMERCIAL Active le regroupement par TC dans le tri true false — désactivé
Seuil picking négatif Par fiche article ("Complete quantity percent excess for negative picking") 55% Inchangé
Poids min picking négatif Poids unitaire sac minimum pour autoriser le picking négatif 7 kg NOUVEAU V1.1
Seuil remplissage palette Taux cible de remplissage palette fille ~95% NOUVEAU V1.1
Poids max palette Poids maximum d'une palette fille 1 250 kg Corrigé (était 1 200 kg dans DevOps)

8. Diagramme de flux

    TaskCreatedEvent                OutboundOrderReleasedEvent
    (nouvelle tâche picking)        (OS passe en Released)
            │                               │
            ▼                               │
    Tâche type PICKING                      │
    ET OS statut Released ?                 │
            │                               │
         OUI                                │
            │                               │
            └──────────┬────────────────────┘
                       │
                       ▼
              OS.CstAtt ← false
              (stacker_crane bloqué)
                       │
                       ▼
              Récupérer tâches de l'OS
                       │
                       ▼
              Filtrer : tâches EN_ATTENTE uniquement
              (tâches en cours = intouchables)
                       │
                       ▼
              ┌────────────────────────────┐
              │         TRIER              │
              │                            │
              │  1. Picking négatif first  │
              │  2. Espèce Maïs first      │
              │  3. Espèce + volumineuse   │
              │  4. Article + lourd        │
              │  5. Regrouper par palette  │
              │         source             │
              └────────────┬───────────────┘
                           │
                           ▼
              Écrire Line.CstAtt
              (ex-aequo si interchangeables)
                           │
                           ▼
              OS.CstAtt ← true
              (stacker_crane libéré)
                           │
                           ▼
              Stacker_crane consomme
              par Line.CstAtt croissant
              → crée mouvements TK → PS
                           │
                           ▼
              Palette arrive au PS
              → algo de placement PS → PK
              (autre document)

9. Points non traités (hors scope)

  • Affichage opérateur au PK (combien de sacs ajouter, possibilité de dévier de la consigne) — à traiter une fois les fondations posées.
  • Picking négatif < 7 kg en option (avantage opérationnel sans obligation) — nécessite discussion élargie.
  • Messagerie carton (moins prioritaire que prépa classique, navette du lendemain, zone angle Est) — en attente de précisions.
  • Verrou réception → recomptage avant picking (mentionné dans l'AF uniquement, non reconfirmé).

10. Sources de référence

Par ordre de fiabilité décroissante :

  1. Réunion 11/05/2026 + mails — fait foi sur tous les points traités
  2. AF (Analyse Fonctionnelle) — référence principale pour les points non abordés en réunion
  3. DevOps #64854 — le plus ancien, peut contenir des règles passées à la trappe mais utile pour vérification croisée