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

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,61 +186,105 @@ struct barrel makeBarrel(short flags, short zone, short timer, short process) {
} }
void schedule_robot_1(struct robot_cmd* cmd) { struct scheduler_task {
short start_zone; // стартовая зона
short dest_zone; // конечная зона
};
void schedule_robot_1() {
static short transaction_state = 0; static short transaction_state = 0;
// начало транзакции
if (transaction_state == 0) { if (transaction_state == 0) {
// ищем работу роботу // формируем список задач
short min_cost = -1, target_barrel = 0, next_zone; 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;
// определяем можно ли ее выполнить и что вообще нужно выполнить
tasks[i].dest_zone = can_move(barrels + i);
} }
short nz = can_move(barrels + i);
if (nz >= 0 || nz == -2) { // найти подходящую задачу
short cost = compute_cost(barrels + i, robot1.curr_zone, nz); if (schedulerOneRobotMode) {
printf("Barrel calc cost result: id=%d cost=%d\n", i, cost); char forward_is_exist = 0;
if (cost >= 0) { short target_task = -1, first_task = -1;
if (cost < min_cost || min_cost == -1) { for (short i = 0; i < BARRELS_COUNT; i++) {
min_cost = cost; short target = tasks[i].start_zone; // фактическая зона откуда тащить барабан
target_barrel = i; if (tasks[i].dest_zone == -2) {
next_zone = nz; 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 (min_cost >= 0) { // тут нахождение первой задачи, нужно если вдруг
if (next_zone == -2) { if (first_task == -1) {
first_task = i;
} else {
if (barrels[first_task].zone > target) {
first_task = i;
}
}
}
// итого есть результат: есть ли таски, которые надо тащить вперед (и если надо то какой ближний), и есть первый таск
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_barrel); printf("Get work: passivate barrel %d\n", target_task);
robot1_cmd.cmd = 3; // пассивация robot1_cmd.cmd = 3; // пассивация
} else { } else {
printf("Get work: move barrel %d from %d to %d\n", target_barrel, barrels[target_barrel].zone, next_zone); 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.cmd = 2; // везем барабан
robot1_cmd.args[0] = barrels[target_barrel].zone; robot1_cmd.args[0] = tasks[target_task].start_zone;
robot1_cmd.args[1] = next_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 (next_zone >= 9 && next_zone <= 17) { if (tasks[target_task].dest_zone >= 9 && tasks[target_task].dest_zone <= 17) {
galvanizing_zone = (galvanizing_zone + 1) % 8; galvanizing_zone = (galvanizing_zone + 1) % 8;
} }
if (barrels[target_barrel].zone == 22) { if (tasks[target_task].start_zone == 22) {
// выгрузка, снимаем кнопку выгрузки // выгрузка, снимаем кнопку выгрузки
schedulerUnloadButton = 0; schedulerUnloadButton = 0;
} }
transaction_state = 1; 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 { } else {
// post transaction // post transaction
short barrel = get_robot_barrel(1); short barrel = get_robot_barrel(1);
@ -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();
} }
// пока без второго робота // пока без второго робота