Исправлен перехват барабана, обнаружение отключенных зон, мелкий рефакторинг
This commit is contained in:
parent
4a029d9aa5
commit
d9eb8a2368
@ -341,9 +341,9 @@ int main() {
|
||||
collectBarrelsStatistic();
|
||||
|
||||
// грузим не больше 5 барабанов
|
||||
if (barrels_count < 5) {
|
||||
button_load = 1;
|
||||
}
|
||||
// if (barrels_count < 5) {
|
||||
// button_load = 1;
|
||||
// }
|
||||
|
||||
// ======= БЛОК КОДА bittons_logic =======
|
||||
|
||||
|
30
scheduler.c
30
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
128
utils.c
128
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) {
|
||||
|
15
utils.h
15
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.
|
||||
|
Reference in New Issue
Block a user