25 changed files with 904 additions and 73 deletions
-
33src/main/java/com/iflytop/gd/common/notification/Notification.java
-
21src/main/java/com/iflytop/gd/infrastructure/drivers/AppErrorCode.java
-
122src/main/java/com/iflytop/gd/infrastructure/drivers/CmdId.java
-
98src/main/java/com/iflytop/gd/infrastructure/drivers/ModuleId.java
-
78src/main/java/com/iflytop/gd/infrastructure/drivers/RegIndex.java
-
98src/main/java/com/iflytop/gd/infrastructure/drivers/WebSocketCommandBusImpl.java
-
18src/main/java/com/iflytop/gd/system/constants/RotationDirection.java
-
46src/main/java/com/iflytop/gd/system/devices/BaseStepStepMotor.java
-
11src/main/java/com/iflytop/gd/system/devices/BinaryDevice.java
-
9src/main/java/com/iflytop/gd/system/devices/DoorStepMotor.java
-
2src/main/java/com/iflytop/gd/system/devices/Fan.java
-
2src/main/java/com/iflytop/gd/system/devices/Heater.java
-
2src/main/java/com/iflytop/gd/system/devices/Relay.java
-
2src/main/java/com/iflytop/gd/system/devices/ServoMotor.java
-
77src/main/java/com/iflytop/gd/system/devices/StepMotor.java
-
22src/main/java/com/iflytop/gd/system/drivers/CommandBus.java
-
34src/main/java/com/iflytop/gd/system/drivers/StepMotor.java
-
22src/main/java/com/iflytop/gd/system/exceptions/CommandExecTimeoutException.java
-
22src/main/java/com/iflytop/gd/system/exceptions/HardwareErrorException.java
-
83src/main/java/com/iflytop/gd/system/models/DataPacket.java
-
125src/main/java/com/iflytop/gd/system/utils/ByteArray.java
@ -0,0 +1,21 @@ |
|||
package com.iflytop.gd.infrastructure.drivers; |
|||
|
|||
public enum AppErrorCode { |
|||
APP_OK(200, "操作成功"), |
|||
FAIL(500, "操作失败"), |
|||
PARAM_ERROR(400, "参数错误"); |
|||
|
|||
private int code; |
|||
private String msg; |
|||
private AppErrorCode(int code, String msg) { |
|||
this.code = code; |
|||
this.msg = msg; |
|||
} |
|||
|
|||
public int getCode() { |
|||
return code; |
|||
} |
|||
public String getMsg() { |
|||
return msg; |
|||
} |
|||
} |
@ -0,0 +1,122 @@ |
|||
package com.iflytop.gd.infrastructure.drivers; |
|||
|
|||
|
|||
public enum CmdId { |
|||
NotSet(0xFFFF, "NOACTION"),// |
|||
|
|||
board_reset(0x0000, "复位板子"),// |
|||
event_bus_reg_change_report(0x0064, "寄存器修改事件"),// |
|||
// |
|||
|
|||
module_ping(0x0101, "MODULE_PING"), |
|||
module_stop(0x0102, "MODULE_STOP"), |
|||
|
|||
module_get_error(0x0110, "MODULE_GET_ERROR"), |
|||
module_get_detail_error(0x0111, "MODULE_GET_DETAIL_ERROR"), |
|||
module_clear_error(0x0112, "MODULE_CLEAR_ERROR"), |
|||
|
|||
module_set_reg(0x0120, "MODULE_SET_REG"), |
|||
module_get_reg(0x0121, "MODULE_GET_REG"), |
|||
module_reset_reg(0x0123, "MODULE_RESET_REG"), |
|||
|
|||
module_get_version(0x0130, "MODULE_GET_VERSION"), |
|||
module_get_type(0x0131, "MODULE_GET_TYPE"), |
|||
module_get_status(0x0132, "MODULE_GET_STATUS"), |
|||
|
|||
// 扩展板 |
|||
extboard_read_inio(0x6701, "EXTBOARD_READ_INIO"),// |
|||
extboard_write_outio(0x6702, "EXTBOARD_WRITE_OUTIO"),// |
|||
extboard_read_muti_inio(0x6703, "EXTBOARD_READ_MUTI_INIO"),// |
|||
extboard_read_inio_index_in_stm32(0x6704, "EXTBOARD_READ_INIO_INDEX_IN_STM32"),// |
|||
extboard_read_outio_index_in_stm32(0x6705, "EXTBOARD_READ_OUTIO_INDEX_IN_STM32"),// |
|||
extboard_read_outio(0x6706, "EXTBOARD_READ_OUTIO"),// |
|||
|
|||
// 补光灯模块 |
|||
module_pwm_light_on(0x0204, "MODULE_PWM_LIGHT_ON"), // 补光灯 开启 |
|||
module_pwm_light_off(0x0205, "MODULE_PWM_LIGHT_OFF"), // 补光灯 |
|||
|
|||
// 三色灯模块 |
|||
module_tricolor_light_on(0x0206, "MODULE_TRICOLOR_LIGHT_ON"), // 三色灯开启 |
|||
module_tricolor_light_off(0x0207, "MODULE_TRICOLOR_LIGHT_OFF"), // 三色灯 |
|||
|
|||
// IO 板卡 1 |
|||
module_io1_read_heat_rod_current(0x0207, "MODULE_IO_READ_HEAT_ROD_CURRENT"), // 读取加热棒电流 |
|||
|
|||
// IO 板卡 2 |
|||
|
|||
// 电机通用控制 |
|||
step_motor_enable(0x0201, "STEP_MOTOR_ENABLE"),// |
|||
step_motor_read_pos(0x020b, "STEP_MOTOR_READ_POS"),// |
|||
step_motor_read_enc_pos(0x020c, "STEP_MOTOR_READ_ENC_POS"),// |
|||
step_motor_easy_rotate(0x0211, "STEP_MOTOR_EASY_ROTATE"),// |
|||
step_motor_easy_move_by(0x0212, "STEP_MOTOR_EASY_MOVE_BY"),// |
|||
step_motor_easy_move_to(0x0213, "STEP_MOTOR_EASY_MOVE_TO"),// |
|||
step_motor_easy_move_to_zero(0x0214, "STEP_MOTOR_EASY_MOVE_TO_ZERO"),// |
|||
step_motor_easy_set_current_pos(0x0215, "STEP_MOTOR_EASY_SET_CURRENT_POS"),// |
|||
step_motor_easy_move_to_io(0x0216, "STEP_MOTOR_EASY_MOVE_TO_IO"),// |
|||
step_motor_stop(0x0228, "STEP_MOTOR_STOP"),// |
|||
step_motor_move_by(0x021d, "STEP_MOTOR_MOVE_BY"), // (dpos,speedlevel)->null speedlevel=0,1,2,3(default,low,mid,high) |
|||
step_motor_move_to(0x021e, "STEP_MOTOR_MOVE_TO"), // (pos,speedlevel)->null speedlevel=0,1,2,3(default,low,mid,high) |
|||
step_motor_move_to_zero_point_quick(0x021f, "STEP_MOTOR_MOVE_TO_ZERO_POINT_QUICK"), // (speedlevel)->null speedlevel=0,1,2,3(default,low,mid,high) |
|||
step_motor_rotate(0x0220, "STEP_MOTOR_ROTATE"), // |
|||
|
|||
step_motor_active_cfg(0x0229, "STEP_MOTOR_ACTIVE_CFG"),// |
|||
step_motor_read_io_state(0x022a, "STEP_MOTOR_READ_IO_STATE"),// |
|||
step_motor_easy_move_to_end_point(0x022c, "STEP_MOTOR_EASY_MOVE_TO_END_POINT"),// |
|||
step_motor_read_tmc5130_status(0x0232, "STEP_MOTOR_READ_TMC5130_STATUS"),// |
|||
step_motor_read_tmc5130_state(0x0233, "STEP_MOTOR_READ_TMC5130_STATE"),// |
|||
step_motor_read_io_index_in_stm32(0x0238, "STEP_MOTOR_READ_IO_INDEX_IN_STM32"),// |
|||
step_motor_set_subdevice_reg(0x0239, "STEP_MOTOR_SET_SUBDEVICE_REG"),// |
|||
step_motor_get_subdevice_reg(0x023a, "STEP_MOTOR_GET_SUBDEVICE_REG"),// |
|||
step_motor_easy_reciprocating_motion(0x022d, "STEP_MOTOR_EASY_RECIPROCATING_MOTION"),// |
|||
step_motor_easy_move_to_zero_point_quick(0x022e, "STEP_MOTOR_EASY_MOVE_TO_ZERO_POINT_QUICK"), |
|||
|
|||
|
|||
; |
|||
|
|||
public final static int ATTACH_IS_BYTES = 1; |
|||
public final static int ATTACH_IS_INT32 = 2; |
|||
public final int index; |
|||
public final String name; |
|||
|
|||
CmdId(int index, String chname) { |
|||
this.index = index; |
|||
this.name = chname; |
|||
} |
|||
|
|||
public int toInt() { |
|||
return index; |
|||
} |
|||
|
|||
public static CmdId valueOf(int val) { |
|||
CmdId[] values = CmdId.values(); |
|||
for (CmdId e : values) { |
|||
if (e.toInt() == val) |
|||
return e; |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public static String toString(int val) { |
|||
CmdId[] values = CmdId.values(); |
|||
for (CmdId e : values) { |
|||
if (e.toInt() == val) { |
|||
return e.toString(); |
|||
} |
|||
} |
|||
return "unknown(" + val + ")"; |
|||
} |
|||
|
|||
public String getName() { |
|||
return name; |
|||
} |
|||
|
|||
public Boolean eq(Integer index) { |
|||
return this.index == index; |
|||
} |
|||
|
|||
|
|||
public boolean isTrace() { |
|||
return true; |
|||
} |
|||
} |
@ -0,0 +1,98 @@ |
|||
package com.iflytop.gd.infrastructure.drivers; |
|||
|
|||
public enum ModuleId { |
|||
NotSet(0, "未设置"), |
|||
IO1Board(10, "台面 IO 板模块"), |
|||
PWMLight(11, "PWM 灯"), |
|||
TriColorLight(12, "三色灯"), |
|||
|
|||
IO2Board(30, "台下 IO 板模块"), |
|||
|
|||
DoorBoard(80, "门电机板模块"),// |
|||
DoorM(81, "门电机"), |
|||
|
|||
ShakeModBoard(90, "摇匀模组板"), // |
|||
ShakeModShakeM(91, "加液位摇匀电机"), // |
|||
|
|||
CapStorageBoard(100, "拍子存放板模块"), // |
|||
CapStorageM(101, "拍子存放电机"), // |
|||
|
|||
DualRobotAxis1Board(110, "双轴机械臂1轴板模块"),// |
|||
DualRobotAxis1M(111, "双轴机械臂1轴电机"), |
|||
DualRobotAxis2Board(120, "双轴机械臂2轴板模块"),// |
|||
DualRobotAxis2M(121, "双轴机械臂2轴电机"), |
|||
|
|||
HBotXBoard(130, "X轴板模块"),// |
|||
HBotXM(131, "X轴电机"), |
|||
HBotYBoard(140, "Y轴板模块"),// |
|||
HBotYM(141, "Y轴电机"), |
|||
HBotZBoard(150, "Z轴板模块"),// |
|||
HBotZM(151, "Z轴电机"), |
|||
|
|||
Heater1Board(160, "加热1板模块"),// |
|||
Heater1M(161, "加热1电机"), |
|||
Heater2Board(170, "加热2板模块"),// |
|||
Heater2M(171, "加热2电机"), |
|||
Heater3Board(180, "加热3板模块"),// |
|||
Heater3M(181, "加热3电机"), |
|||
Heater4Board(190, "加热4板模块"),// |
|||
Heater4M(191, "加热4电机"), |
|||
Heater5Board(200, "加热5板模块"),// |
|||
Heater5M(201, "加热5电机"), |
|||
Heater6Board(210, "加热6板模块"),// |
|||
Heater6M(211, "加热6电机"), |
|||
|
|||
AcidPump1Board(220, "加酸泵1板模块"),// |
|||
AcidPump1M(221, "加酸泵1电机"), |
|||
AcidPump2Board(230, "加酸泵2板模块"),// |
|||
AcidPump2M(231, "加酸泵2电机"), |
|||
AcidPump3Board(240, "加酸泵3板模块"),// |
|||
AcidPump3M(241, "加酸泵3电机"), |
|||
AcidPump4Board(250, "加酸泵4板模块"),// |
|||
AcidPump4M(251, "加酸泵4电机"), |
|||
AcidPump5Board(260, "泵5板模块"),// |
|||
AcidPump5M(261, "泵5电机"), |
|||
AcidPump6Board(270, "泵6板模块"),// |
|||
AcidPump6M(271, "泵6电机"), |
|||
AcidPump7Board(280, "泵7板模块"),// |
|||
AcidPump7M(281, "泵7电机"), |
|||
AcidPump8Board(290, "泵8板模块"),// |
|||
AcidPump8M(291, "泵8电机"), |
|||
; |
|||
|
|||
final public String name; |
|||
final public int index; |
|||
|
|||
ModuleId(int index, String name) { |
|||
this.name = name; |
|||
this.index = index; |
|||
} |
|||
|
|||
public int toInt() { |
|||
return index; |
|||
} |
|||
|
|||
|
|||
public static ModuleId valueOf(Integer val) { |
|||
return valueOf(val.intValue()); |
|||
} |
|||
|
|||
public static ModuleId valueOf(int val) { |
|||
ModuleId[] values = ModuleId.values(); |
|||
for (ModuleId e : values) { |
|||
if (e.toInt() == val) |
|||
return e; |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public static String toString(int val) { |
|||
ModuleId[] values = ModuleId.values(); |
|||
for (ModuleId e : values) { |
|||
if (e.toInt() == val) { |
|||
return e.toString(); |
|||
} |
|||
} |
|||
return "unknown(" + val + ")"; |
|||
} |
|||
} |
@ -0,0 +1,78 @@ |
|||
package com.iflytop.gd.infrastructure.drivers; |
|||
|
|||
/** |
|||
* @brief 寄存器索引 |
|||
*/ |
|||
public enum RegIndex { |
|||
|
|||
/*********************************************************************************************************************** |
|||
* 步进电机控制器 * |
|||
***********************************************************************************************************************/ |
|||
/*********************************************************************************************************************** |
|||
* step_motor start * |
|||
***********************************************************************************************************************/ |
|||
|
|||
kreg_step_motor_pos(10101), // 机器人x坐标 |
|||
kreg_step_motor_is_enable(10102), // 是否使能 |
|||
kreg_step_motor_dpos(10103), // 执行完上一条指令后的相对位移 |
|||
kreg_step_motor_has_move_zero(10104), // 是否回零 |
|||
// kreg_step_motor_shift(10150), // x偏移 |
|||
kreg_step_motor_shaft(10151), // x轴是否反转 |
|||
kreg_step_motor_one_circle_pulse(10152), // x轴一圈脉冲数 |
|||
kreg_step_motor_one_circle_pulse_denominator(10153), // 设置一圈脉冲数的分母 |
|||
kreg_step_motor_default_velocity(10154), // 默认速度 |
|||
kreg_step_motor_low_velocity(10155), // 低速 |
|||
kreg_step_motor_mid_velocity(10156), // 中速 |
|||
kreg_step_motor_high_velocity(10157), // 高速 |
|||
kreg_step_motor_ihold(10158), // 步进电机电流配置 |
|||
kreg_step_motor_irun(10159), // 步进电机电流配置 |
|||
kreg_step_motor_iholddelay(10160), // 步进电机电流配置 |
|||
kreg_step_motor_iglobalscaler(10161), // 步进电机电流配置 |
|||
kreg_step_motor_mres(10162), // 电机细分 |
|||
kreg_step_motor_run_to_zero_speed(10173), // 回零速度 |
|||
kreg_step_motor_look_zero_edge_speed(10175), // 找零边缘速度 |
|||
kreg_step_motor_max_d(10178), // 最大限制距离 |
|||
kreg_step_motor_min_d(10179), // 最小限制距离 |
|||
kreg_step_motor_in_debug_mode(10180), // 驱动器处于调试模式 |
|||
kreg_step_motor_vstart(10181), // a1起作用的速度 |
|||
kreg_step_motor_a1(10182), // |
|||
kreg_step_motor_amax(10183), // |
|||
kreg_step_motor_v1(10184), // |
|||
kreg_step_motor_dmax(10185), // |
|||
kreg_step_motor_d1(10186), // |
|||
kreg_step_motor_vstop(10187), // |
|||
kreg_step_motor_tzerowait(10188), // |
|||
kreg_step_motor_enc_resolution(10189), // 编码器分辨率 1000,1024,4000,4096,16384 |
|||
kreg_step_motor_enable_enc(10190), // |
|||
kreg_step_motor_dzero_pos(10191), // 驱动器处于调试模式 |
|||
kret_step_motor_pos_devi_tolerance(10192), // 位置偏差容忍度 |
|||
kret_step_motor_io_trigger_append_distance(10193), // 移动到io时,附加的距离 |
|||
|
|||
/*********************************************************************************************************************** |
|||
* step_motor end * |
|||
***********************************************************************************************************************/ |
|||
; |
|||
|
|||
public final int index; |
|||
public final Boolean trace; |
|||
|
|||
RegIndex(int regIndex) { |
|||
this.index = regIndex; |
|||
this.trace = true; |
|||
} |
|||
|
|||
RegIndex(int regIndex, Boolean trace) { |
|||
this.index = regIndex; |
|||
this.trace = trace; |
|||
} |
|||
|
|||
public static RegIndex valueOf(int val) { |
|||
RegIndex[] values = RegIndex.values(); |
|||
for (RegIndex regindex : values) { |
|||
if (regindex.index == val) { |
|||
return regindex; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
} |
@ -0,0 +1,98 @@ |
|||
package com.iflytop.gd.infrastructure.drivers; |
|||
|
|||
import cn.hutool.core.util.ObjectUtil; |
|||
import com.iflytop.gd.common.exception.AppException; |
|||
import com.iflytop.gd.system.drivers.CommandBus; |
|||
import com.iflytop.gd.system.exceptions.CommandExecTimeoutException; |
|||
import com.iflytop.gd.system.exceptions.HardwareErrorException; |
|||
import com.iflytop.gd.system.models.DataPacket; |
|||
import com.iflytop.gd.system.utils.ByteArray; |
|||
import jakarta.websocket.*; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Component; |
|||
import org.springframework.web.socket.client.WebSocketClient; |
|||
|
|||
import java.io.IOException; |
|||
import java.util.concurrent.CountDownLatch; |
|||
import java.util.concurrent.TimeUnit; |
|||
import java.util.concurrent.atomic.AtomicReference; |
|||
import java.util.concurrent.locks.ReentrantLock; |
|||
|
|||
|
|||
@Slf4j |
|||
@Component |
|||
@ClientEndpoint |
|||
public class WebSocketCommandBusImpl implements CommandBus { |
|||
private Session session; |
|||
private WebSocketClient webSocketClient; |
|||
private CountDownLatch countDownLatch; |
|||
private DataPacket lastDataPacket; |
|||
|
|||
|
|||
|
|||
public static final int PACKET_TYPE_CMD = 0xA0; |
|||
public static final int PACKET_TYPE_ACK = 0xA1; |
|||
public static final int PACKET_TYPE_ERROR_ACK = 0xA2; |
|||
public static final int PACKET_TYPE_EVENT = 0xA3; |
|||
@Override |
|||
public synchronized DataPacket waitForCommandExec(DataPacket commandPacket, Integer timeout, TimeUnit unit) |
|||
throws CommandExecTimeoutException, HardwareErrorException, IOException, InterruptedException { |
|||
try { |
|||
this.countDownLatch = new CountDownLatch(1); |
|||
this.session.getBasicRemote().sendText(commandPacket.toByteString()); |
|||
boolean isTimeout = this.countDownLatch.await(timeout, unit); |
|||
// 命令返回或者超时了 |
|||
if (isTimeout) { |
|||
// TODO处理超时 |
|||
throw new CommandExecTimeoutException(); |
|||
} |
|||
if (this.lastDataPacket.getPacketType() == PACKET_TYPE_ERROR_ACK) { |
|||
log.error("moduleId={}执行command={}发送硬件错误", this.lastDataPacket.getModuleId(), this.lastDataPacket.getCmdId()); |
|||
throw new HardwareErrorException(); |
|||
} |
|||
return ObjectUtil.cloneByStream(this.lastDataPacket); |
|||
} catch (IOException e) { |
|||
log.error("发送指令发生异常", e); |
|||
throw e; |
|||
} catch (InterruptedException e) { |
|||
Thread.currentThread().getName(); |
|||
log.error(""); |
|||
throw e; |
|||
} |
|||
} |
|||
|
|||
|
|||
@OnOpen |
|||
public void onOpen(Session session) { |
|||
if (this.session != null) { |
|||
try { |
|||
this.session.close(); |
|||
} catch (IOException e) { |
|||
log.error(e.getMessage(), e); |
|||
} |
|||
} |
|||
this.session = session; |
|||
} |
|||
|
|||
@OnMessage |
|||
public void onMessage(String message) { |
|||
byte[] bytes = ByteArray.hexStringToBytes(message); |
|||
this.lastDataPacket = new DataPacket(bytes); |
|||
this.countDownLatch.countDown(); |
|||
} |
|||
|
|||
|
|||
@OnClose |
|||
public void onClose() { |
|||
if (this.countDownLatch != null) { |
|||
this.countDownLatch.countDown(); |
|||
} |
|||
} |
|||
|
|||
@OnError |
|||
public void onError(Session session, Throwable throwable) { |
|||
if (this.countDownLatch != null) { |
|||
this.countDownLatch.countDown(); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,18 @@ |
|||
package com.iflytop.gd.system.constants; |
|||
|
|||
import lombok.Getter; |
|||
|
|||
/** |
|||
* 电机转动方向 |
|||
*/ |
|||
@Getter |
|||
public enum RotationDirection { |
|||
Forward(1),Backward(-1); |
|||
|
|||
private Integer value; |
|||
|
|||
RotationDirection(Integer value) { |
|||
this.value = value; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,46 @@ |
|||
package com.iflytop.gd.system.devices; |
|||
|
|||
import com.iflytop.gd.infrastructure.drivers.CmdId; |
|||
import com.iflytop.gd.infrastructure.drivers.ModuleId; |
|||
import com.iflytop.gd.system.constants.DistanceUnit; |
|||
import com.iflytop.gd.system.constants.SpeedUnit; |
|||
import com.iflytop.gd.system.drivers.CommandBus; |
|||
import com.iflytop.gd.system.exceptions.CommandExecTimeoutException; |
|||
import com.iflytop.gd.system.exceptions.HardwareErrorException; |
|||
import com.iflytop.gd.system.models.DataPacket; |
|||
|
|||
import java.io.IOException; |
|||
import java.util.concurrent.TimeUnit; |
|||
|
|||
public abstract class BaseStepStepMotor implements StepMotor { |
|||
protected final ModuleId moduleId; |
|||
protected final CommandBus commandBus; |
|||
protected final Integer DEFAULT_COMMAND_EXEC_TIMEOUT_SECONDS = 10; |
|||
|
|||
protected BaseStepStepMotor(ModuleId moduleId, CommandBus commandBus) { |
|||
this.moduleId = moduleId; |
|||
this.commandBus = commandBus; |
|||
} |
|||
|
|||
|
|||
@Override |
|||
public void easyMoveTo(Integer value, DistanceUnit unit) { |
|||
DataPacket commandDataPacket = DataPacket.createCommandDataPacket(moduleId.index, CmdId.step_motor_easy_move_to.index, value); |
|||
try { |
|||
commandBus.waitForCommandExec(commandDataPacket, DEFAULT_COMMAND_EXEC_TIMEOUT_SECONDS, TimeUnit.SECONDS); |
|||
} catch (CommandExecTimeoutException e) { |
|||
throw new RuntimeException(e); |
|||
} catch (HardwareErrorException e) { |
|||
throw new RuntimeException(e); |
|||
} catch (IOException e) { |
|||
throw new RuntimeException(e); |
|||
} catch (InterruptedException e) { |
|||
throw new RuntimeException(e); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void easyMoveBy(Integer value, DistanceUnit unit) { |
|||
|
|||
} |
|||
} |
@ -0,0 +1,11 @@ |
|||
package com.iflytop.gd.system.devices; |
|||
|
|||
/** |
|||
* 开关类型设备驱动定义 |
|||
*/ |
|||
public interface BinaryDevice { |
|||
void open(); |
|||
void close(); |
|||
boolean isOpen(); |
|||
boolean isClosed(); |
|||
} |
@ -0,0 +1,9 @@ |
|||
package com.iflytop.gd.system.devices; |
|||
|
|||
/** |
|||
* 步进电机 |
|||
*/ |
|||
public class DoorStepMotor { |
|||
|
|||
|
|||
} |
@ -1,4 +1,4 @@ |
|||
package com.iflytop.gd.system.drivers; |
|||
package com.iflytop.gd.system.devices; |
|||
|
|||
/** |
|||
* 风扇 |
@ -1,4 +1,4 @@ |
|||
package com.iflytop.gd.system.drivers; |
|||
package com.iflytop.gd.system.devices; |
|||
|
|||
/** |
|||
* 加热器 |
@ -1,4 +1,4 @@ |
|||
package com.iflytop.gd.system.drivers; |
|||
package com.iflytop.gd.system.devices; |
|||
|
|||
/** |
|||
* 继电器 |
@ -1,4 +1,4 @@ |
|||
package com.iflytop.gd.system.drivers; |
|||
package com.iflytop.gd.system.devices; |
|||
|
|||
|
|||
/** |
@ -0,0 +1,77 @@ |
|||
package com.iflytop.gd.system.devices; |
|||
|
|||
import com.iflytop.gd.system.constants.DistanceUnit; |
|||
import com.iflytop.gd.system.constants.RotationDirection; |
|||
|
|||
/** |
|||
* 电机驱动类型设备 |
|||
*/ |
|||
public interface StepMotor { |
|||
|
|||
/** |
|||
* 移动指定距离 |
|||
* @param value |
|||
* @param unit |
|||
*/ |
|||
void easyMoveBy(Integer value, DistanceUnit unit); |
|||
|
|||
void easyMoveTo(Integer value, DistanceUnit unit); |
|||
|
|||
void easyMoveToZero(); |
|||
|
|||
void setCurrentPosition(Integer value); |
|||
|
|||
void easyMoveToZeroPointQuick(); |
|||
|
|||
void easyMoveToEndPoint(); |
|||
|
|||
/** |
|||
* 使能电机 |
|||
*/ |
|||
void enable(); |
|||
|
|||
/** |
|||
* 读取当前位置 |
|||
* @return |
|||
*/ |
|||
Integer readPosition(); |
|||
|
|||
/** |
|||
* 读取编码器位置 |
|||
* @return |
|||
*/ |
|||
Integer readEncoderPosition(); |
|||
|
|||
void easyRotate(RotationDirection direction); |
|||
|
|||
void easyMoveByBlock(); |
|||
|
|||
void easyMoveToBlock(); |
|||
|
|||
void easyMoveToZeroBlock(); |
|||
|
|||
void readPositionByMoveToZeroBlock(); |
|||
|
|||
void easyMoveToZeroPointQuickBlock(); |
|||
|
|||
void stop(); |
|||
|
|||
void moveByBlock(); |
|||
|
|||
void moveTOBlock(); |
|||
|
|||
void rotate(); |
|||
|
|||
Boolean readIOState(); |
|||
|
|||
void easyReciprocatingMotion(); |
|||
|
|||
void easyReciprocatingMotionBlock(); |
|||
|
|||
Boolean isReturnToZero(); |
|||
|
|||
void setReg(); |
|||
|
|||
Integer readReg(); |
|||
|
|||
} |
@ -0,0 +1,22 @@ |
|||
package com.iflytop.gd.system.drivers; |
|||
|
|||
import com.iflytop.gd.common.exception.AppException; |
|||
import com.iflytop.gd.system.exceptions.CommandExecTimeoutException; |
|||
import com.iflytop.gd.system.exceptions.HardwareErrorException; |
|||
import com.iflytop.gd.system.models.DataPacket; |
|||
|
|||
import java.io.IOException; |
|||
import java.util.concurrent.TimeUnit; |
|||
|
|||
public interface CommandBus { |
|||
|
|||
/** |
|||
* 发送命令数据包并等待响应 |
|||
* @param commandPacket 命令数据包 |
|||
* @param timeout 等待超时事件 |
|||
* @param unit 超时时间单位 |
|||
* @return 响应数据包 |
|||
* @throws Exception |
|||
*/ |
|||
DataPacket waitForCommandExec(DataPacket commandPacket, Integer timeout, TimeUnit unit) throws CommandExecTimeoutException, HardwareErrorException, IOException, InterruptedException; |
|||
} |
@ -1,34 +0,0 @@ |
|||
package com.iflytop.gd.system.drivers; |
|||
|
|||
import com.iflytop.gd.system.constants.DistanceUnit; |
|||
import com.iflytop.gd.system.constants.SpeedUnit; |
|||
|
|||
/** |
|||
* 步进电机 |
|||
*/ |
|||
public interface StepMotor { |
|||
|
|||
/** |
|||
* 移动指定距离 |
|||
* @param value |
|||
* @param unit |
|||
*/ |
|||
void move(Integer value, DistanceUnit unit); |
|||
|
|||
/** |
|||
* 停止移动 |
|||
*/ |
|||
void stop(); |
|||
|
|||
/** |
|||
* 设置移动速度 |
|||
* @param value |
|||
* @param unit |
|||
*/ |
|||
void setSpeed(Integer value, SpeedUnit unit); |
|||
|
|||
/** |
|||
* 复位电机 |
|||
*/ |
|||
void reset(); |
|||
} |
@ -0,0 +1,22 @@ |
|||
package com.iflytop.gd.system.exceptions; |
|||
|
|||
public class CommandExecTimeoutException extends Exception{ |
|||
public CommandExecTimeoutException() { |
|||
} |
|||
|
|||
public CommandExecTimeoutException(String message) { |
|||
super(message); |
|||
} |
|||
|
|||
public CommandExecTimeoutException(String message, Throwable cause) { |
|||
super(message, cause); |
|||
} |
|||
|
|||
public CommandExecTimeoutException(Throwable cause) { |
|||
super(cause); |
|||
} |
|||
|
|||
public CommandExecTimeoutException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { |
|||
super(message, cause, enableSuppression, writableStackTrace); |
|||
} |
|||
} |
@ -0,0 +1,22 @@ |
|||
package com.iflytop.gd.system.exceptions; |
|||
|
|||
public class HardwareErrorException extends Exception{ |
|||
public HardwareErrorException() { |
|||
} |
|||
|
|||
public HardwareErrorException(String message) { |
|||
super(message); |
|||
} |
|||
|
|||
public HardwareErrorException(String message, Throwable cause) { |
|||
super(message, cause); |
|||
} |
|||
|
|||
public HardwareErrorException(Throwable cause) { |
|||
super(cause); |
|||
} |
|||
|
|||
public HardwareErrorException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { |
|||
super(message, cause, enableSuppression, writableStackTrace); |
|||
} |
|||
} |
@ -0,0 +1,83 @@ |
|||
package com.iflytop.gd.system.models; |
|||
|
|||
import com.iflytop.gd.system.utils.ByteArray; |
|||
|
|||
import java.nio.ByteBuffer; |
|||
import java.nio.ByteOrder; |
|||
|
|||
public class DataPacket { |
|||
public static final int PACKET_TYPE_OFFSET = 0; |
|||
public static final int CMDID_OFFSET = 1; |
|||
public static final int MODULE_ID_OFFSET = 3; |
|||
public static final int INDEX_OFFSET = 4; |
|||
public static final int DATA_LEN_OFFSET = 6; |
|||
public static final int DATA_OFFSET = 7; |
|||
|
|||
public static final int PACKET_MIN_LEN = 8;// |
|||
|
|||
public static final int CMD_OVERTIME = 1500; |
|||
|
|||
|
|||
public static final int PACKET_TYPE_CMD = 0xA0; |
|||
public static final int PACKET_TYPE_ACK = 0xA1; |
|||
public static final int PACKET_TYPE_ERROR_ACK = 0xA2; |
|||
public static final int PACKET_TYPE_EVENT = 0xA3; |
|||
|
|||
byte[] raw; |
|||
|
|||
public DataPacket(byte[] cmd) { |
|||
raw = new byte[cmd.length]; |
|||
System.arraycopy(cmd, 0, raw, 0, cmd.length); |
|||
} |
|||
|
|||
public String toByteString() { |
|||
return ByteArray.toByteString(raw); |
|||
} |
|||
|
|||
static public DataPacket createPacket(Integer moduleId, int packetType, Integer cmdId, Integer[] params) { |
|||
int bufferSize = DataPacket.PACKET_MIN_LEN + 4 * params.length; |
|||
ByteBuffer buffer = ByteBuffer.allocate(bufferSize); |
|||
buffer.order(ByteOrder.LITTLE_ENDIAN); |
|||
buffer.put((byte) (packetType & 0xff)); // packetType |
|||
buffer.putShort((short) (cmdId & 0xffff)); // cmdid |
|||
buffer.put((byte) (moduleId & 0xFF)); // moduleId |
|||
buffer.put((byte) 0x4C); // index |
|||
buffer.put((byte) 0x00); // index |
|||
buffer.put((byte) (params.length * 4)); // datalen |
|||
for (int value : params) { |
|||
buffer.putInt(value); |
|||
} |
|||
// int8_t checksum; |
|||
int checksum = 0; |
|||
for (int i = 0; i < bufferSize - 1; i++) { |
|||
checksum += buffer.get(i); |
|||
} |
|||
buffer.put((byte) checksum); |
|||
return new DataPacket(buffer.array()); |
|||
} |
|||
|
|||
|
|||
public static DataPacket createCommandDataPacket(Integer moduleId, Integer cmdId, Integer... params) { |
|||
return createPacket(moduleId, PACKET_TYPE_CMD, cmdId, params); |
|||
} |
|||
|
|||
public int getPacketIndex() { |
|||
return ByteArray.readU16bit(raw, INDEX_OFFSET); |
|||
} |
|||
|
|||
public int getCmdId() { |
|||
return ByteArray.readU16bit(raw, CMDID_OFFSET); |
|||
} |
|||
|
|||
public int getPacketType() { |
|||
return ByteArray.readU8bit(raw, PACKET_TYPE_OFFSET); |
|||
} |
|||
|
|||
public int getModuleId() { |
|||
return ByteArray.readU8bit(raw, MODULE_ID_OFFSET); |
|||
} |
|||
|
|||
public int getDataLen() { |
|||
return ByteArray.readU8bit(raw, DATA_LEN_OFFSET); |
|||
} |
|||
} |
@ -0,0 +1,125 @@ |
|||
// Source code is decompiled from a .class file using FernFlower decompiler. |
|||
package com.iflytop.gd.system.utils; |
|||
|
|||
import org.springframework.lang.NonNull; |
|||
|
|||
public class ByteArray { |
|||
public ByteArray() { |
|||
} |
|||
|
|||
public static int readU8bit(byte[] code, int index) { |
|||
if (index >= code.length) |
|||
return 0; |
|||
return code[index] & 255; |
|||
} |
|||
|
|||
public static int readS8bit(byte[] code, int index) { |
|||
if (index >= code.length) |
|||
return 0; |
|||
|
|||
return code[index]; |
|||
} |
|||
|
|||
public static int readU16bit(byte[] code, int index) { |
|||
if (index + 1 >= code.length) |
|||
return 0; |
|||
return (code[index + 1] & 255) << 8 | code[index] & 255; |
|||
} |
|||
|
|||
public static void setU16bit(byte[] code, int index, int value) { |
|||
code[index + 1] = (byte) (value >> 8); |
|||
code[index] = (byte) value; |
|||
} |
|||
|
|||
public static void setU8(byte[] code, int off, int value) { |
|||
code[off] = (byte) value; |
|||
} |
|||
|
|||
public static int readS16bit(byte[] code, int index) { |
|||
if (index + 1 >= code.length) |
|||
return 0; |
|||
|
|||
return code[index + 1] << 8 | code[index] & 255; |
|||
} |
|||
|
|||
public static int read32bit(byte[] code, int index) { |
|||
if (index + 3 >= code.length) |
|||
return 0; |
|||
return code[index + 3] << 24 | (code[index + 2] & 255) << 16 | (code[index + 1] & 255) << 8 | code[index] & 255; |
|||
} |
|||
|
|||
public static Integer[] read32bitArray(byte[] code) { |
|||
int count = code.length / 4; |
|||
Integer[] array = new Integer[count]; |
|||
for (int i = 0; i < count; i++) { |
|||
array[i] = read32bit(code, i * 4); |
|||
} |
|||
return array; |
|||
} |
|||
|
|||
public static Integer[] read16bitArray(byte[] code) { |
|||
int count = code.length / 2; |
|||
Integer[] array = new Integer[count]; |
|||
for (int i = 0; i < count; i++) { |
|||
array[i] = readS16bit(code, i * 2); |
|||
} |
|||
return array; |
|||
} |
|||
|
|||
public static Integer[] readU16bitArray(byte[] code) { |
|||
int count = code.length / 2; |
|||
Integer[] array = new Integer[count]; |
|||
for (int i = 0; i < count; i++) { |
|||
array[i] = readU16bit(code, i * 2); |
|||
} |
|||
return array; |
|||
} |
|||
|
|||
|
|||
public static String toByteString(byte[] arrary) { |
|||
StringBuilder sb = new StringBuilder(); |
|||
for (byte b : arrary) { |
|||
sb.append(String.format("%02X", b)); |
|||
} |
|||
return sb.toString(); |
|||
} |
|||
|
|||
public static byte[] hexStringToBytes(@NonNull String str) { |
|||
if (str.isEmpty()) { |
|||
return new byte[0]; |
|||
} else { |
|||
byte[] byteArray = new byte[str.length() / 2]; |
|||
for (int i = 0; i < byteArray.length; i++) { |
|||
int high = Character.digit(str.charAt(i * 2), 16); |
|||
int low = Character.digit(str.charAt(i * 2 + 1), 16); |
|||
if (high == -1 || low == -1) { |
|||
return null; |
|||
} |
|||
byteArray[i] = (byte) (high * 16 + low); |
|||
} |
|||
return byteArray; |
|||
} |
|||
} |
|||
|
|||
|
|||
public static byte[] concat(byte[]... arrays) { |
|||
int length = 0; |
|||
for (byte[] array : arrays) { |
|||
length += array.length; |
|||
} |
|||
|
|||
byte[] result = new byte[length]; |
|||
int destPos = 0; |
|||
for (byte[] array : arrays) { |
|||
System.arraycopy(array, 0, result, destPos, array.length); |
|||
destPos += array.length; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
// public static void main(String[] args) { |
|||
// byte[] bytes = new byte[]{0x01, 0x02, 0x03, 0x04}; |
|||
// System.out.println(toByteString(bytes)); |
|||
// } |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue