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

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