Первый и самый простой планировщик, таскает барабаны справа, если там их нет ищет первый слева и едет к нему

This commit is contained in:
VladislavOstapov 2022-11-19 16:50:44 +03:00
parent b15e14970e
commit 4d7350ac69

View File

@ -32,14 +32,16 @@ short can_move(struct barrel* bar) {
} }
if (bar->software_timer > 0) { if (bar->software_timer > 0) {
return -100; return -1;
} }
if (bar->flags.robot != 0) { if (bar->flags.robot != 0) {
return -2; return -2;
} }
// TODO добавить проверку того, что барабан нельзя перетащить если второй робот мешает if (!schedulerOneRobotMode) {
printf("WARMING: нет проверки того, что для перемещения барабана не мешает второй робот\n");
}
// дальше нужно проверить, что можно передвигать бочку // дальше нужно проверить, что можно передвигать бочку
@ -137,11 +139,10 @@ short can_move(struct barrel* bar) {
break; break;
case PROCESS_RETURN_1: case PROCESS_RETURN_1:
// последняя промывка, нужно разрешение на выгрузку // последняя промывка, нужно разрешение на выгрузку
// TODO сделать так, чтобы в 0 зоне барабаны убирались, а в 1 появлялись
if (schedulerUnloadButton) { if (schedulerUnloadButton) {
// нужна хотя бы одна свободная выгрузка // нужно промывку 3б (зона 10) и загрузку 0
if (!zone_is_busy(0) || !zone_is_busy(1)) { if (!zone_is_busy(17) || !zone_is_busy(0)) {
return 7; // TODO сделать нормальный просчет зон промывок return 17;
} }
} }
break; break;
@ -156,28 +157,12 @@ short can_move(struct barrel* bar) {
if (!zone_is_busy(0)) { if (!zone_is_busy(0)) {
return 0; return 0;
} }
if (!zone_is_busy(1)) {
return 1;
}
break; break;
} }
return -1; 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 makeBarrel(short flags, short zone, short timer, short process) {
struct barrel b; 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) { struct scheduler_task {
static short transaction_state = 0; short start_zone; // стартовая зона
if (transaction_state == 0) { short dest_zone; // конечная зона
// ищем работу роботу };
short min_cost = -1, target_barrel = 0, next_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++) { for (short i = 0; i < BARRELS_COUNT; i++) {
if (barrels[i].flags.robot == 1) { // для каждой задачи:
barrels[i].flags.robot = 0; tasks[i].start_zone = barrels[i].zone;
} // определяем можно ли ее выполнить и что вообще нужно выполнить
short nz = can_move(barrels + i); tasks[i].dest_zone = 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 (schedulerOneRobotMode) {
if (cost < min_cost || min_cost == -1) { char forward_is_exist = 0;
min_cost = cost; short target_task = -1, first_task = -1;
target_barrel = i; for (short i = 0; i < BARRELS_COUNT; i++) {
next_zone = nz; 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) { if (!forward_is_exist) {
// пассивация target_task = first_task;
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 (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].zone = target_zone;
barrels[target_barrel].flags.robot = 1; barrels[target_task].flags.robot = 1;
// TODO сделать нормальное переключение зон с учетом тех, что можно отключить // TODO сделать нормальное переключение зон с учетом тех, что можно отключить
// TODO добавить ограничение - нельзя отключить сразу все зоны цинкования или травления // TODO добавить ограничение - нельзя отключить сразу все зоны цинкования или травления
if (next_zone == 3 || next_zone == 4) { if (tasks[target_task].dest_zone == 3 || tasks[target_task].dest_zone == 4) {
etching_zone ^= 0x1; // переключаем следующую зону 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;
} }
} else {
if (next_zone >= 9 && next_zone <= 17) { printf("WARMING: support only one robot mode\n");
galvanizing_zone = (galvanizing_zone + 1) % 8; }
} } else if (transaction_state == 1) {
if (robot1_cmd.cmd == 0) {
if (barrels[target_barrel].zone == 22) { transaction_state = 2;
// выгрузка, снимаем кнопку выгрузки
schedulerUnloadButton = 0;
}
transaction_state = 1;
} }
} else { } else {
// post transaction // post transaction
@ -265,9 +294,9 @@ void schedule_robot_1(struct robot_cmd* cmd) {
if (barrel >= 0) { if (barrel >= 0) {
b->flags.is_up = 0; b->flags.is_up = 0;
b->flags.robot = 0; b->flags.robot = 0;
if (cmd->cmd == 2) { if (robot1_cmd.cmd == 2) {
b->zone = cmd->args[2]; b->zone = robot1_cmd.args[2];
} else if (cmd->cmd == 3) { } else if (robot1_cmd.cmd == 3) {
b->zone = 20; b->zone = 20;
} }
} }
@ -341,10 +370,12 @@ char create_barrel_in_load(short zone) {
} }
void scheduler_main() { void scheduler_main() {
// вставка барабанов // тут должно быть удаление барабана из зоны 1, если он там есть
if (schedulerLoadButton1) { // if (schedulerLoadButton1) {
schedulerLoadButton1 = create_barrel_in_load(0); // schedulerLoadButton1 = create_barrel_in_load(0);
} // }
// тут возможна только вставка барабанов
if (schedulerLoadButton2) { if (schedulerLoadButton2) {
schedulerLoadButton2 = create_barrel_in_load(1); schedulerLoadButton2 = create_barrel_in_load(1);
} }
@ -358,7 +389,7 @@ void scheduler_main() {
} }
} }
if (robot1_cmd.cmd == 0) { if (robot1_cmd.cmd == 0) {
schedule_robot_1(&robot1_cmd); schedule_robot_1();
} }
// пока без второго робота // пока без второго робота