diff --git a/README.md b/README.md index 551c83b..98ec2d3 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,15 @@ TODO: 1. 数据库文件是否被破坏检查 2. 数据库文件如果被破坏,自动恢复默认配置 + + 舵机位置约定: + 1.抓手夹紧位置为1800 + + +``` + +``` ``` diff --git a/src/main/java/a8k/a8k_can_protocol/ModuleStatus.java b/src/main/java/a8k/a8k_can_protocol/ModuleStatus.java new file mode 100644 index 0000000..ff301d0 --- /dev/null +++ b/src/main/java/a8k/a8k_can_protocol/ModuleStatus.java @@ -0,0 +1,24 @@ +package a8k.a8k_can_protocol; + +public enum ModuleStatus { + IDLE(0), // + BUSY(1), // + ERROR(2),// + ; + + final public int index; + + ModuleStatus(int index) { + this.index = index; + } + + public int getIndex() { + return index; + } + + public static ModuleStatus valueOf(int value) { // 手写的从int到enum的转换函数 + assert (value >= 0 && value < 2); + return values()[value]; + } + +} diff --git a/src/main/java/a8k/appbean/AppErrorCode.java b/src/main/java/a8k/appbean/AppErrorCode.java index cd88b8d..6dc2408 100644 --- a/src/main/java/a8k/appbean/AppErrorCode.java +++ b/src/main/java/a8k/appbean/AppErrorCode.java @@ -1,31 +1,30 @@ package a8k.appbean; public enum AppErrorCode { - Success("Success", "成功", 0), // - TubeNotHasHat("TubeNotHasHat", "全血试管未盖帽", 1), // - SampleLiquidLevelWasNotDetected("SampleLiquidLevelWasNotDetected", "取样时未探测到液面", 2),// - LargeBufferNotEnough("LargeBufferNotEnough", "大瓶缓冲液不足", 3), // - PasswdError("PasswdError", "密码错误", 4), // - UserDoesNotExist("UserDoesNotExist", "用户不存在", 5), // + Success("成功", 0), // + TubeNotHasHat("全血试管未盖帽", 1), // + SampleLiquidLevelWasNotDetected("取样时未探测到液面", 2),// + LargeBufferNotEnough("大瓶缓冲液不足", 3), // + PasswdError("密码错误", 4), // + UserDoesNotExist("用户不存在", 5), // + GripperPosError("抓手舵机位置异常", 6), // + GripperLiftMotorPosError("抓手升降电机位置异常", 8), // + GripperHorizontalMovementMotorPosError("抓手前后移动舵机位置异常", 9),// + TubesInShakeModule("摇匀模组位置有试管", 10),// ; - final private String name; + final private String chName; final private int errorIndex; public int mid; - private AppErrorCode(String name, String chname, int errorIndex) { - this.name = name; + private AppErrorCode(String chname, int errorIndex) { this.chName = chname; this.errorIndex = errorIndex; } - public String toString() { - return name; - } - public String getChName() { return chName; } diff --git a/src/main/java/a8k/base_hardware/A8kCanBusService.java b/src/main/java/a8k/base_hardware/A8kCanBusService.java index 7c4c366..7eb3340 100644 --- a/src/main/java/a8k/base_hardware/A8kCanBusService.java +++ b/src/main/java/a8k/base_hardware/A8kCanBusService.java @@ -29,54 +29,52 @@ public class A8kCanBusService { public static final Logger logger = LoggerFactory.getLogger(A8kCanBusService.class); /** - * receiptQueue - * waittingReceiptIndex + * receiptQueue + * waittingReceiptIndex * - * onPacket - * if(receipt) - * send_receipt_queue + * onPacket + * if(receipt) + * send_receipt_queue * * - * sendcmd - * send cmd - * waiting for receipt - * for(){ - * if(receipt.packetIndex == receiptIndex){ - * return; - * } - * wait - * } + * sendcmd + * send cmd + * waiting for receipt + * for(){ + * if(receipt.packetIndex == receiptIndex){ + * return; + * } + * wait + * } * */ @Autowired private AppEventBusService eventBusService; - public String uri; //assign by application.yml + public String uri; // assign by application.yml private WebSocketClient client; - //接收回执上下文 + // 接收回执上下文 public BlockingQueue receiptQueue = new LinkedBlockingQueue(); // - boolean isWaitingReceipt = false; // - int waitingReceiptIndex = 0;// + boolean isWaitingReceipt = false; // + int waitingReceiptIndex = 0;// - //发送包的packetIndex + // 发送包的packetIndex int packetIndex = 0;// - //调试标志位 - boolean debugFlag = false;// - //websocket自动重连时间 - Timer autoConnectTimer = new Timer();// - + // 调试标志位 + boolean debugFlag = false;// + // websocket自动重连时间 + Timer autoConnectTimer = new Timer();// @PostConstruct public void init() throws URISyntaxException { - logger.info("BaseHardwareService initilized"); packetIndex = 0; if (this.uri == null) { - //this.uri = "ws://127.0.0.1:19005"; + // this.uri = "ws://127.0.0.1:19005"; this.uri = "ws://192.168.8.10:19005"; } @@ -104,7 +102,6 @@ public class A8kCanBusService { }; client.connect(); - autoConnectTimer.schedule(new TimerTask() { @Override public void run() { @@ -114,7 +111,8 @@ public class A8kCanBusService { client.connect(); } catch (IllegalStateException e) { } - } else if (client.getReadyState().equals(ReadyState.CLOSING) || client.getReadyState().equals(ReadyState.CLOSED)) { + } else if (client.getReadyState().equals(ReadyState.CLOSING) + || client.getReadyState().equals(ReadyState.CLOSED)) { client.reconnect(); } } @@ -123,10 +121,11 @@ public class A8kCanBusService { } private A8kPacket packParamsToPacket(Integer moduleId, Integer cmdId, Integer[] params) { - int subCmdId = cmdId & 0xFF; - int mainCmdId = (cmdId >> 8) & 0xFFFF; - int bufferSize = 2 + 2 + 1 + 1 + 2 + 4 * params.length; // PacketIndex - MainCmdId - SubCmdId - CmdType - ModuleId - Parameters - ByteBuffer buffer = ByteBuffer.allocate(bufferSize); + int subCmdId = cmdId & 0xFF; + int mainCmdId = (cmdId >> 8) & 0xFFFF; + int bufferSize = 2 + 2 + 1 + 1 + 2 + 4 * params.length; // PacketIndex - MainCmdId - SubCmdId - CmdType - + // ModuleId - Parameters + ByteBuffer buffer = ByteBuffer.allocate(bufferSize); buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.putShort((short) 0); // PacketIndex buffer.putShort((short) mainCmdId); // MainCmdId @@ -139,75 +138,228 @@ public class A8kCanBusService { return new A8kPacket(buffer.array()); } - //TODO + // + // module opeation + // + public void modulePing(int id) throws HardwareException { + callcmd(id, CmdId.kmodule_ping); + } + + public void moduleStop(int id) throws HardwareException { + callcmd(id, CmdId.kmodule_stop); + } + + public ModuleStatus getModuleStatus(int id) throws HardwareException { + var packet = callcmd(id, CmdId.kmodule_get_status); + return ModuleStatus.valueOf(packet.getContentI32(0)); + + } + + public void moduleSetReg(int id, RegIndex regindex, int reg) throws HardwareException { + callcmd(id, CmdId.kmodule_set_reg, regindex.ordinal(), reg); + } + + public int moduleGetReg(int id, RegIndex regindex) throws HardwareException { + var packet = callcmd(id, CmdId.kmodule_get_reg, regindex.ordinal()); + return packet.getContentI32(0); + } + + public int moduleGetError(int id) throws HardwareException { + var packet = callcmd(id, CmdId.kmodule_get_error); + return packet.getContentI32(0); + } + + public void moduleClearError(int id) throws HardwareException { + callcmd(id, CmdId.kmodule_clear_error); + } + + public void moduleActiveCfg(int id) throws HardwareException { + callcmd(id, CmdId.kmodule_active_cfg); + } + + // + // stepMotor + // + public void stepMotorEnable(int mid, int enable) throws HardwareException { + callcmd(mid, CmdId.kstep_motor_enable, enable); + } + + public int stepMotorReadPos(int id) throws HardwareException { + A8kPacket packet = callcmd(id, CmdId.kstep_motor_read_pos); + return packet.getContentI32(0); + } + + public void stepMotorEasyRotate(int id, int direction) throws HardwareException { + callcmd(id, CmdId.kstep_motor_easy_rotate, direction); + } + + public void stepMotorEasyMoveBy(int id, int dpos) throws HardwareException { + callcmd(id, CmdId.kstep_motor_easy_move_by, dpos); + } + + public void stepMotorEasyMoveTo(int id, int pos) throws HardwareException { + callcmd(id, CmdId.kstep_motor_easy_move_to, pos); + } + + public void stepMotorEasyMoveToZero(int id) throws HardwareException { + callcmd(id, CmdId.kstep_motor_easy_move_to_zero); + } + + public void stepMotorEasySetCurrentPos(int id, int pos) throws HardwareException { + callcmd(id, CmdId.kstep_motor_easy_set_current_pos, pos); + } + + public void stepMotorEasyMoveToIo(int id, int io) throws HardwareException { + callcmd(id, CmdId.kstep_motor_easy_move_to_io, io); + } + + public void stepMotorStop(int id) throws HardwareException { + callcmd(id, CmdId.kstep_motor_stop); + } + + public void stepMotorActiveCfg(int id) throws HardwareException { + callcmd(id, CmdId.kstep_motor_active_cfg); + } + + public int stepMotorReadIoState(int id) throws HardwareException { + var packet = callcmd(id, CmdId.kstep_motor_read_io_state); + return packet.getContentI32(0); + } + + public void stepMotorEasyMoveToEndPoint(int id) throws HardwareException { + callcmd(id, CmdId.kstep_motor_easy_move_to_end_point); + } + + public void stepMotorEasyReciprocatingMotion(int id, int startpos, int endpos, int times) throws HardwareException { + callcmd(id, CmdId.kstep_motor_easy_reciprocating_motion, startpos, endpos, times); + } + + // + // MINI_SERVO + // + + public void miniServoEnable(int id, int enable) throws HardwareException { + callcmd(id, CmdId.kmini_servo_enable, enable); + } + + public int miniServoReadPos(int id) throws HardwareException { + var packet = callcmd(id, CmdId.kmini_servo_read_pos); + return packet.getContentI32(0); + } + + public void miniServoActiveCfg(int id) throws HardwareException { + callcmd(id, CmdId.kmini_servo_active_cfg); + } + + public void miniServoStop(int id) throws HardwareException { + callcmd(id, CmdId.kmini_servo_stop); + } + + public void miniServoSetMidPoint(int id) throws HardwareException { + callcmd(id, CmdId.kmini_servo_set_mid_point); + } + + public int miniServoReadIoState(int id) throws HardwareException { + var packet = callcmd(id, CmdId.kmini_servo_read_io_state); + return packet.getContentI32(0); + } + + public void miniServoMoveTo(int id, int pos) throws HardwareException { + callcmd(id, CmdId.kmini_servo_move_to, pos); + } + + public void miniServoRotate(int id, int direction) throws HardwareException { + callcmd(id, CmdId.kmini_servo_rotate, direction); + } + + public void miniServoRotateWithTorque(int id, int torque) throws HardwareException { + callcmd(id, CmdId.kmini_servo_rotate_with_torque, torque); + } + public boolean getIOState(IOId ioid) throws HardwareException { - return false; + if (ioid.mtype == ModuleType.kboard) { + return callcmd(CmdId.kextboard_read_inio, ioid.mid, ioid.ioIndex).getContentI32(0) != 0; + } else if (ioid.mtype == ModuleType.ktmc_step_motor) { + return callcmd(CmdId.kstep_motor_read_io_state, ioid.mid, ioid.ioIndex).getContentI32(0) != 0; + } else if (ioid.mtype == ModuleType.kmini_servo_motor_module) { + return callcmd(CmdId.kmini_servo_read_io_state, ioid.mid, ioid.ioIndex).getContentI32(0) != 0; + } else { + throw new HardwareException(ioid.mid, Errorcode.killegal_operation); + } } - //TODO public void setIOState(IOId ioid, boolean val) throws HardwareException { + if (ioid.mtype == ModuleType.kboard) { + callcmd(CmdId.kextboard_write_outio, ioid.mid, ioid.ioIndex, val ? 1 : 0); + } else { + throw new HardwareException(ioid.mid, Errorcode.killegal_operation); + } } - public A8kPacket callcmd(Integer moduleId, Integer cmdId) throws HardwareException { - return this.callcmd(moduleId, cmdId, new Integer[]{}); + return this.callcmd(moduleId, cmdId, new Integer[] {}); } public A8kPacket callcmd(Integer moduleId, Integer cmdId, Integer p0) throws HardwareException { - return this.callcmd(moduleId, cmdId, new Integer[]{p0}); + return this.callcmd(moduleId, cmdId, new Integer[] { p0 }); } public A8kPacket callcmd(Integer moduleId, Integer cmdId, Integer p0, Integer p1) throws HardwareException { - return this.callcmd(moduleId, cmdId, new Integer[]{p0, p1}); + return this.callcmd(moduleId, cmdId, new Integer[] { p0, p1 }); } - public A8kPacket callcmd(Integer moduleId, Integer cmdId, Integer p0, Integer p1, Integer p2) throws HardwareException { - return this.callcmd(moduleId, cmdId, new Integer[]{p0, p1, p2}); + public A8kPacket callcmd(Integer moduleId, Integer cmdId, Integer p0, Integer p1, Integer p2) + throws HardwareException { + return this.callcmd(moduleId, cmdId, new Integer[] { p0, p1, p2 }); } - public A8kPacket callcmd(Integer moduleId, Integer cmdId, Integer p0, Integer p1, Integer p2, Integer p3) throws HardwareException { - return this.callcmd(moduleId, cmdId, new Integer[]{p0, p1, p2, p3}); + public A8kPacket callcmd(Integer moduleId, Integer cmdId, Integer p0, Integer p1, Integer p2, Integer p3) + throws HardwareException { + return this.callcmd(moduleId, cmdId, new Integer[] { p0, p1, p2, p3 }); } - public void callblockcmd(Integer moduleId, Integer cmdId, Integer p0, Integer p1, Integer p2, Integer p3, Integer acitionOvertime) throws HardwareException, InterruptedException { - this.callblockcmd(moduleId, cmdId, new Integer[]{p0,p1,p2,p3}, acitionOvertime); + public void callblockcmd(Integer moduleId, Integer cmdId, Integer p0, Integer p1, Integer p2, Integer p3, + Integer acitionOvertime) throws HardwareException, InterruptedException { + this.callblockcmd(moduleId, cmdId, new Integer[] { p0, p1, p2, p3 }, acitionOvertime); } - public void callblockcmd(Integer moduleId, Integer cmdId, Integer p0, Integer p1, Integer p2, Integer acitionOvertime) throws HardwareException, InterruptedException { - this.callblockcmd(moduleId, cmdId, new Integer[]{p0,p1,p2}, acitionOvertime); + public void callblockcmd(Integer moduleId, Integer cmdId, Integer p0, Integer p1, Integer p2, + Integer acitionOvertime) throws HardwareException, InterruptedException { + this.callblockcmd(moduleId, cmdId, new Integer[] { p0, p1, p2 }, acitionOvertime); } - public void callblockcmd(Integer moduleId, Integer cmdId, Integer p0, Integer p1, Integer acitionOvertime) throws HardwareException, InterruptedException { - this.callblockcmd(moduleId, cmdId, new Integer[]{p0,p1}, acitionOvertime); + public void callblockcmd(Integer moduleId, Integer cmdId, Integer p0, Integer p1, Integer acitionOvertime) + throws HardwareException, InterruptedException { + this.callblockcmd(moduleId, cmdId, new Integer[] { p0, p1 }, acitionOvertime); } - public void callblockcmd(Integer moduleId, Integer cmdId, Integer p0, Integer acitionOvertime) throws HardwareException, InterruptedException { - this.callblockcmd(moduleId, cmdId, new Integer[]{p0}, acitionOvertime); + public void callblockcmd(Integer moduleId, Integer cmdId, Integer p0, Integer acitionOvertime) + throws HardwareException, InterruptedException { + this.callblockcmd(moduleId, cmdId, new Integer[] { p0 }, acitionOvertime); } - //TODO - public void callblockcmd(Integer moduleId, Integer cmdId, Integer acitionOvertime) throws HardwareException, InterruptedException { - this.callblockcmd(moduleId, cmdId, new Integer[]{}, acitionOvertime); + public void callblockcmd(Integer moduleId, Integer cmdId, Integer acitionOvertime) + throws HardwareException, InterruptedException { + this.callblockcmd(moduleId, cmdId, new Integer[] {}, acitionOvertime); } - //TODO + // TODO public Integer module_read_reg(Integer moduleId, RegIndex regindex) { return 0; } - //TODO + + // TODO public void module_write_reg(Integer moduleId, RegIndex regindex, Integer reg) { } - public A8kPacket callcmd(Integer moduleId, Integer cmdId, Integer[] params) throws HardwareException { var packet = this.packParamsToPacket(moduleId, cmdId, params); return this.sendCmd(packet, A8kPacket.CMD_OVERTIME); } - public A8kPacket sendCmdAutoResend(A8kPacket pack, int overtime) throws HardwareException { - //调用sendCmd, + // 调用sendCmd, // 如果捕获到超时异常,则重发,最多重发三次 // 如果是其他异常,则直接抛出异常。 for (int i = 0; i < 3; i++) { @@ -222,18 +374,18 @@ public class A8kCanBusService { return null; } - - public void callblockcmd(Integer moduleId, Integer cmdId, Integer[] params, int acitionOvertime) throws HardwareException, InterruptedException { + public void callblockcmd(Integer moduleId, Integer cmdId, Integer[] params, int acitionOvertime) + throws HardwareException, InterruptedException { var packet = this.packParamsToPacket(moduleId, cmdId, params); this.sendCmdAutoResend(packet, A8kPacket.CMD_OVERTIME); - //调用sendCmdAutoResend - // 通过kmodule_get_status判断指令是否完成,超时未完成则报错,则调用module_stop,同时抛出异常 + // 调用sendCmdAutoResend + // 通过kmodule_get_status判断指令是否完成,超时未完成则报错,则调用module_stop,同时抛出异常 // long startedAt = System.currentTimeMillis(); do { - var pack = this.callcmd(moduleId, CmdId.kmodule_get_status, new Integer[]{}); + var pack = this.callcmd(moduleId, CmdId.kmodule_get_status, new Integer[] {}); var status = pack.getContentI32(0); if (0 == status) { break; @@ -251,7 +403,7 @@ public class A8kCanBusService { private A8kPacket sendCmd(A8kPacket pack, int overtime) throws HardwareException { pack.setPacketIndex(packetIndex); waitingReceiptIndex = packetIndex; - packetIndex = packetIndex + 1; + packetIndex = packetIndex + 1; if (packetIndex > 10000) { packetIndex = 1; } @@ -306,7 +458,8 @@ public class A8kCanBusService { logger.info("RX {}:({})", packet, rx); } - if (packet.getPacketType() == A8kPacket.PACKET_TYPE_ACK || packet.getPacketType() == A8kPacket.PACKET_TYPE_ERROR_ACK) { + if (packet.getPacketType() == A8kPacket.PACKET_TYPE_ACK + || packet.getPacketType() == A8kPacket.PACKET_TYPE_ERROR_ACK) { if (isWaitingReceipt) { if (waitingReceiptIndex == packet.getPacketIndex()) { receiptQueue.add(packet); @@ -321,7 +474,6 @@ public class A8kCanBusService { } } - public static void main(String[] args) { A8kCanBusService service = new A8kCanBusService(); try { diff --git a/src/main/java/a8k/controller/TmpTestController.java b/src/main/java/a8k/controller/TmpTestController.java index 1879f56..6231582 100644 --- a/src/main/java/a8k/controller/TmpTestController.java +++ b/src/main/java/a8k/controller/TmpTestController.java @@ -62,7 +62,9 @@ public class TmpTestController { } @PostMapping("/api/zhaohe_test/initialize_device") + @ResponseBody public AppErrorCode initialize_device() { return deviceInitializationCtrlService.initializeDevice(); +// return "OK"; } } diff --git a/src/main/java/a8k/service/ctrl_service/DeviceInitializationCtrlService.java b/src/main/java/a8k/service/ctrl_service/DeviceInitializationCtrlService.java index a03f583..895803b 100644 --- a/src/main/java/a8k/service/ctrl_service/DeviceInitializationCtrlService.java +++ b/src/main/java/a8k/service/ctrl_service/DeviceInitializationCtrlService.java @@ -1,6 +1,9 @@ package a8k.service.ctrl_service; import a8k.appbean.AppErrorCode; +import a8k.base_hardware.A8kCanBusService; +import a8k.service.db.dao.SamplesPreProcessModuleCtrlParamsService; +import jakarta.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -18,12 +21,60 @@ public class DeviceInitializationCtrlService { * 2.试管夹紧 * 3.抓手平移 * 4.抓手 + * 0. + * 1. 抓手尝试移动到夹紧位置,等待一定时间,如果没有移动到夹紧位置,则返回错误。 + * 2. 试管夹紧电机归零,超时一定时间,没有归零,则返回错误。 + * 3. 抓手平移电机,移动到待机位,如果移动不到,则返回错误。 * */ + @Resource + A8kCanBusService canBus; + + @Resource + SamplesPreProcessModuleCtrlParamsService samplesPreProcessModuleCtrlParams; public AppErrorCode initializeDevice() { logger.info("Initializing device ..."); + +// canBus + + + +// this.a8kCanBusService.callblockcmd( +// ModuleId.ServoTubeCapClipModule, +// CmdId.kmini_servo_move_to, +// params.getGripperServo_standbyPos(), +// params.getActionOvertime() +// ); +// +// this.a8kCanBusService.callblockcmd( +// ModuleId.MotorTubeMoveUpDownModule, +// CmdId.kstep_motor_easy_move_to_zero, +// params.getMoveToZeroOvertime() +// ); +// +// this.a8kCanBusService.callblockcmd( +// ModuleId.ServoTubeMoveFrontBackModule, +// CmdId.kmini_servo_move_to, +// params.getHorizontalMotor_standbyPos(), +// params.getActionOvertime() +// ); +// +// this.a8kCanBusService.callblockcmd( +// ModuleId.MotorTubeShakeModule, +// CmdId.kstep_motor_easy_move_to_zero, +// params.getMoveToZeroOvertime() +// ); +// +// this.a8kCanBusService.callblockcmd( +// ModuleId.MotorTubeScanClampModule, +// CmdId.kstep_motor_easy_move_to_zero, +// params.getMoveToZeroOvertime() +// ); +// + + return AppErrorCode.Success; } diff --git a/src/main/java/a8k/service/state_service/A8kStateDB.java b/src/main/java/a8k/service/state_service/A8kStateDB.java index 2fe0dbe..720d535 100644 --- a/src/main/java/a8k/service/state_service/A8kStateDB.java +++ b/src/main/java/a8k/service/state_service/A8kStateDB.java @@ -14,6 +14,4 @@ public class A8kStateDB extends UfActiveRecord { return "A8kStateDB" + "Table"; } - - } diff --git a/src/main/java/a8k/service/state_service/A8kStateMgrService.java b/src/main/java/a8k/service/state_service/A8kStateMgrService.java index c792791..8f3b74d 100644 --- a/src/main/java/a8k/service/state_service/A8kStateMgrService.java +++ b/src/main/java/a8k/service/state_service/A8kStateMgrService.java @@ -32,10 +32,10 @@ public class A8kStateMgrService { @PostConstruct public void init() { -// var one = UfActiveRecord.find(A8kStateDB.class).get(0); -// if (one == null) { -// updateA8kState(new A8kState()); -// } + var list = UfActiveRecord.find(A8kStateDB.class); + if (list.isEmpty()) { + updateA8kState(new A8kState()); + } } // @@ -120,10 +120,13 @@ public class A8kStateMgrService { } void updateA8kState(A8kState state) { - var one = UfActiveRecord.find(A8kStateDB.class).get(0); + var list = UfActiveRecord.find(A8kStateDB.class); - if (one == null) { + A8kStateDB one; + if (list.isEmpty()) { one = new A8kStateDB(); + } else { + one = list.get(0); } ObjectMapper mapper = new ObjectMapper(); diff --git a/zhaohe_app.db b/zhaohe_app.db index fa0167c..ee8c366 100644 Binary files a/zhaohe_app.db and b/zhaohe_app.db differ