From 8f19d1b277d5c3ecc54754591ad6738fa6efffa7 Mon Sep 17 00:00:00 2001 From: VladislavOstapov Date: Fri, 2 Dec 2022 22:29:36 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=B3=D0=BE=D1=82=D0=BE?= =?UTF-8?q?=D0=B2=D0=BA=D0=B0=20=D0=BA=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BF?= =?UTF-8?q?=D0=B8=D1=81=D1=8B=D0=B2=D0=B0=D0=BD=D0=B8=D1=8E=20=D0=BF=D0=BB?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D1=80=D0=BE=D0=B2=D1=89=D0=B8=D0=BA=D0=B0:?= =?UTF-8?q?=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20?= =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=BD=D1=8B=D0=B5=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=9F=D0=9B=D0=9A,=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D1=81=D0=B8=D1=81=D1=82=D0=B5?= =?UTF-8?q?=D0=BC=D0=B0=20=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD=D0=B4=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D1=80=D0=BE=D0=B1=D0=BE=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- emulator.cpp | 22 ++--- emulator.h | 126 ++++++++++------------------- robot.cpp | 111 +++++++++++++++++++++++-- robot.h | 3 + scheduler.c | 96 +++++++++++++++++----- utils.c | 6 ++ utils.h | 215 +++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 461 insertions(+), 120 deletions(-) create mode 100644 utils.c create mode 100644 utils.h diff --git a/CMakeLists.txt b/CMakeLists.txt index aa3a8bb..9d64fbb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,6 @@ project(sdp_sheduler C CXX) set(CMAKE_C_STANDARD 17) set(CMAKE_CXX_STANDARD 17) -add_executable(sdp_sheduler scheduler.c emulator.cpp emulator.h robot.cpp robot.h) +add_executable(sdp_sheduler scheduler.c emulator.cpp emulator.h robot.cpp robot.h utils.c utils.h) add_executable(remote_listener remote_listener.cpp) diff --git a/emulator.cpp b/emulator.cpp index f68a96e..7852692 100644 --- a/emulator.cpp +++ b/emulator.cpp @@ -8,13 +8,8 @@ #include "emulator.h" #include "robot.h" -struct barrel barrels[BARRELS_COUNT]; - -struct robot_cmd robot1_cmd; -struct robot_cmd robot2_cmd; - -struct robot robot1; -struct robot robot2; +struct robot_regs robot1; +struct robot_regs robot2; char schedulerSoftwareTimer = 0; char schedulerUnloadButton = 0; @@ -27,6 +22,13 @@ static const int COLS = 23 * 5 + 1; static char buffer[ROWS][COLS]; static int current_tic = 0; +robot_code robot1_code{0, -1}; +robot_code robot2_code{0, -1}; + +short robot1_lock_zone = 0; +short robot2_lock_zone = 0; + + static int sock_fd; static void send_str(const char* str) { write(sock_fd, str, strlen(str)); @@ -135,7 +137,9 @@ static void showAll() { // рисуем роботов sprintf(tmp, "R1"); // image_insert_sprite(2 + (robot1.mz.is_up ? 0 : 2), (robot1.curr_zone * 5) + 2, tmp); - image_insert_sprite(2 + (robot1.mz.is_up ? 0 : 2), (robot1.curr_zone * 5) + 2, tmp); + image_insert_sprite(2 + (robot1.mz.is_up ? 0 : 2), + (robot1.dx.current_zone * 5) + 2 + (robot1_offset_pos * 2), + tmp); // sprintf(tmp, "R2"); // image_insert_sprite(3 + (robot2.mz.is_up ? 0 : 2), (robot2.curr_zone * 5) + 2, tmp); @@ -176,7 +180,7 @@ int main() { open_socket(); // for (auto & b : barrels) { -// b.flags.is_exist = 1; +// b.barrel_flags.is_exist = 1; // b.software_timer = (short)(random() % 50); // b.zone = (short) abs(random() % 20); // } diff --git a/emulator.h b/emulator.h index bb59199..bcf6090 100644 --- a/emulator.h +++ b/emulator.h @@ -1,94 +1,14 @@ -// -// Created by Владислав Остапов on 27.10.2022. -// - #ifndef SDP_SHEDULER_EMULATOR_H #define SDP_SHEDULER_EMULATOR_H -#include - -#define BARRELS_COUNT 10 - -union flags { - int16_t raw_word; - struct { - char is_exist: 1; - char is_up: 1; // для панели - char robot: 2; // обслуживающий робот - int _unused: 11; - }; -}; - -struct barrel { - union flags flags; - short zone; - short software_timer; - short curr_process; // стадия процесса - - // время процессов - // TODO сделать это как union, чтобы можно было юзать как таблицу - short time_defatting; // Время обезжиривания - short time_washing_1a; // Время промывки 1А - short time_washing_1b; // Время промывки 1Б - short time_etching; // Время травления - short time_washing_2a; // Время промывки 2А - short time_washing_2b; // Время промывки 2Б - short time_galvanizing; // Время цинкования - short time_washing_3a; // Время промывки 3А - short time_washing_3b; // Время промывки 3Б - short time_passivation; // Время пассивации - short time_washing_4a; // Время промывки 4А - short time_washing_4b; // Время промывки 4Б -}; - -enum BarrelProcess { - PROCESS_NONE = 0, // сразу после загрузки - PROCESS_DEFATTING, // обезжиривание - PROCESS_WASHING_1A, // промывка 1А - PROCESS_WASHING_1B, // промывка 1Б - PROCESS_ETCHING, // травление - PROCESS_WASHING_2A, // промывка 2А - PROCESS_WASHING_2B, // промывка 2Б - PROCESS_GALVANIZING, // цинкование - PROCESS_WASHING_3A, // промывка 3А - PROCESS_WASHING_3B, // промывка 3Б - PROCESS_PASSIVATION, // пассивация - PROCESS_WASHING_4B, // промывка 4Б - PROCESS_RETURN_1, // возвращение обратно, стадия 1 - перекладываем в свободную промывку (если есть) - PROCESS_RETURN_2, // возвращение обратно, стадия 2 - перекладываем в свободную загрузку и удалить барабан -}; - -struct robot_cmd { - short cmd; - short args[4]; - short step; -}; - - -union robot_flags_mz { - short raw_word; - struct { - char is_corrected: 1; - char is_up: 1; - }; -}; - -struct robot { - union robot_flags_mz mz; - short curr_zone; // пока будет достаточно этого -}; +#include "utils.h" #ifdef __cplusplus extern "C" { #endif -extern struct barrel barrels[BARRELS_COUNT]; - -extern struct robot_cmd robot1_cmd; -extern struct robot_cmd robot2_cmd; - -extern struct robot robot1; -extern struct robot robot2; +extern struct robot_regs robot1; +extern struct robot_regs robot2; extern char schedulerSoftwareTimer; extern char schedulerUnloadButton; @@ -98,6 +18,46 @@ extern char schedulerOneRobotMode; void scheduler_main(); + +// Флаги, которые есть в оригинальной программе на ПЛК, в "C global variables" + +// Кнопки с панели +extern char hla_auto_mode; +extern char hla_night_mode; +extern char hla_pause; +extern char hla_correct_command; + + +// кнопки управления роботом с панели + + +// кнопка загрузки в зоне 0, означает что барабан надо изъять из этой загрузки (а перед этим создать) +extern char button_load; + +// разрешающий сигнал подавать не буду, он не нужен поскольку планировщик нужен всегда + +// кнопка выгрузки, означает что барабан нужно вернуть обратно +extern char button_unload; + +// кнопка загрузки в зоне 1, означает что барабан в этой зоне подлежит удалению +extern char button_unload_end; + +// кнопка загрузки в зоне 22, означает что барабан в этой зоне подлежит удалению +extern char button_unload_remove; + + +// Переменные, которые надо добавить в C Global variables + +// код для роботов +extern robot_code robot1_code; +extern robot_code robot2_code; + + +// lock-зоны, нельзя двигаться за них и за робота +extern short robot1_lock_zone; +extern short robot2_lock_zone; + + #ifdef __cplusplus } #endif diff --git a/robot.cpp b/robot.cpp index 4bb29b5..ffe0a0e 100644 --- a/robot.cpp +++ b/robot.cpp @@ -3,6 +3,11 @@ // #include "robot.h" +#include + +bool robot1_offset_pos = false; +bool robot2_offset_pos = false; + static short get_barrel(char robot_id) { for (short i = 0; i < BARRELS_COUNT; i++) { @@ -14,20 +19,27 @@ static short get_barrel(char robot_id) { } // true означает что движение закончено -static bool robot_move(robot& r, int target, char robot_id) { - if (r.curr_zone == target) { +static bool robot_move(robot_regs& r, int target, char robot_id) { + // после перемещения мы явно в точной позиции + if (robot_id == 1) { + robot1_offset_pos = false; + } else { + robot2_offset_pos = false; + } + + if (r.dx.current_zone == target) { return true; } - if (r.curr_zone < target) { - r.curr_zone++; + if (r.dx.current_zone < target) { + r.dx.current_zone++; } else { - r.curr_zone--; + r.dx.current_zone--; } return false; } -static void emulate_robot(robot_cmd& cmd, robot& r, char robot_id) { +static void emulate_robot(robot_cmd& cmd, robot_regs& r, char robot_id) { auto barrel = get_barrel(robot_id); switch (cmd.cmd) { case 1: @@ -171,11 +183,96 @@ static void emulate_robot(robot_cmd& cmd, robot& r, char robot_id) { if (r.mz.is_up) { if (barrel != -1) { - barrels[barrel].zone = r.curr_zone; + barrels[barrel].zone = r.dx.current_zone; } } } + +static void emulate_robot_v2(robot_code* code, robot_regs& r, char robot_id) { + if (code->PC < 0) { + return; + } + const short cmd_arg = code->code[code->PC] & (~ROBOT_CMD_MASK); + + switch (code->code[code->PC] & ROBOT_CMD_MASK) { + case ROBOT_CMD_MOVE_TO_ZONE: + // двигаемся в сторону цели + if (robot_move(r, cmd_arg, robot_id)) { + code->PC++; + } + break; + + case ROBOT_CMD_MOVE_OFF: + if (robot_id == 1) { + robot1_offset_pos = true; + } else { + robot2_offset_pos = true; + } + code->PC++; + break; + + case ROBOT_CMD_UP: + if (code->barrel_id >= 0) { + barrels[code->barrel_id].flags.is_up = true; + r.mz.is_up = 1; + } + code->PC++; + break; + + // в эмуляторе не важно где я, поэтому тут обе команды вниз обрабатываются одинаково + case ROBOT_CMD_DOWN: + case ROBOT_CMD_DOWN_2: + if (code->barrel_id >= 0) { + barrels[code->barrel_id].flags.is_up = false; + r.mz.is_up = 0; + } + code->PC++; + break; + + case ROBOT_CMD_WAIT: + std::cout << "robot " << robot_id << " wait " << cmd_arg << " secs..." << std::endl; + code->PC++; + break; + + case ROBOT_CMD_TMR_SET: + if (code->barrel_id >= 0) { + barrels[code->barrel_id].software_timer = code->code[code->PC + 1]; + r.mz.is_up = 0; + } + code->PC += 2; + break; + + case ROBOT_CMD_SET_LOCK_ZONE: + if (robot_id == 1) { + robot1_lock_zone = cmd_arg; + } else { + robot2_lock_zone = cmd_arg; + } + code->PC += 2; + break; + + case ROBOT_CMD_CORRECT_X: + std::cout << "robot " << robot_id << " correct axis X..." << std::endl; + r.dz.current_zone = 0; + r.mx.correct_status = true; + code->PC++; + break; + + case ROBOT_CMD_CORRECT_Z: + std::cout << "robot " << robot_id << " correct axis Z..." << std::endl; + r.mz.is_up = true; + r.mz.correct_status = true; + code->PC++; + break; + + case ROBOT_CMD_END: + default: + code->PC = -1; + } +} + + void robot_main() { emulate_robot(robot1_cmd, robot1, 1); emulate_robot(robot2_cmd, robot2, 2); diff --git a/robot.h b/robot.h index cef7b50..8abe381 100644 --- a/robot.h +++ b/robot.h @@ -7,6 +7,9 @@ #include "emulator.h" +extern bool robot1_offset_pos; +extern bool robot2_offset_pos; + void robot_main(); #endif //SDP_SHEDULER_ROBOT_H diff --git a/scheduler.c b/scheduler.c index a2da4ae..c83fc64 100644 --- a/scheduler.c +++ b/scheduler.c @@ -22,8 +22,9 @@ static short get_robot_barrel(char robot_id) { return -1; } +// TODO обновить метод // вернет можно ли ехать и главное куда ехать, если можно (нельзя если вернулось значение < 0) -// -1 вренет что перемещать нельзя +// -1 вернет что перемещать нельзя // -2 вернет если требуется атомарная операция пассивации short can_move(struct barrel* bar) { // сразу отсекаем варианты, при которых невозможно переместить барабан @@ -90,7 +91,6 @@ short can_move(struct barrel* bar) { case PROCESS_WASHING_2B: // промывка 2Б, нужно цинкование (зоны 9-16) - // TODO сделать приоритет на барабан, который больше всего ждет if (!zone_is_busy(9 + galvanizing_zone)) { return 9 + galvanizing_zone; } @@ -164,34 +164,48 @@ short can_move(struct barrel* bar) { } +struct scheduler_task { + short start_zone; // стартовая зона + short dest_zone; // конечная зона + short priority; // приоритет, чем больше тем выше, по умолчанию 0 +}; + +// выставляет приоритет операции +short get_operation_priority(short barrel_id) { + // сделать приоритет на барабан, который больше всего ждет + +// task->priority = 0; +// switch (barrel_process) { +// case PROCESS_RETURN_2: +// break; +// } + + return 0; +} + + struct barrel makeBarrel(short flags, short zone, short timer, short process) { struct barrel b; b.flags.raw_word = flags; b.zone = zone; b.software_timer = timer; b.curr_process = process; - b.time_defatting = 6; - b.time_washing_1a = 2; - b.time_washing_1b = 3; - b.time_etching = 8; - b.time_washing_2a = 3; - b.time_washing_2b = 4; - b.time_galvanizing = 15; - b.time_washing_3a = 4; - b.time_washing_3b = 5; + b.time_defatting = 12; + b.time_washing_1a = 4; + b.time_washing_1b = 6; + b.time_etching = 16; + b.time_washing_2a = 6; + b.time_washing_2b = 8; + b.time_galvanizing = 30; + b.time_washing_3a = 8; + b.time_washing_3b = 10; b.time_passivation = 3; - b.time_washing_4a = 6; - b.time_washing_4b = 7; + b.time_washing_4a = 12; + b.time_washing_4b = 14; return b; } -struct scheduler_task { - short start_zone; // стартовая зона - short dest_zone; // конечная зона -}; - - static short scheduler_find_task(struct scheduler_task* tasks, const short curr_pos) { // ищем первый барабан слева, и ближайший справа short left = -1, right = -1; @@ -264,7 +278,7 @@ void schedule_robot_1() { // найти подходящую задачу if (schedulerOneRobotMode) { - short target_task = scheduler_find_task(tasks, robot1.curr_zone); + short target_task = scheduler_find_task(tasks, robot1.dx.current_zone); if (target_task >= 0) { // создаем транзакцию @@ -390,6 +404,48 @@ char create_barrel_in_load(short zone) { return 1; } +/* +=== ЦИКЛОГРАММА ПЕРЕТАСКИВАНИЯ БАРАБАНА === +// NOTE первой командой на любую транзакцию должна стоять команда опустить траверсу (в 22 зоне мы никогда не закончим, за нее не беспокоится) +* опустить траверсу +если зона изъятия != промывка 3б + если текущая зона != зона иъятия + если зона изъятия == 22 + * встать на смещенную + * поднять траверсу + * съебать в 21 зону + * встать на смещенную + * опустить траверсу не до конца + * съебать в 22 зону + иначе + * съебать в зону изъятия + * поднять траверсу + если зона изъятия != 22 и зона изъятия != 0: + * ждать скапывания (зависит от зоны) + * ехать в зону назначения + если зона назначения == 22 + * опустить траверсу не до конца + * съебать в 21 зону + если ЭНКОДЕРЫ СТАРЫЕ (по умолчанию) + * поднять траверсу + * опустить траверсу + иначе + * опустить траверсу + если зона назначения != 1 + * установить время ожидания барабана (зависит от зоны) +иначе + если текущая зона != промывка 3б + * съебать в промывку 3б + * поднять траверсу + * съебать в пассивацию + * опустить траверсу + * поставить время ожидания барабана в <время пассивации> + * поднять траверсу + * съебать в зону промывка 4а + * опустить траверсу + * установить время ожидания барабана (для промывки 4а) + */ + void scheduler_main() { // тут должно быть удаление барабана из зоны 1, если он там есть // if (schedulerLoadButton1) { diff --git a/utils.c b/utils.c new file mode 100644 index 0000000..9b754de --- /dev/null +++ b/utils.c @@ -0,0 +1,6 @@ +#include "utils.h" + +struct barrel barrels[BARRELS_COUNT]; + +struct robot_cmd robot1_cmd; +struct robot_cmd robot2_cmd; diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..68723a9 --- /dev/null +++ b/utils.h @@ -0,0 +1,215 @@ +#ifndef SDP_SCHEDULER_UTILS_H +#define SDP_SCHEDULER_UTILS_H + + +// Все зоны линии +enum Zones { + ZONE_LOAD_1 = 0, // загрузка 0, используется как точка появления барабанов + ZONE_LOAD_2, // загрузка 1, используется как конечная точка барабанов + ZONE_DEGREASING, // обезжиривание + ZONE_WASHING_1A, // промывка 1А + ZONE_WASHING_1B, // промывка 1Б + ZONE_ETCHING_1, // травление 1 + ZONE_ETCHING_2, // травление 2 + ZONE_WASHING_2A, // промывка 2А + ZONE_WASHING_2B, // промывка 2Б + ZONE_GALVANIZING_1, // цинкование 1 + ZONE_GALVANIZING_2, // цинкование 2 + ZONE_GALVANIZING_3, // цинкование 3 + ZONE_GALVANIZING_4, // цинкование 4 + ZONE_GALVANIZING_5, // цинкование 5 + ZONE_GALVANIZING_6, // цинкование 6 + ZONE_GALVANIZING_7, // цинкование 7 + ZONE_GALVANIZING_8, // цинкование 8 + ZONE_WASHING_3A, // промывка 3А + ZONE_WASHING_3B, // промывка 3Б + ZONE_PASSIVATION, // пассивация + ZONE_WASHING_4A, // промывка 4A + ZONE_WASHING_4B, // промывка 4Б + ZONE_UNLOAD, // зона выгрузки +}; + + +#define BARRELS_COUNT 10 + +union barrel_flags { + short raw_word; + struct { + char is_exist: 1; + char is_up: 1; // для панели + char robot: 2; // обслуживающий робот + char is_night: 1; // ночной барабан, имеет такой статус если он в промывке в ночном режиме или в промывке, + // но пока не дождался очереди на выход из ночного режима + char is_empty: 1; // пустой барабан, нужен для работы операции возврата + }; +}; + +struct barrel { + union barrel_flags flags; + short zone; + // программный таймер, тикает сразу у всех барабанов, + short software_timer; + short curr_process; // стадия процесса + + // время процессов + short time_defatting; // Время обезжиривания + short time_washing_1a; // Время промывки 1А + short time_washing_1b; // Время промывки 1Б + short time_etching; // Время травления + short time_washing_2a; // Время промывки 2А + short time_washing_2b; // Время промывки 2Б + short time_galvanizing; // Время цинкования + short time_washing_3a; // Время промывки 3А + short time_washing_3b; // Время промывки 3Б + short time_passivation; // Время пассивации + short time_washing_4a; // Время промывки 4А + short time_washing_4b; // Время промывки 4Б +}; + +// deprecated: do not use! +enum BarrelProcess { + PROCESS_NONE = 0, // сразу после загрузки + PROCESS_DEFATTING, // обезжиривание + PROCESS_WASHING_1A, // промывка 1А + PROCESS_WASHING_1B, // промывка 1Б + PROCESS_ETCHING, // травление + PROCESS_WASHING_2A, // промывка 2А + PROCESS_WASHING_2B, // промывка 2Б + PROCESS_GALVANIZING, // цинкование + PROCESS_WASHING_3A, // промывка 3А + PROCESS_WASHING_3B, // промывка 3Б + PROCESS_PASSIVATION, // пассивация + PROCESS_WASHING_4B, // промывка 4Б + PROCESS_RETURN_1, // возвращение обратно, стадия 1 - перекладываем в свободную промывку (если есть) + PROCESS_RETURN_2, // возвращение обратно, стадия 2 - перекладываем в свободную загрузку и удалить барабан +}; + +struct robot_cmd { + short cmd; + short args[2]; + short step; +}; + + +union robot_regs_mx { + short raw_word; + struct { + char correct_status: 1; + char last_cmd_executed: 1; + char correct_sensor: 1; + char move_to_zone: 1; + char move_to_offset: 1; + char move_to_precise: 1; + char do_correct: 1; + char do_parking: 1; + char hla_left: 1; + char hla_right: 1; + char auto_mode: 1; + char error: 1; + }; +}; + +union robot_regs_dx { + short raw_data[6]; + struct { + short current_zone; + short target_zone; + short left_max; + short right_max; + short output_current; + short output_freq; + }; +}; + +union robot_regs_mz { + short raw_word; + struct { + char correct_status: 1; + char last_cmd_executed: 1; + char is_up: 1; + char move_up: 1; + char move_down: 1; + char do_correct: 1; + char hla_up: 1; + char hla_down: 1; + char auto_mode: 1; + char error: 1; + }; +}; + +union robot_regs_dz { + short raw_data[3]; + struct { + short current_zone; + short output_current; + short output_freq; + }; +}; + +struct robot_regs { + union robot_regs_mx mx; + union robot_regs_dx dx; + union robot_regs_mz mz; + union robot_regs_dz dz; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct barrel barrels[BARRELS_COUNT]; + +extern struct robot_cmd robot1_cmd; +extern struct robot_cmd robot2_cmd; + +// почему-то компилер говорит что размер структуру сраный +//extern struct robot robot1; +//extern struct robot robot2; + +#define ROBOT_CMD_MASK 0xF000 +#define ROBOT_CMD_END 0x0000 +#define ROBOT_CMD_MOVE_TO_ZONE 0x1000 +#define ROBOT_CMD_MOVE_OFF 0x2000 +#define ROBOT_CMD_UP 0x3000 +#define ROBOT_CMD_DOWN 0x4000 +#define ROBOT_CMD_DOWN_2 0x5000 +#define ROBOT_CMD_WAIT 0x6000 +#define ROBOT_CMD_TMR_SET 0x7000 +#define ROBOT_CMD_SET_LOCK_ZONE 0x8000 +#define ROBOT_CMD_CORRECT_X 0x9000 +#define ROBOT_CMD_CORRECT_Z 0xA000 + + +// NOTE первой командой на любую транзакцию должна стоять команда опустить траверсу (в 22 зоне по идее никогда не закончим) +struct robot_code { + short barrel_id; // нужен ID барабана, если + short PC; // когда -1, код не выполняется + + /* + * система команд, которая нужна: (квадратные скобки - аргумент это младший байт, фигурные - отдельное слово) + * 0: конец + * 1 [зона]: съебаться в зону + * 2: встать на смещенную позицию + * 3 [с барабаном]: поднять траверсу (перед выполнением ожидать если таймер барабана не истек) + * 4 [с барабаном]: опустить траверсу + * 5 [с барабаном]: опустить траверсу не до конца + * 6 [сек]: пауза на нужное количество секунд + * 7 {время}: установить таймер барабану + * 8 [зона]: установить зону блокировки + * 9: скорректировать ос X + * 10: скорректировать ос Z + * + * формат команды: (команда, старший байт) [младший байт, аргумент команды (если есть)] [слово, аргумент если команда требует] + */ + short code[16]; // формат кода: [команды] <команда 0> + +}; + + + + +#ifdef __cplusplus +} +#endif + +#endif //SDP_SCHEDULER_UTILS_H