Laboratorio 1 · Semáforos
Célula FMS: prensa, CNC y robot
Una célula de fabricación flexible: las piezas llegan a la posición de entrada, un robot las lleva a la prensa (estampado), luego al CNC (mecanizado) y finalmente a la salida. Cuatro hilos gobiernan las cuatro posiciones y el robot es región crítica. Es el ejercicio ej24 del cuaderno SCTR, ejecutable.
Qué observar
- Cómo
hPrensaqueda bloqueado enwait(scEntradaPrensa)hasta quehEntradahacesignaltras depositar la pieza. - Cómo los hilos se turnan en
wait(sRobot): nunca dos transferencias a la vez. - Cómo
spEntradaPrensaimpide quehEntradaintente dejar una pieza si la prensa aún no ha terminado y soltado su hueco.
Pulsa Ejecutar y usa Paso para avanzar instrucción a instrucción.
Mapa semáforo → significado
| Semáforo | Inicial | Una unidad significa… |
|---|---|---|
spEntradaPrensa | 1 | la prensa tiene su hueco libre |
scEntradaPrensa | 0 | hay pieza esperando en la prensa |
spPrensaCNC | 1 | el CNC tiene su hueco libre |
scPrensaCNC | 0 | hay pieza esperando en el CNC |
spCNCSalida | 1 | la posición de salida está libre |
scCNCSalida | 0 | hay pieza terminada en la salida |
sRobot | 1 | el robot está disponible |
Qué línea produce qué efecto
| Línea | Efecto en la planta |
|---|---|
| hEntrada:4 wait(spEntradaPrensa) | La entrada se detiene si la prensa está ocupada. |
| hEntrada:5 wait(sRobot) | Solicita el robot; si otro hilo lo usa, espera. |
| hEntrada:6–7 coge/deja | El brazo gira de la entrada a la prensa con la pieza. |
| hEntrada:9 signal(scEntradaPrensa) | Despierta a hPrensa: empieza el estampado. |
| hPrensa:4 estampa() | La prensa trabaja durante varios ticks. |
| hPrensa:10 signal(spEntradaPrensa) | Libera la prensa: hEntrada puede traer la siguiente pieza. |
| hCNC:4 mecaniza() | El CNC trabaja la pieza. |
| hSalida:4 while(barrera_salida()) | Espera a que el operario retire la pieza terminada. |
Código C++20 equivalente
#include <semaphore>
#include <thread>
#include <mutex>
std::binary_semaphore spEntradaPrensa(1), scEntradaPrensa(0);
std::binary_semaphore spPrensaCNC(1), scPrensaCNC(0);
std::binary_semaphore spCNCSalida(1), scCNCSalida(0);
std::binary_semaphore sRobot(1); // robot: región crítica
void hEntrada() {
while (true) {
esperarPiezaEnEntrada(); // sensor / barrera óptica
spEntradaPrensa.acquire();
sRobot.acquire();
coge(100, 0); deja(0, 100);
sRobot.release();
scEntradaPrensa.release();
}
}
void hPrensa() {
while (true) {
scEntradaPrensa.acquire();
estampa();
spPrensaCNC.acquire();
sRobot.acquire();
coge(0, 100); deja(-100, 0);
sRobot.release();
spEntradaPrensa.release();
scPrensaCNC.release();
}
}
void hCNC() {
while (true) {
scPrensaCNC.acquire();
mecaniza();
spCNCSalida.acquire();
sRobot.acquire();
coge(-100, 0); deja(0, -100);
sRobot.release();
spPrensaCNC.release();
scCNCSalida.release();
}
}
void hSalida() {
while (true) {
scCNCSalida.acquire();
while (piezaEnSalida()) // el operario debe retirarla
std::this_thread::yield();
spCNCSalida.release();
}
}
int main() {
std::jthread t1(hEntrada), t2(hPrensa), t3(hCNC), t4(hSalida);
}
Experimentos propuestos
- Elimina mentalmente
spPrensaCNC: ¿qué intentaría hacer hPrensa mientras el CNC mecaniza? (Respuesta: esperar el robot, mover la pieza… y el código de la simulación bloquearía la entrega; en hardware real habría colisión.) - Haz que
estampa()dure mucho más quemecaniza()y observa dónde se acumulan las esperas: ese es el cuello de botella. - Cuenta en el registro cuántos
wait(sRobot)quedan bloqueados por ciclo: ¿cuánto tiempo está el robot retenido?