From 4d7350ac699c4c72c58e4656bc4e5ff9246570d0 Mon Sep 17 00:00:00 2001 From: VladislavOstapov Date: Sat, 19 Nov 2022 16:50:44 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B2=D1=8B=D0=B9=20=D0=B8?= =?UTF-8?q?=20=D1=81=D0=B0=D0=BC=D1=8B=D0=B9=20=D0=BF=D1=80=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D0=BE=D0=B9=20=D0=BF=D0=BB=D0=B0=D0=BD=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D1=89=D0=B8=D0=BA,=20=D1=82=D0=B0=D1=81=D0=BA=D0=B0?= =?UTF-8?q?=D0=B5=D1=82=20=D0=B1=D0=B0=D1=80=D0=B0=D0=B1=D0=B0=D0=BD=D1=8B?= =?UTF-8?q?=20=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B0,=20=D0=B5=D1=81=D0=BB?= =?UTF-8?q?=D0=B8=20=D1=82=D0=B0=D0=BC=20=D0=B8=D1=85=20=D0=BD=D0=B5=D1=82?= =?UTF-8?q?=20=D0=B8=D1=89=D0=B5=D1=82=20=D0=BF=D0=B5=D1=80=D0=B2=D1=8B?= =?UTF-8?q?=D0=B9=20=D1=81=D0=BB=D0=B5=D0=B2=D0=B0=20=D0=B8=20=D0=B5=D0=B4?= =?UTF-8?q?=D0=B5=D1=82=20=D0=BA=20=D0=BD=D0=B5=D0=BC=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scheduler.c | 179 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 105 insertions(+), 74 deletions(-) diff --git a/scheduler.c b/scheduler.c index b122f71..c2777f9 100644 --- a/scheduler.c +++ b/scheduler.c @@ -32,14 +32,16 @@ short can_move(struct barrel* bar) { } if (bar->software_timer > 0) { - return -100; + return -1; } if (bar->flags.robot != 0) { return -2; } - // TODO добавить проверку того, что барабан нельзя перетащить если второй робот мешает + if (!schedulerOneRobotMode) { + printf("WARMING: нет проверки того, что для перемещения барабана не мешает второй робот\n"); + } // дальше нужно проверить, что можно передвигать бочку @@ -137,11 +139,10 @@ short can_move(struct barrel* bar) { break; case PROCESS_RETURN_1: // последняя промывка, нужно разрешение на выгрузку - // TODO сделать так, чтобы в 0 зоне барабаны убирались, а в 1 появлялись if (schedulerUnloadButton) { - // нужна хотя бы одна свободная выгрузка - if (!zone_is_busy(0) || !zone_is_busy(1)) { - return 7; // TODO сделать нормальный просчет зон промывок + // нужно промывку 3б (зона 10) и загрузку 0 + if (!zone_is_busy(17) || !zone_is_busy(0)) { + return 17; } } break; @@ -156,28 +157,12 @@ short can_move(struct barrel* bar) { if (!zone_is_busy(0)) { return 0; } - if (!zone_is_busy(1)) { - return 1; - } break; } return -1; } -short compute_cost(struct barrel* b, short current_pos, short next_zone) { - short delta = (short)(b->zone - current_pos); - - if (next_zone < 0 && next_zone != -2) { - return -3; - } - - if (delta < 0) { - return (short)((-delta) * 2); - } else { - return delta; - } -} struct barrel makeBarrel(short flags, short zone, short timer, short process) { struct barrel b; @@ -201,60 +186,104 @@ struct barrel makeBarrel(short flags, short zone, short timer, short process) { } -void schedule_robot_1(struct robot_cmd* cmd) { - static short transaction_state = 0; - if (transaction_state == 0) { - // ищем работу роботу - short min_cost = -1, target_barrel = 0, next_zone; +struct scheduler_task { + short start_zone; // стартовая зона + short dest_zone; // конечная зона +}; + +void schedule_robot_1() { + static short transaction_state = 0; + + // начало транзакции + + if (transaction_state == 0) { + // формируем список задач + struct scheduler_task tasks[BARRELS_COUNT]; for (short i = 0; i < BARRELS_COUNT; i++) { - if (barrels[i].flags.robot == 1) { - barrels[i].flags.robot = 0; - } - short nz = can_move(barrels + i); - if (nz >= 0 || nz == -2) { - short cost = compute_cost(barrels + i, robot1.curr_zone, nz); - printf("Barrel calc cost result: id=%d cost=%d\n", i, cost); - if (cost >= 0) { - if (cost < min_cost || min_cost == -1) { - min_cost = cost; - target_barrel = i; - next_zone = nz; + // для каждой задачи: + tasks[i].start_zone = barrels[i].zone; + // определяем можно ли ее выполнить и что вообще нужно выполнить + tasks[i].dest_zone = can_move(barrels + i); + } + + // найти подходящую задачу + if (schedulerOneRobotMode) { + char forward_is_exist = 0; + short target_task = -1, first_task = -1; + for (short i = 0; i < BARRELS_COUNT; i++) { + short target = tasks[i].start_zone; // фактическая зона откуда тащить барабан + if (tasks[i].dest_zone == -2) { + target = 18; + } else if (tasks[i].dest_zone < 0) { + continue; + } + + if (robot1.curr_zone <= target) { + forward_is_exist = 1; + if (target_task == -1) { + target_task = i; + } else { + if (barrels[target_task].zone > target) { + target_task = i; + } + } + } + + // тут нахождение первой задачи, нужно если вдруг + if (first_task == -1) { + first_task = i; + } else { + if (barrels[first_task].zone > target) { + first_task = i; } } } - } - if (min_cost >= 0) { - if (next_zone == -2) { - // пассивация - printf("Get work: passivate barrel %d\n", target_barrel); - robot1_cmd.cmd = 3; // пассивация - } else { - printf("Get work: move barrel %d from %d to %d\n", target_barrel, barrels[target_barrel].zone, next_zone); - robot1_cmd.cmd = 2; // везем барабан - robot1_cmd.args[0] = barrels[target_barrel].zone; - robot1_cmd.args[1] = next_zone; + // итого есть результат: есть ли таски, которые надо тащить вперед (и если надо то какой ближний), и есть первый таск + if (!forward_is_exist) { + target_task = first_task; } + + if (target_task >= 0) { + // создаем транзакцию + if (tasks[target_task].dest_zone == -2) { + // пассивация + printf("Get work: passivate barrel %d\n", target_task); + robot1_cmd.cmd = 3; // пассивация + } else { + printf("Get work: move barrel %d from %d to %d\n", + target_task, tasks[target_task].start_zone, tasks[target_task].dest_zone); + robot1_cmd.cmd = 2; // везем барабан + robot1_cmd.args[0] = tasks[target_task].start_zone; + robot1_cmd.args[1] = tasks[target_task].dest_zone; + } // barrels[target_barrel].zone = target_zone; - barrels[target_barrel].flags.robot = 1; + barrels[target_task].flags.robot = 1; - // TODO сделать нормальное переключение зон с учетом тех, что можно отключить - // TODO добавить ограничение - нельзя отключить сразу все зоны цинкования или травления - if (next_zone == 3 || next_zone == 4) { - etching_zone ^= 0x1; // переключаем следующую зону + // TODO сделать нормальное переключение зон с учетом тех, что можно отключить + // TODO добавить ограничение - нельзя отключить сразу все зоны цинкования или травления + if (tasks[target_task].dest_zone == 3 || tasks[target_task].dest_zone == 4) { + etching_zone ^= 0x1; // переключаем следующую зону + } + + if (tasks[target_task].dest_zone >= 9 && tasks[target_task].dest_zone <= 17) { + galvanizing_zone = (galvanizing_zone + 1) % 8; + } + + if (tasks[target_task].start_zone == 22) { + // выгрузка, снимаем кнопку выгрузки + schedulerUnloadButton = 0; + } + + transaction_state = 1; } - - if (next_zone >= 9 && next_zone <= 17) { - galvanizing_zone = (galvanizing_zone + 1) % 8; - } - - if (barrels[target_barrel].zone == 22) { - // выгрузка, снимаем кнопку выгрузки - schedulerUnloadButton = 0; - } - - transaction_state = 1; + } else { + printf("WARMING: support only one robot mode\n"); + } + } else if (transaction_state == 1) { + if (robot1_cmd.cmd == 0) { + transaction_state = 2; } } else { // post transaction @@ -265,9 +294,9 @@ void schedule_robot_1(struct robot_cmd* cmd) { if (barrel >= 0) { b->flags.is_up = 0; b->flags.robot = 0; - if (cmd->cmd == 2) { - b->zone = cmd->args[2]; - } else if (cmd->cmd == 3) { + if (robot1_cmd.cmd == 2) { + b->zone = robot1_cmd.args[2]; + } else if (robot1_cmd.cmd == 3) { b->zone = 20; } } @@ -341,10 +370,12 @@ char create_barrel_in_load(short zone) { } void scheduler_main() { - // вставка барабанов - if (schedulerLoadButton1) { - schedulerLoadButton1 = create_barrel_in_load(0); - } + // тут должно быть удаление барабана из зоны 1, если он там есть +// if (schedulerLoadButton1) { +// schedulerLoadButton1 = create_barrel_in_load(0); +// } + + // тут возможна только вставка барабанов if (schedulerLoadButton2) { schedulerLoadButton2 = create_barrel_in_load(1); } @@ -358,7 +389,7 @@ void scheduler_main() { } } if (robot1_cmd.cmd == 0) { - schedule_robot_1(&robot1_cmd); + schedule_robot_1(); } // пока без второго робота