Исправлен перехват барабана, обнаружение отключенных зон, мелкий рефакторинг
This commit is contained in:
parent
4a029d9aa5
commit
d9eb8a2368
@ -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 =======
|
||||||
|
|
||||||
|
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);
|
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
128
utils.c
@ -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
15
utils.h
@ -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.
|
||||||
|
Reference in New Issue
Block a user