Рефакторинг, добавление документации
This commit is contained in:
parent
929a95504f
commit
0c70783f64
@ -10,7 +10,7 @@
|
||||
#include "robot.h"
|
||||
|
||||
|
||||
// закомментить когда надо будет отключить
|
||||
// закомментируй когда надо будет отключить
|
||||
//#define DEBUG_CORRECTION
|
||||
|
||||
|
||||
@ -207,7 +207,7 @@ static void collectBarrelsStatistic() {
|
||||
continue;
|
||||
}
|
||||
if (barrels[i].flags.robot == 0 && barrels[i].software_timer < 0) {
|
||||
// время отрицательное, вычитаем его чтобы убрать минус
|
||||
// время отрицательное, вычитаем его, чтобы убрать минус
|
||||
barrels_time -= barrels[i].software_timer;
|
||||
}
|
||||
}
|
||||
|
11
scheduler.c
11
scheduler.c
@ -4,7 +4,6 @@
|
||||
|
||||
|
||||
struct scheduler_task {
|
||||
short start_zone; // стартовая зона
|
||||
short dest_zone; // конечная зона
|
||||
short priority; // приоритет, чем больше тем выше, по умолчанию 0
|
||||
};
|
||||
@ -28,7 +27,7 @@ short scheduler_find_task(const struct scheduler_task* tasks, const short curr_p
|
||||
// ищем первый барабан слева, и ближайший справа
|
||||
short left = -1, right = -1;
|
||||
for (short i = 0; i < BARRELS_COUNT; i++) {
|
||||
short target = tasks[i].start_zone; // фактическая зона откуда тащить барабан
|
||||
short target = barrels[i].zone; // фактическая зона откуда тащить барабан
|
||||
if (tasks[i].dest_zone < 0) {
|
||||
continue;
|
||||
}
|
||||
@ -86,8 +85,6 @@ void schedule_one_robot(const short robot_id) {
|
||||
struct scheduler_task tasks[BARRELS_COUNT];
|
||||
|
||||
for (short i = 0; i < BARRELS_COUNT; i++) {
|
||||
// для каждой задачи:
|
||||
tasks[i].start_zone = barrels[i].zone;
|
||||
// определяем можно ли ее выполнить и что вообще нужно выполнить
|
||||
tasks[i].dest_zone = can_move(barrels + i, robot_id);
|
||||
if (tasks[i].dest_zone >= 0) {
|
||||
@ -108,11 +105,9 @@ void schedule_one_robot(const short robot_id) {
|
||||
|
||||
if (target_task >= 0) {
|
||||
if (robot_id == ROBOT_1) {
|
||||
create_operation(&robot1_code, target_task, tasks[target_task].start_zone, tasks[target_task].dest_zone,
|
||||
current_zone, robot_id);
|
||||
create_operation(target_task, barrels[target_task].zone, tasks[target_task].dest_zone, robot_id);
|
||||
} else {
|
||||
create_operation(&robot2_code, target_task, tasks[target_task].start_zone, tasks[target_task].dest_zone,
|
||||
current_zone, robot_id);
|
||||
create_operation(target_task, barrels[target_task].zone, tasks[target_task].dest_zone, robot_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
35
utils.c
35
utils.c
@ -24,7 +24,7 @@ const short NIGHT_ZONES[9] = {
|
||||
|
||||
char zone_is_busy(short zone) {
|
||||
for (short i = 0; i < BARRELS_COUNT; i++) {
|
||||
if (barrels[i].flags.is_exist && barrels[i].zone == zone) {
|
||||
if (barrels[i].flags.is_exist && barrels[i].zone == zone && !barrels[i].flags.is_up) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -33,7 +33,6 @@ char zone_is_busy(short zone) {
|
||||
|
||||
|
||||
short get_first_night_zone() {
|
||||
// TODO сделать корректное вычисление ночной зоны
|
||||
// всего зон, куда можно сныкать барабаны (всего 9 мест: загрузка 1 и 8 промывок)
|
||||
for (short nz = 0; nz < 9; nz++) {
|
||||
char found = 0;
|
||||
@ -67,13 +66,15 @@ short _get_dest_zone(struct barrel *bar, char robot_id) {
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
} else if (robot_id == ROBOT_2) {
|
||||
// робот 2 всегда кидает барабаны в загрузку 1, но только дальше зоны обмена он не имеет права брать
|
||||
if (bar->zone <= hla_exchange_zone) {
|
||||
return ZONE_LOAD_1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return ZONE_LOAD_1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -209,9 +210,7 @@ short _get_dest_zone(struct barrel *bar, char robot_id) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// вернет можно ли ехать и главное куда ехать, если можно (нельзя если вернулось значение < 0)
|
||||
// robot_id - 1 или 2 для роботов или -1 без привязки к конкретному роботу
|
||||
// -1 вернет что перемещать нельзя
|
||||
|
||||
short can_move(struct barrel *bar, char robot_id) {
|
||||
if (robot_id != ROBOT_NONE && robot_id != ROBOT_1 && robot_id != ROBOT_2) {
|
||||
return -3;
|
||||
@ -249,9 +248,9 @@ short can_move(struct barrel *bar, char robot_id) {
|
||||
|
||||
#ifndef EMULATOR
|
||||
if (approximate_time > 1) {
|
||||
approximate_time = ((approximate_time - 1) * 3) + 6;
|
||||
approximate_time = ((approximate_time - 1) * 3) + 4;
|
||||
} else if (approximate_time == 1) {
|
||||
approximate_time = 8;
|
||||
approximate_time = 5;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -270,7 +269,7 @@ short can_move(struct barrel *bar, char robot_id) {
|
||||
// учитывать границы только в режиме двух роботов и с привязкой к роботу
|
||||
if (!one_robot_mode && dest_zone >= 0 && robot_id != ROBOT_NONE) {
|
||||
if (robot_id == 1) {
|
||||
// если робот 1, то это старый, который ближе к концу линнии.
|
||||
// если робот 1, то это старый, который ближе к концу линии.
|
||||
// Ему нельзя ехать если хоть одна из зон <= max(r2_pos, r2_lock) + кол-во пограничных зон
|
||||
short border = robot2.dx.current_zone;
|
||||
if (border < robot2_lock_zone) {
|
||||
@ -286,7 +285,7 @@ short can_move(struct barrel *bar, char robot_id) {
|
||||
dest_zone = -6;
|
||||
}
|
||||
} else {
|
||||
// если робот 2, то это новый, который ближе к началу линнии.
|
||||
// если робот 2, то это новый, который ближе к началу линии.
|
||||
// Ему нельзя ехать если хоть одна из зон >= max(r2_pos, r2_lock) - кол-во пограничных зон
|
||||
short border = robot1.dx.current_zone;
|
||||
if (border > robot1_lock_zone) {
|
||||
@ -308,7 +307,6 @@ short can_move(struct barrel *bar, char robot_id) {
|
||||
}
|
||||
|
||||
|
||||
// выставляет приоритет операции, предполагается что ее можно выполнить
|
||||
short get_operation_priority(short barrel_id) {
|
||||
// если барабан пустой и не в ночном режиме, приоритет ему 2
|
||||
if (barrels[barrel_id].flags.is_empty && !barrels[barrel_id].flags.is_night) {
|
||||
@ -495,8 +493,19 @@ void debug_print_robot_code(const struct robot_code *code, const short robot_id,
|
||||
#endif
|
||||
|
||||
|
||||
void create_operation(struct robot_code *code, short barrel_id, const short start_zone, const short dest_zone,
|
||||
const short current_zone, const short robot_id) {
|
||||
void create_operation(short barrel_id, const short start_zone, const short dest_zone, const short robot_id) {
|
||||
short current_zone;
|
||||
struct robot_code *code;
|
||||
if (robot_id == ROBOT_1) {
|
||||
current_zone = robot1.dx.current_zone;
|
||||
code = &robot1_code;
|
||||
} else if (robot_id == ROBOT_2) {
|
||||
current_zone = robot2.dx.current_zone;
|
||||
code = &robot2_code;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// создаем код транзакции, пока обычный
|
||||
if (barrel_id >= BARRELS_COUNT) {
|
||||
barrel_id = -1;
|
||||
|
71
utils.h
71
utils.h
@ -130,24 +130,9 @@ struct robot_regs {
|
||||
|
||||
// NOTE первой командой на любую транзакцию должна стоять команда опустить траверсу (в 22 зоне по идее никогда не закончим)
|
||||
struct robot_code {
|
||||
short barrel_id; // нужен ID барабана, если
|
||||
short barrel_id; // если требуются операции с барабаном, то для корректного исполнения нужно указать значение >= 0
|
||||
short PC; // когда -1, код не выполняется
|
||||
|
||||
/*
|
||||
* система команд, которая нужна: (квадратные скобки - аргумент это младшие 14 бит)
|
||||
* 0 (смещение: да () ? нет): установить смещение (да - встанет в смещенную позицию, нет - в точную)
|
||||
* 1 (опция с барабаном) [поднять (1) | опустить]: поднять/опустить траверсу (перед поднятием ожидать если таймер барабана не истек)
|
||||
* 2 (опция с барабаном) [зона]: съебаться в зону
|
||||
* 3 [сек]: пауза на нужное количество секунд
|
||||
* 4 [время]: установить таймер барабану
|
||||
* 5 (ETCH(1) | GAL (2)) [зона]: установить зону блокировки, умеет использовать автоинкримент зоны гальваники или обезжиривания
|
||||
* 6 [X(1) | Y(2)]: скорректировать ось
|
||||
* 15: конец
|
||||
*
|
||||
* формат команды: (команда, старший байт) [младший байт, аргумент команды (если есть)] [слово, аргумент если команда требует]
|
||||
*/
|
||||
unsigned short code[16]; // формат кода: [команды] <команда 0>
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -252,6 +237,8 @@ extern short scheduler_stage;
|
||||
extern const short NIGHT_ZONES[9];
|
||||
|
||||
|
||||
/* ======================== ROBOT CODE ======================== */
|
||||
|
||||
#define ROBOT_CMD_MASK 0xF000U
|
||||
#define ROBOT_CMD_END_code 0x0000U
|
||||
#define ROBOT_CMD_MOVE_TO_ZONE_code 0x1000U
|
||||
@ -302,7 +289,7 @@ extern const short NIGHT_ZONES[9];
|
||||
#define ROBOT_CMD_INC_ZONE(arg) (ROBOT_CMD_INC_ZONE_code | (unsigned short)(arg))
|
||||
|
||||
|
||||
/* ======================== DISABLED ZONES DEFS ======================== */
|
||||
/* ======================== DISABLED ZONES ======================== */
|
||||
|
||||
#define DISABLED_ETCH_1 0x0001
|
||||
#define DISABLED_ETCH_2 0x0002
|
||||
@ -318,7 +305,8 @@ extern const short NIGHT_ZONES[9];
|
||||
#define DISABLED_GAL_8 0x0200
|
||||
#define DISABLED_GAL 0x03FC
|
||||
|
||||
/* ======================== IO DEFS ======================== */
|
||||
|
||||
/* ======================== IO ======================== */
|
||||
|
||||
#define ROBOT1_X 1
|
||||
#define ROBOT1_Z 2
|
||||
@ -329,8 +317,6 @@ extern const short NIGHT_ZONES[9];
|
||||
#define VFD_REG_D0_ADDR 4096
|
||||
#define VFD_REG_M0_ADDR 2048
|
||||
|
||||
/* ======================== ROBOT DEFS ======================== */
|
||||
|
||||
#define MB_CMD_WRITE_FLAG 5
|
||||
#define MB_CMD_WRITE_REG 6
|
||||
|
||||
@ -376,6 +362,13 @@ extern const short NIGHT_ZONES[9];
|
||||
#define ROBOT_X_TARGET_ZONE_ADDR (VFD_REG_D0_ADDR + ROBOT_X_TARGET_ZONE_OFFSET)
|
||||
|
||||
|
||||
/* ======================== UTILS FUNCTIONS ======================== */
|
||||
|
||||
/**
|
||||
* Занята ли зона. Учитываются только барабаны, которые внизу
|
||||
* @param zone зона для обнаружения
|
||||
* @return true если занята, в противном случае false
|
||||
*/
|
||||
char zone_is_busy(short zone);
|
||||
|
||||
|
||||
@ -383,14 +376,38 @@ char zone_is_busy(short zone);
|
||||
#define ROBOT_2 2
|
||||
#define ROBOT_NONE -1
|
||||
|
||||
/**
|
||||
* Функция, определяющая можно ли переместить барабан и куда его нужно переместить.
|
||||
* @param bar указатель на барабан
|
||||
* @param robot_id ID робота, нужно передавать всегда, в режиме одного робота учитывается время, в режиме двух роботов
|
||||
* учитываются рабочие границы роботов. Для отключения учета времени и границ следует передать <code>ROBOT_NONE</code>.
|
||||
* @return Зону, куда нужно переместить барабан. Если значение < 0, то барабан переместить в данный момент невозможно.
|
||||
*/
|
||||
short can_move(struct barrel *bar, char robot_id);
|
||||
|
||||
/**
|
||||
* Получить приоритет для операции перемещения барабана. Учитывает взаимное положение барабанов на линии и аттрибуты барабана
|
||||
* @note Вызывать следует только если барабан подлежит перемещению (<code>can_move</code> вернул значение >= 0)
|
||||
* @param barrel_id номер барабана, для которого нужно вычислить приоритет.
|
||||
* @return Приоритет операции. Чем больше число тем выше приоритет.
|
||||
*/
|
||||
short get_operation_priority(short barrel_id);
|
||||
|
||||
/**
|
||||
* Удаление барабана из зоны, учитывает блокировку барабана роботом и положение барабана (нельзя удалить висящий барабан).
|
||||
* @param zone Зона, из которой требуется удалить барабана.
|
||||
* @return true, если барабан был удален, в противном случае false.
|
||||
*/
|
||||
char remove_barrel_from_zone(short zone);
|
||||
|
||||
void create_operation(struct robot_code *code, const short barrel_id, const short start_zone, const short dest_zone,
|
||||
const short current_zone, const short robot_id);
|
||||
/**
|
||||
* Создание операции на перемещение барабана.
|
||||
* @param barrel_id индекс барабана в структуре барабана, функцией напрямую не учитывается, но копируется в структуру кода робота
|
||||
* @param start_zone зона, откуда нужно переместить барабан
|
||||
* @param dest_zone зона, куда нужно переместить барабан (если ZONE_PASSIVATION то фактически после операции барабан окажется в зоне промывки 4а)
|
||||
* @param robot_id ID робота, который должен выполнить операцию
|
||||
*/
|
||||
void create_operation(short barrel_id, const short start_zone, const short dest_zone, const short robot_id);
|
||||
|
||||
/**
|
||||
* Активна ли зона цинкования или травления
|
||||
@ -406,9 +423,19 @@ char is_accessible_zone(short zone);
|
||||
*/
|
||||
char increment_zone(short zone);
|
||||
|
||||
/**
|
||||
* Получение первой ночной зоны, то есть зоны куда нужно ложить ночной барабан
|
||||
* @return номер зоны, либо -1 если зона занята или еще нужна для обслуживания других барабанов
|
||||
*/
|
||||
short get_first_night_zone();
|
||||
|
||||
#ifdef EMULATOR
|
||||
/**
|
||||
* Вывод структуры кода робота, работает только в эмуляторе.
|
||||
* @param code структура кода робота, именно ее и будет выводить функция
|
||||
* @param robot_id ID робота (1 или 2), нужно для вывода отладочной информации
|
||||
* @param fd file descriptor, устройство куда нужно записать весь вывод
|
||||
*/
|
||||
void debug_print_robot_code(const struct robot_code *code, const short robot_id, int fd);
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user