From d9eb8a236861561a025624234305b3610dce8a5b Mon Sep 17 00:00:00 2001 From: VladislavOstapov Date: Sun, 5 Feb 2023 14:07:32 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=BF=D0=B5=D1=80=D0=B5=D1=85=D0=B2=D0=B0=D1=82?= =?UTF-8?q?=20=D0=B1=D0=B0=D1=80=D0=B0=D0=B1=D0=B0=D0=BD=D0=B0,=20=D0=BE?= =?UTF-8?q?=D0=B1=D0=BD=D0=B0=D1=80=D1=83=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BE=D1=82=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D1=85=20=D0=B7=D0=BE=D0=BD,=20=D0=BC=D0=B5=D0=BB=D0=BA=D0=B8?= =?UTF-8?q?=D0=B9=20=D1=80=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D0=BD=D0=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- emulator.cpp | 6 +-- scheduler.c | 30 ++++++------ utils.c | 128 ++++++++++++++++++++++++++++----------------------- utils.h | 15 ++++++ 4 files changed, 104 insertions(+), 75 deletions(-) diff --git a/emulator.cpp b/emulator.cpp index 0fb2cbc..ebb3255 100644 --- a/emulator.cpp +++ b/emulator.cpp @@ -341,9 +341,9 @@ int main() { collectBarrelsStatistic(); // грузим не больше 5 барабанов - if (barrels_count < 5) { - button_load = 1; - } +// if (barrels_count < 5) { +// button_load = 1; +// } // ======= БЛОК КОДА bittons_logic ======= diff --git a/scheduler.c b/scheduler.c index da7e7a1..972c747 100644 --- a/scheduler.c +++ b/scheduler.c @@ -211,10 +211,10 @@ void scheduler_main() } // автоматический инкремент зон травления и цинкования - if (etching_zone < 0) { + if (!is_accessible_zone(ROBOT_ZONE_ETCH)) { increment_zone(ROBOT_ZONE_ETCH); } - if (galvanizing_zone < 0) { + if (!is_accessible_zone(ROBOT_ZONE_GAL)) { increment_zone(ROBOT_ZONE_GAL); } @@ -224,16 +224,16 @@ void scheduler_main() if (one_robot_mode) { // режим одного робота - char robot_id = 0; + char robot_id = ROBOT_NONE; if (hla_robot1_en && robot1_code.PC < 0) { - robot_id = 1; + robot_id = ROBOT_1; } else if (hla_robot2_en && robot2_code.PC < 0) { - robot_id = 2; + robot_id = ROBOT_2; } - if (robot_id != 0) { - if ((robot_id == 1 && robot1.dx.current_zone < ZONE_WASHING_1A) || - (robot_id == 2 && robot2.dx.current_zone < ZONE_WASHING_1A)) { + if (robot_id != ROBOT_NONE) { + if ((robot_id == ROBOT_1 && robot1.dx.current_zone < ZONE_WASHING_1A) || + (robot_id == ROBOT_2 && robot2.dx.current_zone < ZONE_WASHING_1A)) { if (robot_id == 1) { robot1_code.barrel_id = -1; robot1_code.code[0] = ROBOT_CMD_DOWN(); @@ -258,10 +258,10 @@ void scheduler_main() } } - if (robot_id == 1) { - schedule_one_robot(tasks, &robot1, &robot1_code, 1); + if (robot_id == ROBOT_1) { + schedule_one_robot(tasks, &robot1, &robot1_code, ROBOT_1); } else { - schedule_one_robot(tasks, &robot2, &robot2_code, 2); + schedule_one_robot(tasks, &robot2, &robot2_code, ROBOT_2); } } } @@ -306,13 +306,13 @@ void scheduler_main() // для каждой задачи: tasks[i].start_zone = barrels[i].zone; // определяем можно ли ее выполнить и что вообще нужно выполнить - tasks[i].dest_zone = can_move(barrels + i, 1); + tasks[i].dest_zone = can_move(barrels + i, ROBOT_1); if (tasks[i].dest_zone >= 0) { tasks[i].priority = get_operation_priority(i); } } - schedule_one_robot(tasks, &robot1, &robot1_code, 1); + schedule_one_robot(tasks, &robot1, &robot1_code, ROBOT_1); } // и отдельно для второго (только если не в ночном режиме) @@ -332,13 +332,13 @@ void scheduler_main() // для каждой задачи: tasks[i].start_zone = barrels[i].zone; // определяем можно ли ее выполнить и что вообще нужно выполнить - tasks[i].dest_zone = can_move(barrels + i, 2); + tasks[i].dest_zone = can_move(barrels + i, ROBOT_2); if (tasks[i].dest_zone >= 0) { tasks[i].priority = get_operation_priority(i); } } - schedule_one_robot(tasks, &robot2, &robot2_code, 2); + schedule_one_robot(tasks, &robot2, &robot2_code, ROBOT_2); } } } diff --git a/utils.c b/utils.c index cf1c743..5f57456 100644 --- a/utils.c +++ b/utils.c @@ -176,9 +176,10 @@ short _get_dest_zone(struct barrel *bar) { } // вернет можно ли ехать и главное куда ехать, если можно (нельзя если вернулось значение < 0) +// robot_id - 1 или 2 для роботов или -1 без привязки к конкретному роботу // -1 вернет что перемещать нельзя short can_move(struct barrel *bar, char robot_id) { - if (robot_id != 1 && robot_id != 2) { + if (robot_id != ROBOT_NONE && robot_id != ROBOT_1 && robot_id != ROBOT_2) { return -3; } // сразу отсекаем варианты, при которых невозможно переместить барабан @@ -198,7 +199,8 @@ short can_move(struct barrel *bar, char robot_id) { } // тут просчет примерного времени, в течении которого можно доехать до барабана - if (!bar->flags.is_empty) { + // !учитывается только с привязкой к роботу + if (!bar->flags.is_empty && robot_id != ROBOT_NONE) { short approximate_time; if (robot_id == 1) { approximate_time = bar->zone - robot1.dx.current_zone; @@ -231,7 +233,8 @@ short can_move(struct barrel *bar, char robot_id) { return -1; } - if (!one_robot_mode && dest_zone >= 0) { + // учитывать границы только в режиме двух роботов и с привязкой к роботу + if (!one_robot_mode && dest_zone >= 0 && robot_id != ROBOT_NONE) { if (robot_id == 1) { // если робот 1, то это старый, который ближе к концу линнии. // Ему нельзя ехать если хоть одна из зон <= max(r2_pos, r2_lock) + кол-во пограничных зон @@ -271,8 +274,40 @@ short can_move(struct barrel *bar, char robot_id) { } -// выставляет приоритет операции +// выставляет приоритет операции, предполагается что ее можно выполнить short get_operation_priority(short barrel_id) { + // если барабан пустой и не в ночном режиме, приоритет ему 2 + if (barrels[barrel_id].flags.is_empty && !barrels[barrel_id].flags.is_night) { + return 2; + } + + // если барабан в ночном режиме, то приоритет 1 самому левому, остальным 0 + if (barrels[barrel_id].flags.is_night) { + char is_not_one = 0; + char is_with_max_time = 1; + + for (short i = 0; i < BARRELS_COUNT; i++) { + if (i == barrel_id) { + continue; + } + if (barrels[i].flags.is_exist && barrels[i].flags.is_night) { + if (can_move(barrels + i, ROBOT_NONE) >= 0) { + is_not_one = 1; + // чем больше у барабана время ожидания тем меньше у него число + if (barrels[i].software_timer < barrels[barrel_id].software_timer) { + is_with_max_time = 0; + break; + } + } + } + } + + if (is_not_one == 0) { + return 1; + } + return is_with_max_time; + } + // сделать приоритет на барабан, который больше всего ждет if (barrels[barrel_id].zone >= ZONE_GALVANIZING_1 && barrels[barrel_id].zone <= ZONE_GALVANIZING_8) { // теперь надо выяснить, есть ли барабаны с большим временем ожидания @@ -288,7 +323,7 @@ short get_operation_priority(short barrel_id) { continue; } if (barrels[i].flags.is_exist && barrels[i].zone >= ZONE_GALVANIZING_1 && barrels[i].zone <= ZONE_GALVANIZING_8) { - if (can_move(barrels + i, 1) >= 0) { + if (can_move(barrels + i, ROBOT_NONE) >= 0) { is_not_one = 1; // чем больше у барабана время ожидания тем меньше у него число if (barrels[i].software_timer < barrels[barrel_id].software_timer) { @@ -320,7 +355,7 @@ short get_operation_priority(short barrel_id) { } if (barrels[i].flags.is_exist && barrels[i].zone >= ZONE_ETCHING_1 && barrels[i].zone <= ZONE_ETCHING_2) { - if (can_move(barrels + i, 1) >= 0) { + if (can_move(barrels + i, ROBOT_NONE) >= 0) { if (barrels[i].software_timer < barrels[barrel_id].software_timer) { return 0; // у этого барабана больше время ожидания (число меньше), значит приоритет 0 } else { @@ -433,53 +468,6 @@ void debug_print_robot_code(const struct robot_code *code, const short robot_id, #endif -/* -=== циклограмма перетаскивания барабана === -// NOTE первой командой на любую транзакцию должна стоять команда опустить траверсу (в 22 зоне мы никогда не закончим, за нее не беспокоится) -если режим двух роботов: - если команда для робота 1: - robot1_lock_zone = min(зона изъятия, зона назначения) - иначе: - robot2_lock_zone = max(зона изъятия, зона назначения) -* опустить траверсу -если зона изъятия != промывка 3б: - если текущая зона != зона изъятия: - если зона изъятия == 22: - * встать на смещенную - * поднять траверсу - * уехать в 22 зону - * встать на смещенную - * опустить траверсу - * встать в точную - иначе: - * уехать в зону изъятия - если режим двух роботов: - * установить новую lock-зону - * поднять траверсу - если зона изъятия != 22 и зона изъятия >= 2: - * ждать скапывания (зависит от зоны) - * ехать в зону назначения - если зона назначения == 22: - * опустить траверсу - * уехать в 21 зону - если ЭНКОДЕРЫ СТАРЫЕ (по умолчанию): - * поднять траверсу - * опустить траверсу - - если зона назначения != 22 и зона назначения != 0: - * установить время ожидания барабана (зависит от зоны) -иначе: - если текущая зона != промывка 3б: - * уехать в промывку 3б - * поднять траверсу - * уехать в пассивацию - * опустить траверсу - * ждать <время пассивации> - * поднять траверсу - * уехать в зону промывка 4а - * опустить траверсу - * установить время ожидания барабана (для промывки 4а) - */ void create_operation(struct robot_code *code, short barrel_id, const short start_zone, const short dest_zone, const short current_zone, const short robot_id) { // создаем код транзакции, пока обычный @@ -728,9 +716,9 @@ void create_operation(struct robot_code *code, short barrel_id, const short star // из промывки 2б он перекладывал, пусть едет в промывку 2а code->code[cmd_index++] = ROBOT_CMD_SET_LOCK_ZONE(robot2_border - 1); code->code[cmd_index++] = ROBOT_CMD_MOVE_TO_ZONE(robot2_border - 1); - } else if (dest_zone < ZONE_DEGREASING) { -// code->code[cmd_index++] = ROBOT_CMD_SET_LOCK_ZONE(ZONE_DEGREASING); - code->code[cmd_index++] = ROBOT_CMD_MOVE_TO_ZONE(ZONE_DEGREASING); + } else if (dest_zone < ZONE_WASHING_1A) { +// code->code[cmd_index++] = ROBOT_CMD_SET_LOCK_ZONE(ZONE_WASHING_1A); + code->code[cmd_index++] = ROBOT_CMD_MOVE_TO_ZONE(ZONE_WASHING_1A); } } else if (robot_id == 1) { // суть этого предела в том, чтобы робот всегда был свободен ЗА зоной gal8, @@ -739,10 +727,15 @@ void create_operation(struct robot_code *code, short barrel_id, const short star if (dest_zone <= robot1_border) { // чтобы из этой зоны можно было переложить барабан первому роботу -// code->code[cmd_index++] = ROBOT_CMD_SET_LOCK_ZONE(robot1_border + 1); + code->code[cmd_index++] = ROBOT_CMD_SET_LOCK_ZONE(robot1_border + 1); code->code[cmd_index++] = ROBOT_CMD_MOVE_TO_ZONE(robot1_border + 1); } } + } else { + // автоматический отгоняем робота в зону 3, чтоб не мешался + if (dest_zone < ZONE_WASHING_1A) { + code->code[cmd_index++] = ROBOT_CMD_MOVE_TO_ZONE(ZONE_WASHING_1A); + } } code->code[cmd_index++] = ROBOT_CMD_END(); @@ -753,6 +746,27 @@ void create_operation(struct robot_code *code, short barrel_id, const short star code->PC = 0; } + +char is_accessible_zone(short zone) { + if (zone == ROBOT_ZONE_ETCH) { + if (etching_zone < 0) { + return 0; + } + + return (hla_disabled_zones & (DISABLED_ETCH_1 << etching_zone)) != 0; + } else if (zone == ROBOT_ZONE_GAL) { + if (galvanizing_zone < 0) { + return 0; + } + + return (hla_disabled_zones & (DISABLED_GAL_1 << galvanizing_zone)) != 0; + } else { + // неверный аргумент + return 0; + } +} + + char increment_zone(short zone) { if (zone == ROBOT_ZONE_ETCH) { if ((hla_disabled_zones & DISABLED_ETCH) == DISABLED_ETCH) { diff --git a/utils.h b/utils.h index d5f5457..d312f10 100644 --- a/utils.h +++ b/utils.h @@ -375,13 +375,28 @@ extern const short NIGHT_ZONES[9]; char zone_is_busy(short zone); + + +#define ROBOT_1 1 +#define ROBOT_2 2 +#define ROBOT_NONE -1 + short can_move(struct barrel *bar, char robot_id); + short get_operation_priority(short barrel_id); + char remove_barrel_from_zone(short zone); void create_operation(struct robot_code *code, const short barrel_id, const short start_zone, const short dest_zone, const short current_zone, const short robot_id); +/** + * Активна ли зона цинкования или травления + * @param zone ROBOT_ZONE_ETCH или ROBOT_ZONE_GAL. Для других значений функция вернет false. + * @return true, если выбранная зона цинкования или травления доступна + */ +char is_accessible_zone(short zone); + /** * Инкрементировать зону цинкования или зону травления. * @param zone ROBOT_ZONE_ETCH или ROBOT_ZONE_GAL. Для других значений функция вернет false.