Browse Source

feat:实现步进电机接口定义和命令总线消息发送功能;

tags/freeze
黄翔 3 months ago
parent
commit
6de9098060
  1. 33
      src/main/java/com/iflytop/gd/common/notification/Notification.java
  2. 21
      src/main/java/com/iflytop/gd/infrastructure/drivers/AppErrorCode.java
  3. 122
      src/main/java/com/iflytop/gd/infrastructure/drivers/CmdId.java
  4. 98
      src/main/java/com/iflytop/gd/infrastructure/drivers/ModuleId.java
  5. 78
      src/main/java/com/iflytop/gd/infrastructure/drivers/RegIndex.java
  6. 98
      src/main/java/com/iflytop/gd/infrastructure/drivers/WebSocketCommandBusImpl.java
  7. 18
      src/main/java/com/iflytop/gd/system/constants/RotationDirection.java
  8. 46
      src/main/java/com/iflytop/gd/system/devices/BaseStepStepMotor.java
  9. 11
      src/main/java/com/iflytop/gd/system/devices/BinaryDevice.java
  10. 9
      src/main/java/com/iflytop/gd/system/devices/DoorStepMotor.java
  11. 2
      src/main/java/com/iflytop/gd/system/devices/Fan.java
  12. 2
      src/main/java/com/iflytop/gd/system/devices/Heater.java
  13. 2
      src/main/java/com/iflytop/gd/system/devices/Relay.java
  14. 2
      src/main/java/com/iflytop/gd/system/devices/ServoMotor.java
  15. 77
      src/main/java/com/iflytop/gd/system/devices/StepMotor.java
  16. 22
      src/main/java/com/iflytop/gd/system/drivers/CommandBus.java
  17. 34
      src/main/java/com/iflytop/gd/system/drivers/StepMotor.java
  18. 22
      src/main/java/com/iflytop/gd/system/exceptions/CommandExecTimeoutException.java
  19. 22
      src/main/java/com/iflytop/gd/system/exceptions/HardwareErrorException.java
  20. 83
      src/main/java/com/iflytop/gd/system/models/DataPacket.java
  21. 125
      src/main/java/com/iflytop/gd/system/utils/ByteArray.java

33
src/main/java/com/iflytop/gd/common/notification/Notification.java

@ -10,13 +10,26 @@ import lombok.Getter;
@Getter @Getter
public class Notification { public class Notification {
private final String commandId;
private final String command;
private final String level; private final String level;
private final String content;
private final String title;
private String content = null;
private final String dateTime = DateTime.now().toString("yyyy/MM/dd HH:mm:ss"); private final String dateTime = DateTime.now().toString("yyyy/MM/dd HH:mm:ss");
private Notification(String level, String content) {
private Notification(String commandId, String command, String level, String title, String content) {
this.commandId = commandId;
this.level = level; this.level = level;
this.title = title;
this.content = content; this.content = content;
this.command = command;
}
private Notification(String commandId, String command, String level, String title) {
this.commandId = commandId;
this.level = level;
this.title = title;
this.command = command;
} }
/** /**
@ -24,8 +37,8 @@ public class Notification {
* @param content 通知内容 * @param content 通知内容
* @return 通知实例 * @return 通知实例
*/ */
public static Notification infoNotification(String content) {
return new Notification("info", content);
public static Notification infoNotification(String commandId, String command, String title, String content) {
return new Notification(commandId, command, "info", title, content);
} }
@ -34,8 +47,8 @@ public class Notification {
* @param content 通知内容 * @param content 通知内容
* @return 通知实例 * @return 通知实例
*/ */
public static Notification warnNotification(String content) {
return new Notification("warn", content);
public static Notification warnNotification(String commandId, String command, String title, String content) {
return new Notification(commandId, command, "warn", title, content);
} }
/** /**
@ -43,8 +56,8 @@ public class Notification {
* @param content 通知内容 * @param content 通知内容
* @return 通知实例 * @return 通知实例
*/ */
public static Notification errorNotification(String content) {
return new Notification("error", content);
public static Notification errorNotification(String commandId, String command, String title, String content) {
return new Notification(commandId, command, "error", title, content);
} }
@ -53,8 +66,8 @@ public class Notification {
* @param content 通知内容 * @param content 通知内容
* @return 通知实例 * @return 通知实例
*/ */
public static Notification fatalNotification(String content) {
return new Notification("fatal", content);
public static Notification fatalNotification(String commandId, String command, String title, String content) {
return new Notification(commandId, command, "fatal", title, content);
} }

21
src/main/java/com/iflytop/gd/infrastructure/drivers/AppErrorCode.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;
}
}

122
src/main/java/com/iflytop/gd/infrastructure/drivers/CmdId.java

@ -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;
}
}

98
src/main/java/com/iflytop/gd/infrastructure/drivers/ModuleId.java

@ -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 + ")";
}
}

78
src/main/java/com/iflytop/gd/infrastructure/drivers/RegIndex.java

@ -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;
}
}

98
src/main/java/com/iflytop/gd/infrastructure/drivers/WebSocketCommandBusImpl.java

@ -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();
}
}
}

18
src/main/java/com/iflytop/gd/system/constants/RotationDirection.java

@ -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;
}
}

46
src/main/java/com/iflytop/gd/system/devices/BaseStepStepMotor.java

@ -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) {
}
}

11
src/main/java/com/iflytop/gd/system/devices/BinaryDevice.java

@ -0,0 +1,11 @@
package com.iflytop.gd.system.devices;
/**
* 开关类型设备驱动定义
*/
public interface BinaryDevice {
void open();
void close();
boolean isOpen();
boolean isClosed();
}

9
src/main/java/com/iflytop/gd/system/devices/DoorStepMotor.java

@ -0,0 +1,9 @@
package com.iflytop.gd.system.devices;
/**
* 步进电机
*/
public class DoorStepMotor {
}

2
src/main/java/com/iflytop/gd/system/drivers/Fan.java → src/main/java/com/iflytop/gd/system/devices/Fan.java

@ -1,4 +1,4 @@
package com.iflytop.gd.system.drivers;
package com.iflytop.gd.system.devices;
/** /**
* 风扇 * 风扇

2
src/main/java/com/iflytop/gd/system/drivers/Heater.java → src/main/java/com/iflytop/gd/system/devices/Heater.java

@ -1,4 +1,4 @@
package com.iflytop.gd.system.drivers;
package com.iflytop.gd.system.devices;
/** /**
* 加热器 * 加热器

2
src/main/java/com/iflytop/gd/system/drivers/Relay.java → src/main/java/com/iflytop/gd/system/devices/Relay.java

@ -1,4 +1,4 @@
package com.iflytop.gd.system.drivers;
package com.iflytop.gd.system.devices;
/** /**
* 继电器 * 继电器

2
src/main/java/com/iflytop/gd/system/drivers/ServoMotor.java → src/main/java/com/iflytop/gd/system/devices/ServoMotor.java

@ -1,4 +1,4 @@
package com.iflytop.gd.system.drivers;
package com.iflytop.gd.system.devices;
/** /**

77
src/main/java/com/iflytop/gd/system/devices/StepMotor.java

@ -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();
}

22
src/main/java/com/iflytop/gd/system/drivers/CommandBus.java

@ -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;
}

34
src/main/java/com/iflytop/gd/system/drivers/StepMotor.java

@ -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();
}

22
src/main/java/com/iflytop/gd/system/exceptions/CommandExecTimeoutException.java

@ -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);
}
}

22
src/main/java/com/iflytop/gd/system/exceptions/HardwareErrorException.java

@ -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);
}
}

83
src/main/java/com/iflytop/gd/system/models/DataPacket.java

@ -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);
}
}

125
src/main/java/com/iflytop/gd/system/utils/ByteArray.java

@ -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));
// }
}
Loading…
Cancel
Save