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<\n",
opercalc->operation );
fflush(log_fp);
fprintf(log_fp,
"opercalc: numoprattids=%d\n",
opercalc->numoprattids );
fflush(log_fp);
for (i=0;i<opercalc->numoprattids;i++)
{
fprintf(log_fp,
"opercalc: opr attid =>%s<\n"
"opercalc: opr attvalue=>%s<\n",
opercalc->oprattidlist[i]->attid,
opercalc->oprattidlist[i]->attvalue );
fflush(log_fp);
}
fprintf(log_fp,
"opercalc: order=>%s<\n",
opercalc->order );
fflush(log_fp);
fprintf(log_fp,
"opercalc: numordattids=%d\n",
opercalc->numordattids );
fflush(log_fp);
for (i=0;i<opercalc->numordattids;i++)
{
fprintf(log_fp,
"opercalc: ord attid =>%s<\n"
"opercalc: ord attvalue=>%s<\n",
opercalc->ordattidlist[i]->attid,
opercalc->ordattidlist[i]->attvalue );
fflush(log_fp);
}
fprintf(log_fp,
"opercalc: part=>%s<\n",
opercalc->part );
fflush(log_fp);
fprintf(log_fp,
"opercalc: numprtattids=%d\n",
opercalc->numprtattids );
fflush(log_fp);
for (i=0;i<opercalc->numprtattids;i++)
{
fprintf(log_fp,
"opercalc: prt attid =>%s<\n"
"opercalc: prt attvalue=>%s<\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<\n",
opercalc->startwindow );
fflush(log_fp);
fprintf(log_fp,
"opercalc: end=>%s<\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<opercalc->numresources;i++)
{
fprintf(log_fp,
"opercalc: resource=>%s<\n",
opercalc->resourcelist[i]->resource );
fflush(log_fp);
fprintf(log_fp,
"opercalc: category=>%s<\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<opercalc->resourcelist[i]->numresattids;j++)
{
fprintf(log_fp,
"opercalc: res attid =>%s<\n"
"opercalc: res attvalue=>%s<\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<\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.