Подготовка к переписыванию планировщика: добавлены переменные на ПЛК, добавлена система команд для роботов
This commit is contained in:
parent
aa8d949323
commit
8f19d1b277
@ -4,6 +4,6 @@ project(sdp_sheduler C CXX)
|
|||||||
set(CMAKE_C_STANDARD 17)
|
set(CMAKE_C_STANDARD 17)
|
||||||
set(CMAKE_CXX_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)
|
add_executable(remote_listener remote_listener.cpp)
|
||||||
|
22
emulator.cpp
22
emulator.cpp
@ -8,13 +8,8 @@
|
|||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
#include "robot.h"
|
#include "robot.h"
|
||||||
|
|
||||||
struct barrel barrels[BARRELS_COUNT];
|
struct robot_regs robot1;
|
||||||
|
struct robot_regs robot2;
|
||||||
struct robot_cmd robot1_cmd;
|
|
||||||
struct robot_cmd robot2_cmd;
|
|
||||||
|
|
||||||
struct robot robot1;
|
|
||||||
struct robot robot2;
|
|
||||||
|
|
||||||
char schedulerSoftwareTimer = 0;
|
char schedulerSoftwareTimer = 0;
|
||||||
char schedulerUnloadButton = 0;
|
char schedulerUnloadButton = 0;
|
||||||
@ -27,6 +22,13 @@ static const int COLS = 23 * 5 + 1;
|
|||||||
static char buffer[ROWS][COLS];
|
static char buffer[ROWS][COLS];
|
||||||
static int current_tic = 0;
|
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 int sock_fd;
|
||||||
static void send_str(const char* str) {
|
static void send_str(const char* str) {
|
||||||
write(sock_fd, str, strlen(str));
|
write(sock_fd, str, strlen(str));
|
||||||
@ -135,7 +137,9 @@ static void showAll() {
|
|||||||
// рисуем роботов
|
// рисуем роботов
|
||||||
sprintf(tmp, "R1");
|
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.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");
|
// sprintf(tmp, "R2");
|
||||||
// image_insert_sprite(3 + (robot2.mz.is_up ? 0 : 2), (robot2.curr_zone * 5) + 2, tmp);
|
// image_insert_sprite(3 + (robot2.mz.is_up ? 0 : 2), (robot2.curr_zone * 5) + 2, tmp);
|
||||||
@ -176,7 +180,7 @@ int main() {
|
|||||||
open_socket();
|
open_socket();
|
||||||
|
|
||||||
// for (auto & b : barrels) {
|
// for (auto & b : barrels) {
|
||||||
// b.flags.is_exist = 1;
|
// b.barrel_flags.is_exist = 1;
|
||||||
// b.software_timer = (short)(random() % 50);
|
// b.software_timer = (short)(random() % 50);
|
||||||
// b.zone = (short) abs(random() % 20);
|
// b.zone = (short) abs(random() % 20);
|
||||||
// }
|
// }
|
||||||
|
126
emulator.h
126
emulator.h
@ -1,94 +1,14 @@
|
|||||||
//
|
|
||||||
// Created by Владислав Остапов on 27.10.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef SDP_SHEDULER_EMULATOR_H
|
#ifndef SDP_SHEDULER_EMULATOR_H
|
||||||
#define SDP_SHEDULER_EMULATOR_H
|
#define SDP_SHEDULER_EMULATOR_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "utils.h"
|
||||||
|
|
||||||
#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; // пока будет достаточно этого
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern struct barrel barrels[BARRELS_COUNT];
|
extern struct robot_regs robot1;
|
||||||
|
extern struct robot_regs robot2;
|
||||||
extern struct robot_cmd robot1_cmd;
|
|
||||||
extern struct robot_cmd robot2_cmd;
|
|
||||||
|
|
||||||
extern struct robot robot1;
|
|
||||||
extern struct robot robot2;
|
|
||||||
|
|
||||||
extern char schedulerSoftwareTimer;
|
extern char schedulerSoftwareTimer;
|
||||||
extern char schedulerUnloadButton;
|
extern char schedulerUnloadButton;
|
||||||
@ -98,6 +18,46 @@ extern char schedulerOneRobotMode;
|
|||||||
|
|
||||||
void scheduler_main();
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
111
robot.cpp
111
robot.cpp
@ -3,6 +3,11 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "robot.h"
|
#include "robot.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
bool robot1_offset_pos = false;
|
||||||
|
bool robot2_offset_pos = false;
|
||||||
|
|
||||||
|
|
||||||
static short get_barrel(char robot_id) {
|
static short get_barrel(char robot_id) {
|
||||||
for (short i = 0; i < BARRELS_COUNT; i++) {
|
for (short i = 0; i < BARRELS_COUNT; i++) {
|
||||||
@ -14,20 +19,27 @@ static short get_barrel(char robot_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// true означает что движение закончено
|
// true означает что движение закончено
|
||||||
static bool robot_move(robot& r, int target, char robot_id) {
|
static bool robot_move(robot_regs& r, int target, char robot_id) {
|
||||||
if (r.curr_zone == target) {
|
// после перемещения мы явно в точной позиции
|
||||||
|
if (robot_id == 1) {
|
||||||
|
robot1_offset_pos = false;
|
||||||
|
} else {
|
||||||
|
robot2_offset_pos = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r.dx.current_zone == target) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r.curr_zone < target) {
|
if (r.dx.current_zone < target) {
|
||||||
r.curr_zone++;
|
r.dx.current_zone++;
|
||||||
} else {
|
} else {
|
||||||
r.curr_zone--;
|
r.dx.current_zone--;
|
||||||
}
|
}
|
||||||
return false;
|
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);
|
auto barrel = get_barrel(robot_id);
|
||||||
switch (cmd.cmd) {
|
switch (cmd.cmd) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -171,11 +183,96 @@ static void emulate_robot(robot_cmd& cmd, robot& r, char robot_id) {
|
|||||||
|
|
||||||
if (r.mz.is_up) {
|
if (r.mz.is_up) {
|
||||||
if (barrel != -1) {
|
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() {
|
void robot_main() {
|
||||||
emulate_robot(robot1_cmd, robot1, 1);
|
emulate_robot(robot1_cmd, robot1, 1);
|
||||||
emulate_robot(robot2_cmd, robot2, 2);
|
emulate_robot(robot2_cmd, robot2, 2);
|
||||||
|
3
robot.h
3
robot.h
@ -7,6 +7,9 @@
|
|||||||
|
|
||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
|
|
||||||
|
extern bool robot1_offset_pos;
|
||||||
|
extern bool robot2_offset_pos;
|
||||||
|
|
||||||
void robot_main();
|
void robot_main();
|
||||||
|
|
||||||
#endif //SDP_SHEDULER_ROBOT_H
|
#endif //SDP_SHEDULER_ROBOT_H
|
||||||
|
96
scheduler.c
96
scheduler.c
@ -22,8 +22,9 @@ static short get_robot_barrel(char robot_id) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO обновить метод
|
||||||
// вернет можно ли ехать и главное куда ехать, если можно (нельзя если вернулось значение < 0)
|
// вернет можно ли ехать и главное куда ехать, если можно (нельзя если вернулось значение < 0)
|
||||||
// -1 вренет что перемещать нельзя
|
// -1 вернет что перемещать нельзя
|
||||||
// -2 вернет если требуется атомарная операция пассивации
|
// -2 вернет если требуется атомарная операция пассивации
|
||||||
short can_move(struct barrel* bar) {
|
short can_move(struct barrel* bar) {
|
||||||
// сразу отсекаем варианты, при которых невозможно переместить барабан
|
// сразу отсекаем варианты, при которых невозможно переместить барабан
|
||||||
@ -90,7 +91,6 @@ short can_move(struct barrel* bar) {
|
|||||||
|
|
||||||
case PROCESS_WASHING_2B:
|
case PROCESS_WASHING_2B:
|
||||||
// промывка 2Б, нужно цинкование (зоны 9-16)
|
// промывка 2Б, нужно цинкование (зоны 9-16)
|
||||||
// TODO сделать приоритет на барабан, который больше всего ждет
|
|
||||||
if (!zone_is_busy(9 + galvanizing_zone)) {
|
if (!zone_is_busy(9 + galvanizing_zone)) {
|
||||||
return 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 makeBarrel(short flags, short zone, short timer, short process) {
|
||||||
struct barrel b;
|
struct barrel b;
|
||||||
b.flags.raw_word = flags;
|
b.flags.raw_word = flags;
|
||||||
b.zone = zone;
|
b.zone = zone;
|
||||||
b.software_timer = timer;
|
b.software_timer = timer;
|
||||||
b.curr_process = process;
|
b.curr_process = process;
|
||||||
b.time_defatting = 6;
|
b.time_defatting = 12;
|
||||||
b.time_washing_1a = 2;
|
b.time_washing_1a = 4;
|
||||||
b.time_washing_1b = 3;
|
b.time_washing_1b = 6;
|
||||||
b.time_etching = 8;
|
b.time_etching = 16;
|
||||||
b.time_washing_2a = 3;
|
b.time_washing_2a = 6;
|
||||||
b.time_washing_2b = 4;
|
b.time_washing_2b = 8;
|
||||||
b.time_galvanizing = 15;
|
b.time_galvanizing = 30;
|
||||||
b.time_washing_3a = 4;
|
b.time_washing_3a = 8;
|
||||||
b.time_washing_3b = 5;
|
b.time_washing_3b = 10;
|
||||||
b.time_passivation = 3;
|
b.time_passivation = 3;
|
||||||
b.time_washing_4a = 6;
|
b.time_washing_4a = 12;
|
||||||
b.time_washing_4b = 7;
|
b.time_washing_4b = 14;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct scheduler_task {
|
|
||||||
short start_zone; // стартовая зона
|
|
||||||
short dest_zone; // конечная зона
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static short scheduler_find_task(struct scheduler_task* tasks, const short curr_pos) {
|
static short scheduler_find_task(struct scheduler_task* tasks, const short curr_pos) {
|
||||||
// ищем первый барабан слева, и ближайший справа
|
// ищем первый барабан слева, и ближайший справа
|
||||||
short left = -1, right = -1;
|
short left = -1, right = -1;
|
||||||
@ -264,7 +278,7 @@ void schedule_robot_1() {
|
|||||||
|
|
||||||
// найти подходящую задачу
|
// найти подходящую задачу
|
||||||
if (schedulerOneRobotMode) {
|
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) {
|
if (target_task >= 0) {
|
||||||
// создаем транзакцию
|
// создаем транзакцию
|
||||||
@ -390,6 +404,48 @@ char create_barrel_in_load(short zone) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=== ЦИКЛОГРАММА ПЕРЕТАСКИВАНИЯ БАРАБАНА ===
|
||||||
|
// NOTE первой командой на любую транзакцию должна стоять команда опустить траверсу (в 22 зоне мы никогда не закончим, за нее не беспокоится)
|
||||||
|
* опустить траверсу
|
||||||
|
если зона изъятия != промывка 3б
|
||||||
|
если текущая зона != зона иъятия
|
||||||
|
если зона изъятия == 22
|
||||||
|
* встать на смещенную
|
||||||
|
* поднять траверсу
|
||||||
|
* съебать в 21 зону
|
||||||
|
* встать на смещенную
|
||||||
|
* опустить траверсу не до конца
|
||||||
|
* съебать в 22 зону
|
||||||
|
иначе
|
||||||
|
* съебать в зону изъятия
|
||||||
|
* поднять траверсу
|
||||||
|
если зона изъятия != 22 и зона изъятия != 0:
|
||||||
|
* ждать скапывания (зависит от зоны)
|
||||||
|
* ехать в зону назначения
|
||||||
|
если зона назначения == 22
|
||||||
|
* опустить траверсу не до конца
|
||||||
|
* съебать в 21 зону
|
||||||
|
если ЭНКОДЕРЫ СТАРЫЕ (по умолчанию)
|
||||||
|
* поднять траверсу
|
||||||
|
* опустить траверсу
|
||||||
|
иначе
|
||||||
|
* опустить траверсу
|
||||||
|
если зона назначения != 1
|
||||||
|
* установить время ожидания барабана (зависит от зоны)
|
||||||
|
иначе
|
||||||
|
если текущая зона != промывка 3б
|
||||||
|
* съебать в промывку 3б
|
||||||
|
* поднять траверсу
|
||||||
|
* съебать в пассивацию
|
||||||
|
* опустить траверсу
|
||||||
|
* поставить время ожидания барабана в <время пассивации>
|
||||||
|
* поднять траверсу
|
||||||
|
* съебать в зону промывка 4а
|
||||||
|
* опустить траверсу
|
||||||
|
* установить время ожидания барабана (для промывки 4а)
|
||||||
|
*/
|
||||||
|
|
||||||
void scheduler_main() {
|
void scheduler_main() {
|
||||||
// тут должно быть удаление барабана из зоны 1, если он там есть
|
// тут должно быть удаление барабана из зоны 1, если он там есть
|
||||||
// if (schedulerLoadButton1) {
|
// if (schedulerLoadButton1) {
|
||||||
|
6
utils.c
Normal file
6
utils.c
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
struct barrel barrels[BARRELS_COUNT];
|
||||||
|
|
||||||
|
struct robot_cmd robot1_cmd;
|
||||||
|
struct robot_cmd robot2_cmd;
|
215
utils.h
Normal file
215
utils.h
Normal file
@ -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
|
Reference in New Issue
Block a user