Первый и самый простой планировщик, таскает барабаны справа, если там их нет ищет первый слева и едет к нему
This commit is contained in:
parent
b15e14970e
commit
4d7350ac69
179
scheduler.c
179
scheduler.c
@ -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();
|
||||
}
|
||||
|
||||
// пока без второго робота
|
||||
|
Reference in New Issue
Block a user