Ecriture d'un calcul d'opération personnalisé

Vous pouvez écrire une routine C personnalisée pour permettre à APS de calculer la durée des opérations sélectionnées. Le système appelle votre routine de calcul personnalisée si le champ Règle de planif. de l'opération est sélectionné.

A propos de la routine de calcul d'opération standard

La routine de calcul d'opération standard est ol_opercalc. Par défaut, elle renvoie la valeur -1,0, qui indique à l'algorithme d'utiliser le calcul standard (c'est-à-dire non personnalisé) pour déterminer la durée de l'opération. Le code C de cette routine est indiqué ci-dessous.


#include "ol_api.h"
double
ol_opercalc(opercalc)
opercalc_s* opercalc;
{
return(-1.0);
}

Entrée dans la routine standard

L'entrée dans ol_opercalc est un pointeur désignant une structure opercalc_s. Comme indiqué ci-dessous, cette structure contient des informations utilisées pour calculer la durée de l'opération.


/*------------------------------------------------------------------------*/
typedef struct attid_struct
/*------------------------------------------------------------------------*/
{
 char                   attid[MAX_OLXFSTR+1];
 char                           attvalue[MAX_OLXFSTR+1];
}
attid_s;
/*------------------------------------------------------------------------*/
typedef struct reslist_struct
/*------------------------------------------------------------------------*/
{
 char                   resource[MAX_OLXFSTR+1];
 char                   category[MAX_OLXFSTR+1];
 double                 catbufpre;
 double                 catbufpost;
 long                   numresattids;
 attid_s**      resattidlist;
}
reslist_s;
/*------------------------------------------------------------------------*/
typedef struct opercalc_struct
/*------------------------------------------------------------------------*/
{
 char                                   operation[MAX_OLXFSTR+1];
 char                           order[MAX_OLXFSTR+1];
 char                           part[MAX_OLXFSTR+1];
 double                         quantity;
 char                           startwindow[14];
 char                           endwindow[14];
 long                           oprflags;
 double                         oprsetup;
 double                         oprcycle;
 double                         oprbufpre;
 double                         oprbufpost;
 long                           oprovltype;
 double                         oprovlvalue;
 long                                   matltag;
 long                           numresources;
 reslist_s**    resourcelist;
 long                           numoprattids;
 attid_s**              oprattidlist;
 long                           numordattids;
 attid_s**              ordattidlist;
 long                           numprtattids;
 attid_s**              prtattidlist;
}
opercalc_s;

Sortie de la routine standard

Il existe deux types de sorties de ol_opercalc :

  • La valeur de retour de la fonction. La valeur de retour attendue de ol_opercalc est la durée totale de l'opération en heures (comme type double) ou la valeur -1,0 (ou une valeur négative quelconque). Une valeur négative indique au système d'utiliser le calcul d'opération standard (non personnalisée).
  • Un ensemble de trois paramètres. Ces paramètres font partie de la structure opercalc_s :
    • oprsetup - Temps de réglage de l'opération (heures)
    • oprovltype - Type de chevauchement d'opération
    • oprovlvalue - Valeur de chevauchement d'opération

Lorsque l'algorithme transmet ces paramètres à ol_opercalc, ceux-ci contiennent les valeurs définies par l'utilisateur issues de la base de données. Vous pouvez les modifier dans ol_opercalc avant de les renvoyer à l'algorithme. S'ils sont modifiés, le système répond comme suit :

  • oprsetup - Le temps de réglage sera modifié pour cette opération.
  • oprovltype - Le chevauchement sera recalculé pour cette opération.
  • oprovlvalue - Le chevauchement sera recalculé pour cette opération.

Vous pouvez activer le chevauchement d'opération par l'intermédiaire de la valeur de base de données d'origine ou en modifiant oprovltype. S'il est activé et si oprsetup est modifié et/ou si la valeur de retour ol_opercalc indique qu'une autre valeur oprcycle est en vigueur (compte tenu du réglage des champs Hres fixes jalonnées et Règle de planif. de l'opération), le système recalcule le chevauchement pour cette opération.

Ecriture de votre routine personnalisée

Lorsque vous écrivez votre routine, assurez-vous que la valeur de retour est de type double. Cette valeur doit représenter la durée totale requise de l'opération (en heures), pour le nombre indiqué de pièces utilisant les ressources indiquées, au cours de l'intervalle de temps disponible pour la fabrication.

L'exemple suivant de routine ol_opercalc détermine la durée de l'opération pour une ressource particulière.


#include "ol_api.h"
double
ol_opercalc(opercalc)
opercalc_s* opercalc;
{
    FILE* log_fp;
    int i,j;
 double dTime;
   log_fp = fopen("d:\\opercalc50.txt","a");
  fprintf(log_fp,
                "\nopercalc:  oper=>%s&LT\n",
                opercalc->operation );
        fflush(log_fp);
  fprintf(log_fp,
                "opercalc:  numoprattids=%d\n",
                opercalc->numoprattids );
        fflush(log_fp);
  for (i=0;i&LTopercalc->numoprattids;i++)
        {
   fprintf(log_fp,
    "opercalc:  opr attid   =>%s&LT\n"
    "opercalc:  opr attvalue=>%s&LT\n",
                opercalc->oprattidlist[i]->attid,
    opercalc->oprattidlist[i]->attvalue );
            fflush(log_fp);
        }
  fprintf(log_fp,
                "opercalc:  order=>%s&LT\n",
                opercalc->order );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  numordattids=%d\n",
                opercalc->numordattids );
        fflush(log_fp);
  for (i=0;i&LTopercalc->numordattids;i++)
        {
   fprintf(log_fp,
                "opercalc:  ord attid   =>%s&LT\n"
    "opercalc:  ord attvalue=>%s&LT\n",
                opercalc->ordattidlist[i]->attid,
    opercalc->ordattidlist[i]->attvalue );
            fflush(log_fp);
        }
  fprintf(log_fp,
                "opercalc:  part=>%s&LT\n",
                opercalc->part );
        fflush(log_fp);
  fprintf(log_fp,
                "opercalc:  numprtattids=%d\n",
                opercalc->numprtattids );
        fflush(log_fp);
  for (i=0;i&LTopercalc->numprtattids;i++)
        {
   fprintf(log_fp,
          "opercalc:  prt attid   =>%s&LT\n"
    "opercalc:  prt attvalue=>%s&LT\n",
                opercalc->prtattidlist[i]->attid,
    opercalc->prtattidlist[i]->attvalue );
            fflush(log_fp);
        }
        fprintf(log_fp,
                "opercalc:  quantity=%f\n",
                opercalc->quantity );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  start=>%s&LT\n",
                opercalc->startwindow );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  end=>%s&LT\n",
                opercalc->endwindow );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  oprflags=%d\n",
                opercalc->oprflags );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  oprsetup=%f\n",
                opercalc->oprsetup );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  oprcycle=%f\n",
                opercalc->oprcycle );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  oprbufpre=%f\n",
                opercalc->oprbufpre );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  oprbufpost=%f\n",
                opercalc->oprbufpost );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  oprovltype=%d\n",
                opercalc->oprovltype );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  oprovlvalue=%f\n",
                opercalc->oprovlvalue );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  numresources=%d\n",
                opercalc->numresources );
        fflush(log_fp);
  for (i=0;i&LTopercalc->numresources;i++)
        {
   fprintf(log_fp,
                "opercalc:  resource=>%s&LT\n",
                opercalc->resourcelist[i]->resource );
            fflush(log_fp);
   fprintf(log_fp,
                "opercalc:  category=>%s&LT\n",
                opercalc->resourcelist[i]->category );
            fflush(log_fp);
            fprintf(log_fp,
                    "opercalc:  catbufpre=%f\n",
                    opercalc->resourcelist[i]->catbufpre );
            fflush(log_fp);
            fprintf(log_fp,
                    "opercalc:  catbufpost=%f\n",
                    opercalc->resourcelist[i]->catbufpost );
            fflush(log_fp);
      fprintf(log_fp,
                    "opercalc:  numresattids=%d\n",
                    opercalc->resourcelist[i]->numresattids );
            fflush(log_fp);
      for (j=0;j&LTopercalc->resourcelist[i]->numresattids;j++)
            {
       fprintf(log_fp,
        "opercalc:  res attid   =>%s&LT\n"
        "opercalc:  res attvalue=>%s&LT\n",
                    opercalc->resourcelist[i]->resattidlist[j]->attid,
        opercalc->resourcelist[i]->resattidlist[j]->attvalue );
                fflush(log_fp);
            }
        }
  dTime = -1.0;
  if ( (!strcmp(opercalc->part,"SA-50910")) &&
    (!strcmp(opercalc->operation,
             "SA-50910                      SA-5.20")) &&
    (!strcmp(opercalc->resourcelist[0]->resource,"PNT10.1")) )
  {
   if ( opercalc->oprflags == 2 )
            {
    fprintf(log_fp, "opercalc:  per cycle\n");
    fflush(log_fp);
    if ( opercalc->quantity > 10.0 )
    {
        opercalc->oprsetup = 0.15;
     fprintf(log_fp, "opercalc:  changing oprsetup\n");
     opercalc->oprcycle = 0.25;
     fprintf(log_fp, "opercalc:  changing oprcycle\n");
     opercalc->oprovltype = 1;
     fprintf(log_fp, "opercalc:  changing oprovltype\n");
     opercalc->oprovlvalue = opercalc->quantity / 2;
     fprintf(log_fp, "opercalc:  changing oprovlvalue\n");
     opercalc->oprbufpre = opercalc->quantity / 2;
     fprintf(log_fp, "opercalc:  changing oprbufpre to qty/2=%f\n",
                        opercalc->oprbufpre);
     opercalc->oprbufpost = opercalc->quantity / 4;
     fprintf(log_fp, "opercalc:  changing oprbufpost to qty/4=%f\n",
                        opercalc->oprbufpost);
//     dTime = opercalc->oprcycle * opercalc->quantity;
     fflush(log_fp);
    }
            }
   else
            {
    fprintf(log_fp, "opercalc:  per load\n");
    fflush(log_fp);
    dTime = 1.0;
                /* opercalc->oprsetup = 0.0;
                opercalc->oprcycle = 0.1;
                opercalc->oprovltype = 1;
                opercalc->oprovlvalue = 3.0; */
            }
  }
  fprintf(log_fp, "opercalc:  dTime = >%f&LT\n", dTime );
        fflush(log_fp);
  fclose(log_fp);
  return(dTime);
}

Création de la DLL Opercalc

Reportez-vous à la rubrique Création de la DLL Opercalc pour la routine de calcul de l'opération personnalisée.

Appel de votre routine personnalisée

Lorsque la planification APS est exécutée, elle n'utilise votre routine personnalisée que si le champ JOBSTEP.STEPTMRL de l'opération a la valeur 2 (Règle de planif. sélectionnée, Hres fixes jalonnées contenant une valeur) ou 3 (Règle de planif. sélectionnée, Hres fixes jalonnées vide ou contenant 0). Toute opération avec 2 comme valeur STEPTMRL utilise un cycle fixe ; la valeur 3 dénote un cycle par pièce.

Si le champ Règle de planif. de l'opération n'est pas activé, le système n'appelle pas la routine ol_opercalc.