Первый и самый простой планировщик, таскает барабаны справа, если там их нет ищет первый слева и едет к нему
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) {
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
// пока без второго робота
|
// пока без второго робота
|
||||||
|
Reference in New Issue
Block a user