This repository has been archived on 2024-09-18. You can view files and clone it, but cannot push or open issues or pull requests.
sdp-scheduler/utils.h

416 lines
16 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 time_degreasing; // Время обезжиривания
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Б
};
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;
};
// NOTE первой командой на любую транзакцию должна стоять команда опустить траверсу (в 22 зоне по идее никогда не закончим)
struct robot_code {
short barrel_id; // нужен ID барабана, если
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>
};
#ifdef __cplusplus
extern "C" {
#endif
#ifdef EMULATOR
extern struct barrel barrels[BARRELS_COUNT];
extern struct robot_regs robot1;
extern struct robot_regs robot2;
extern struct robot_code robot1_code;
extern struct robot_code robot2_code;
// времена для барабанов, нужно копировать их только при создании барабанов
extern short hla_time_degreasing;
extern short hla_time_washing_1a;
extern short hla_time_washing_1b;
extern short hla_time_etching;
extern short hla_time_washing_2a;
extern short hla_time_washing_2b;
extern short hla_time_galvanizing;
extern short hla_time_washing_3a;
extern short hla_time_washing_3b;
extern short hla_time_passivation;
extern short hla_time_washing_4a;
extern short hla_time_washing_4b;
// времена скапывания, одинаковые для всех барабанов
extern short hla_time_digging;
extern short hla_time_reagent;
extern short hla_time_washing_1;
extern short hla_time_washing_2;
// выбор зоны промежуточной с панели
extern short hla_exchange_zone;
// выбор отключенных зон
extern short hla_disabled_zones;
extern char hla_robot1_en;
extern char hla_robot2_en;
// пауза для автоматического режима, при паузе идут таймера, но команды не могут быть выданы
extern char auto_mode_pause;
// Кнопки с панели
extern char hla_night_mode;
extern char hla_correct_command;
// разрешение на работу планировщика
extern char scheduler_en;
// сигнал инициализации планировщика, должен быть установлен по фронту разрешения на работу
extern char scheduler_start_signal;
extern short scheduler_stage;
#else
#define barrels ((struct barrel*)barrels_array)
#define robot1 (*((struct robot_regs*)&robot1_reg_mx))
#define robot2 (*((struct robot_regs*)&robot2_reg_mx))
#define robot1_code (*((struct robot_code*)_robot1_code_struct))
#define robot2_code (*((struct robot_code*)_robot2_code_struct))
// времена для барабанов, нужно копировать их только при создании барабанов
#define hla_time_degreasing _c_hla_time_degreasing
#define hla_time_washing_1a _c_hla_time_washing_1a
#define hla_time_washing_1b _c_hla_time_washing_1b
#define hla_time_etching _c_hla_time_etching
#define hla_time_washing_2a _c_hla_time_washing_2a
#define hla_time_washing_2b _c_hla_time_washing_2b
#define hla_time_galvanizing _c_hla_time_galvanizing
#define hla_time_washing_3a _c_hla_time_washing_3a
#define hla_time_washing_3b _c_hla_time_washing_3b
#define hla_time_passivation _c_hla_time_passivation
#define hla_time_washing_4a _c_hla_time_washing_4a
#define hla_time_washing_4b _c_hla_time_washing_4b
// времена скапывания, одинаковые для всех барабанов
#define hla_time_digging _c_hla_time_digging
#define hla_time_reagent _c_hla_time_reagent
#define hla_time_washing_1 _c_hla_time_washing_1
#define hla_time_washing_2 _c_hla_time_washing_2
#define hla_exchange_zone _c_hla_exchange_zone
#define hla_disabled_zones _c_hla_disabled_zones
#define hla_robot1_en _c_hla_robot1_en
#define hla_robot2_en _c_hla_robot2_en
#define auto_mode_pause _c_auto_mode_pause
#define hla_night_mode _c_hla_night_mode
#define hla_correct_command _c_hla_correct_command
#define scheduler_stage _c_scheduler_stage
#endif
extern const short NIGHT_ZONES[9];
#define ROBOT_CMD_MASK 0xF000U
#define ROBOT_CMD_END_code 0x0000U
#define ROBOT_CMD_MOVE_TO_ZONE_code 0x1000U
#define ROBOT_CMD_MOVE_OFF_code 0x2000U
#define ROBOT_CMD_MOVE_ACCURATE_code 0x3000U
#define ROBOT_CMD_UP_code 0x4000U
#define ROBOT_CMD_DOWN_code 0x5000U
#define ROBOT_CMD_WAIT_code 0x6000U
#define ROBOT_CMD_TMR_SET_code 0x7000U
#define ROBOT_CMD_SET_LOCK_ZONE_code 0x8000U
#define ROBOT_CMD_CORRECT_AXIS_code 0x9000U
#define ROBOT_CMD_INC_ZONE_code 0xA000U
// перемещение с барабаном
#define ROBOT_WITH_BARREL 0x0800U
// опции зон
#define ROBOT_ZONE_ETCH 0x0400U
#define ROBOT_ZONE_GAL 0x0200U
#define ROBOT_ZONE_PARKING 0x0100U
// опции коррекции осей
#define ROBOT_AXIS_X 1
#define ROBOT_AXIS_Z 2
// макросы для генерации команд
#define ROBOT_CMD_END() (ROBOT_CMD_END_code)
#define ROBOT_CMD_MOVE_TO_ZONE(zone) (ROBOT_CMD_MOVE_TO_ZONE_code | (unsigned short)(zone & 0x00FF))
#define ROBOT_CMD_MOVE_TO_ZONE_WITH_BARREL(zone) (ROBOT_CMD_MOVE_TO_ZONE_code | ROBOT_WITH_BARREL | (unsigned short)(zone & 0x00FF))
#define ROBOT_CMD_MOVE_TO_PARKING() (ROBOT_CMD_MOVE_TO_ZONE_code | ROBOT_ZONE_PARKING)
#define ROBOT_CMD_MOVE_OFF() (ROBOT_CMD_MOVE_OFF_code)
#define ROBOT_CMD_MOVE_ACCURATE() (ROBOT_CMD_MOVE_ACCURATE_code)
#define ROBOT_CMD_UP() (ROBOT_CMD_UP_code)
#define ROBOT_CMD_UP_WITH_BARREL() (ROBOT_CMD_UP_code | ROBOT_WITH_BARREL)
#define ROBOT_CMD_DOWN() (ROBOT_CMD_DOWN_code)
#define ROBOT_CMD_DOWN_WITH_BARREL() (ROBOT_CMD_DOWN_code | ROBOT_WITH_BARREL)
#define ROBOT_CMD_WAIT(time) (ROBOT_CMD_WAIT_code | (unsigned short)(time & 0x0FFF))
#define ROBOT_CMD_TMR_SET(time) ((ROBOT_CMD_TMR_SET_code) | (unsigned short)(time & 0x0FFF))
#define ROBOT_CMD_SET_LOCK_ZONE(zone) ((ROBOT_CMD_SET_LOCK_ZONE_code) | (unsigned short)(zone & 0x00FF))
#define ROBOT_CMD_CORRECT_AXIS(axis) (ROBOT_CMD_CORRECT_AXIS_code | (unsigned short)axis)
#define ROBOT_CMD_INC_ZONE(arg) (ROBOT_CMD_INC_ZONE_code | (unsigned short)(arg))
/* ======================== DISABLED ZONES DEFS ======================== */
#define DISABLED_ETCH_1 0x0001
#define DISABLED_ETCH_2 0x0002
#define DISABLED_ETCH 0x0003
#define DISABLED_GAL_1 0x0004
#define DISABLED_GAL_2 0x0008
#define DISABLED_GAL_3 0x0010
#define DISABLED_GAL_4 0x0020
#define DISABLED_GAL_5 0x0040
#define DISABLED_GAL_6 0x0080
#define DISABLED_GAL_7 0x0100
#define DISABLED_GAL_8 0x0200
#define DISABLED_GAL 0x03FC
/* ======================== IO DEFS ======================== */
#define ROBOT1_X 1
#define ROBOT1_Z 2
#define ROBOT2_X 3
#define ROBOT2_Z 4
#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
#define VFD_REG_D0_ADDR 4096
#define VFD_REG_M0_ADDR 2048
// смещение регистров M относительно M0
#define ROBOT_Z_CORRECT_STATUS_OFFSET 0
#define ROBOT_Z_CMD_EXECUTED_OFFSET 1
#define ROBOT_Z_CMD_UP_OFFSET 3
#define ROBOT_Z_CMD_DOWN_OFFSET 4
#define ROBOT_Z_CMD_CORRECT_OFFSET 5
#define ROBOT_X_CORRECT_STATUS_OFFSET 0
#define ROBOT_X_CMD_EXECUTED_OFFSET 1
#define ROBOT_X_CORRECT_SENSOR_OFFSET 2
#define ROBOT_X_CMD_MOVE_TO_ZONE_OFFSET 3
#define ROBOT_X_CMD_MOVE_TO_OFF_POS_OFFSET 4 // встать в смещенную позицию
#define ROBOT_X_CMD_MOVE_TO_COR_POS_OFFSET 5 // встать в точную позицию
#define ROBOT_X_CMD_CORRECT_OFFSET 6
#define ROBOT_X_CMD_CMD_PARKING_OFFSET 7
// смещение регистров D относительно D0
#define ROBOT_X_TARGET_ZONE_OFFSET 2
// адреса регистров в частотнике
#define ROBOT_Z_CORRECT_STATUS_ADDR VFD_REG_M0_ADDR
#define ROBOT_Z_CMD_EXECUTED_ADDR (VFD_REG_M0_ADDR + 1)
#define ROBOT_Z_CMD_UP_ADDR (VFD_REG_M0_ADDR + 3)
#define ROBOT_Z_CMD_DOWN_ADDR (VFD_REG_M0_ADDR + 4)
#define ROBOT_Z_CMD_CORRECT_ADDR (VFD_REG_M0_ADDR + 5)
#define ROBOT_X_CORRECT_STATUS_ADDR VFD_REG_M0_ADDR
#define ROBOT_X_CMD_EXECUTED_ADDR (VFD_REG_M0_ADDR + ROBOT_X_CMD_EXECUTED_OFFSET)
#define ROBOT_X_CORRECT_SENSOR_ADDR (VFD_REG_M0_ADDR + ROBOT_X_CORRECT_SENSOR_OFFSET)
#define ROBOT_X_CMD_MOVE_TO_ZONE_ADDR (VFD_REG_M0_ADDR + ROBOT_X_CMD_MOVE_TO_ZONE_OFFSET)
#define ROBOT_X_CMD_MOVE_TO_OFF_ADDR (VFD_REG_M0_ADDR + ROBOT_X_CMD_MOVE_TO_OFF_POS_OFFSET)
#define ROBOT_X_CMD_MOVE_TO_COR_ADDR (VFD_REG_M0_ADDR + ROBOT_X_CMD_MOVE_TO_COR_POS_OFFSET)
#define ROBOT_X_CMD_CORRECT_ADDR (VFD_REG_M0_ADDR + ROBOT_X_CMD_CORRECT_OFFSET)
#define ROBOT_X_CMD_PARKING_ADDR (VFD_REG_M0_ADDR + ROBOT_X_CMD_CMD_PARKING_OFFSET)
#define ROBOT_X_TARGET_ZONE_ADDR (VFD_REG_D0_ADDR + ROBOT_X_TARGET_ZONE_OFFSET)
char zone_is_busy(short zone);
#define ROBOT_1 1
#define ROBOT_2 2
#define ROBOT_NONE -1
short can_move(struct barrel *bar, char robot_id);
short get_operation_priority(short barrel_id);
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 zone ROBOT_ZONE_ETCH или ROBOT_ZONE_GAL. Для других значений функция вернет false.
* @return true, если выбранная зона цинкования или травления доступна
*/
char is_accessible_zone(short zone);
/**
* Инкрементировать зону цинкования или зону травления.
* @param zone ROBOT_ZONE_ETCH или ROBOT_ZONE_GAL. Для других значений функция вернет false.
* @return true, если существует хотя бы одна зона, куда можно положить баран. При любых ошибках вернет false.
*/
char increment_zone(short zone);
#ifdef EMULATOR
void debug_print_robot_code(const struct robot_code *code, const short robot_id, int fd);
#endif
#ifdef __cplusplus
}
#endif
#endif //SDP_SCHEDULER_UTILS_H