Исправлен перехват барабана, обнаружение отключенных зон, мелкий рефакторинг

This commit is contained in:
VladislavOstapov 2023-02-05 14:07:32 +03:00
parent 4a029d9aa5
commit d9eb8a2368
4 changed files with 104 additions and 75 deletions

View File

@ -341,9 +341,9 @@ int main() {
collectBarrelsStatistic(); collectBarrelsStatistic();
// грузим не больше 5 барабанов // грузим не больше 5 барабанов
if (barrels_count < 5) { // if (barrels_count < 5) {
button_load = 1; // button_load = 1;
} // }
// ======= БЛОК КОДА bittons_logic ======= // ======= БЛОК КОДА bittons_logic =======

View File

@ -211,10 +211,10 @@ void scheduler_main()
} }
// автоматический инкремент зон травления и цинкования // автоматический инкремент зон травления и цинкования
if (etching_zone < 0) { if (!is_accessible_zone(ROBOT_ZONE_ETCH)) {
increment_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); increment_zone(ROBOT_ZONE_GAL);
} }
@ -224,16 +224,16 @@ void scheduler_main()
if (one_robot_mode) { if (one_robot_mode) {
// режим одного робота // режим одного робота
char robot_id = 0; char robot_id = ROBOT_NONE;
if (hla_robot1_en && robot1_code.PC < 0) { if (hla_robot1_en && robot1_code.PC < 0) {
robot_id = 1; robot_id = ROBOT_1;
} else if (hla_robot2_en && robot2_code.PC < 0) { } else if (hla_robot2_en && robot2_code.PC < 0) {
robot_id = 2; robot_id = ROBOT_2;
} }
if (robot_id != 0) { if (robot_id != ROBOT_NONE) {
if ((robot_id == 1 && robot1.dx.current_zone < ZONE_WASHING_1A) || if ((robot_id == ROBOT_1 && robot1.dx.current_zone < ZONE_WASHING_1A) ||
(robot_id == 2 && robot2.dx.current_zone < ZONE_WASHING_1A)) { (robot_id == ROBOT_2 && robot2.dx.current_zone < ZONE_WASHING_1A)) {
if (robot_id == 1) { if (robot_id == 1) {
robot1_code.barrel_id = -1; robot1_code.barrel_id = -1;
robot1_code.code[0] = ROBOT_CMD_DOWN(); robot1_code.code[0] = ROBOT_CMD_DOWN();
@ -258,10 +258,10 @@ void scheduler_main()
} }
} }
if (robot_id == 1) { if (robot_id == ROBOT_1) {
schedule_one_robot(tasks, &robot1, &robot1_code, 1); schedule_one_robot(tasks, &robot1, &robot1_code, ROBOT_1);
} else { } 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].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) { if (tasks[i].dest_zone >= 0) {
tasks[i].priority = get_operation_priority(i); 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].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) { if (tasks[i].dest_zone >= 0) {
tasks[i].priority = get_operation_priority(i); tasks[i].priority = get_operation_priority(i);
} }
} }
schedule_one_robot(tasks, &robot2, &robot2_code, 2); schedule_one_robot(tasks, &robot2, &robot2_code, ROBOT_2);
} }
} }
} }

128
utils.c
View File

@ -176,9 +176,10 @@ short _get_dest_zone(struct barrel *bar) {
} }
// вернет можно ли ехать и главное куда ехать, если можно (нельзя если вернулось значение < 0) // вернет можно ли ехать и главное куда ехать, если можно (нельзя если вернулось значение < 0)
// robot_id - 1 или 2 для роботов или -1 без привязки к конкретному роботу
// -1 вернет что перемещать нельзя // -1 вернет что перемещать нельзя
short can_move(struct barrel *bar, char robot_id) { 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; 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; short approximate_time;
if (robot_id == 1) { if (robot_id == 1) {
approximate_time = bar->zone - robot1.dx.current_zone; approximate_time = bar->zone - robot1.dx.current_zone;
@ -231,7 +233,8 @@ short can_move(struct barrel *bar, char robot_id) {
return -1; return -1;
} }
if (!one_robot_mode && dest_zone >= 0) { // учитывать границы только в режиме двух роботов и с привязкой к роботу
if (!one_robot_mode && dest_zone >= 0 && robot_id != ROBOT_NONE) {
if (robot_id == 1) { if (robot_id == 1) {
// если робот 1, то это старый, который ближе к концу линнии. // если робот 1, то это старый, который ближе к концу линнии.
// Ему нельзя ехать если хоть одна из зон <= max(r2_pos, r2_lock) + кол-во пограничных зон // Ему нельзя ехать если хоть одна из зон <= 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) { 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) { 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; continue;
} }
if (barrels[i].flags.is_exist && barrels[i].zone >= ZONE_GALVANIZING_1 && barrels[i].zone <= ZONE_GALVANIZING_8) { 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; is_not_one = 1;
// чем больше у барабана время ожидания тем меньше у него число // чем больше у барабана время ожидания тем меньше у него число
if (barrels[i].software_timer < barrels[barrel_id].software_timer) { 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 (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) { if (barrels[i].software_timer < barrels[barrel_id].software_timer) {
return 0; // у этого барабана больше время ожидания (число меньше), значит приоритет 0 return 0; // у этого барабана больше время ожидания (число меньше), значит приоритет 0
} else { } else {
@ -433,53 +468,6 @@ void debug_print_robot_code(const struct robot_code *code, const short robot_id,
#endif #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, 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) { 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а // из промывки 2б он перекладывал, пусть едет в промывку 2а
code->code[cmd_index++] = ROBOT_CMD_SET_LOCK_ZONE(robot2_border - 1); code->code[cmd_index++] = ROBOT_CMD_SET_LOCK_ZONE(robot2_border - 1);
code->code[cmd_index++] = ROBOT_CMD_MOVE_TO_ZONE(robot2_border - 1); code->code[cmd_index++] = ROBOT_CMD_MOVE_TO_ZONE(robot2_border - 1);
} else if (dest_zone < ZONE_DEGREASING) { } else if (dest_zone < ZONE_WASHING_1A) {
// code->code[cmd_index++] = ROBOT_CMD_SET_LOCK_ZONE(ZONE_DEGREASING); // code->code[cmd_index++] = ROBOT_CMD_SET_LOCK_ZONE(ZONE_WASHING_1A);
code->code[cmd_index++] = ROBOT_CMD_MOVE_TO_ZONE(ZONE_DEGREASING); code->code[cmd_index++] = ROBOT_CMD_MOVE_TO_ZONE(ZONE_WASHING_1A);
} }
} else if (robot_id == 1) { } else if (robot_id == 1) {
// суть этого предела в том, чтобы робот всегда был свободен ЗА зоной gal8, // суть этого предела в том, чтобы робот всегда был свободен ЗА зоной gal8,
@ -739,10 +727,15 @@ void create_operation(struct robot_code *code, short barrel_id, const short star
if (dest_zone <= robot1_border) { 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); 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(); 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; 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) { char increment_zone(short zone) {
if (zone == ROBOT_ZONE_ETCH) { if (zone == ROBOT_ZONE_ETCH) {
if ((hla_disabled_zones & DISABLED_ETCH) == DISABLED_ETCH) { if ((hla_disabled_zones & DISABLED_ETCH) == DISABLED_ETCH) {

15
utils.h
View File

@ -375,13 +375,28 @@ extern const short NIGHT_ZONES[9];
char zone_is_busy(short zone); 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 can_move(struct barrel *bar, char robot_id);
short get_operation_priority(short barrel_id); short get_operation_priority(short barrel_id);
char remove_barrel_from_zone(short zone); 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, 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); 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. * @param zone ROBOT_ZONE_ETCH или ROBOT_ZONE_GAL. Для других значений функция вернет false.