Escribir un cálculo de operación personalizada
Acerca de la rutina de cálculo de operaciones estándar
La rutina de cálculo de operaciones estándar es ol_opercalc. De forma predeterminada, devuelve el valor -1,0, lo que señala el algoritmo que va a usar el cálculo estándar (es decir, no personalizado) para determinar la duración de la operación. A continuación se muestra el código C de esta rutina.
#include "ol_api.h"
double
ol_opercalc(opercalc)
opercalc_s* opercalc;
{
return(-1.0);
}
Entrada en la rutina estándar
La entrada a ol_opercalc señala a una estructura opercalc_s. Tal y como se muestra a continuación, esta estructura contiene información que se utiliza para calcular la duración de la operación.
/*------------------------------------------------------------------------*/
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;
Salida de la rutina estándar
Existen dos tipos de salida de ol_opercalc:
- El valor de retorno de la función. El valor de retorno esperado de ol_opercalc puede ser el total de la duración de la operación en horas (como tipo Double) o el valor -1,0 (o cualquier valor negativo). Un valor negativo indica al sistema que utilice el cálculo de operación estándar (no personalizado).
- Un conjunto de tres parámetros. Estos parámetros son parte de la estructura opercalc_s:
- oprsetup - Tiempo de configuración de la operación (horas)
- oprovltype - Tipo de superposición de la operación
- oprovlvalue - Valor de superposición de la operación
Cuando el algoritmo transfiere estos parámetros a ol_opercalc, los parámetros contienen los valores especificados por el usuario de la base de datos. Puede modificarlos en ol_opercalc antes de devolverlos al algoritmo. Si se modifican, el sistema responderá de la siguiente forma:
- oprsetup - Cambiará el tiempo de configuración de esta operación.
- oprovltype - Se volverá a calcular la compensación de superposición de esta operación.
- oprovlvalue - Se volverá a calcular la compensación de superposición de esta operación.
Puede activar la superposición de operaciones a través del valor original de la base de datos o mediante la modificación de oprovltype. Si se activa, y si se modifica oprsetup y el valor de retorno de ol_opercalc denota que hay en vigor un valor de oprcycle diferente (teniendo en cuenta la configuración de los campos Horas fijas de programa y Regla del planificador personalizada), el sistema volverá a calcular la compensación de superposición de esta operación.
Escribir una rutina personalizada
Cuando escriba su rutina, asegúrese de que el valor de retorno es de tipo Double. El valor de retorno debe representar el total de la duración de la operación necesario (en horas) para el número especificado de piezas mediante los recursos especificados y durante el intervalo de tiempo disponible para la producción.
La siguiente rutina ol_opercalc de ejemplo determina el tiempo de operación de un recurso concreto.
#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);
}
Creación de Opercalc.dll
Consulte Creación de Opercalc DLL para la rutina de cálculo de operación personalizada.
Invocación de la rutina personalizada
Cuando se ejecuta APS, solo utiliza la rutina personalizada si el campo JOBSTEP.STEPTMRL de la operación está establecido en 2 (Regla de planificador personalizada seleccionado, Horas fijas de programa contiene un valor) o 3 (Regla de planificador personalizada seleccionado, Horas fijas de programa está en blanco o tiene un valor 0). Una operación con un valor STEPMRL de 2 utiliza un tiempo de ciclo fijo; un valor de 3 utiliza un tiempo de ciclo por pieza.
Si se borra la Regla de planificador personalizada de la operación, el sistema no podrá llamar a la rutina ol_opercalc personalizada.