Browse Source

update

tags/v0
zhaohe 1 year ago
parent
commit
99a7fdd3ac
  1. BIN
      app.db
  2. 108
      src/main/java/a8k/a8k_can_protocol/ModuleId.java
  3. 12
      src/main/java/a8k/appbean/PosBean.java
  4. 38
      src/main/java/a8k/base_hardware/A8kCanBusService.java
  5. 36
      src/main/java/a8k/service/db/dao/A8KGeneralConsumablesPropertyDao.java
  6. 47
      src/main/java/a8k/service/db/dao/A8kDirectCtrlPosDao.java
  7. 30
      src/main/java/a8k/service/db/dao/A8kTubeInfoDao.java
  8. 17
      src/main/java/a8k/service/db/dao/MotorParameterDao.java
  9. 27
      src/main/java/a8k/service/db/entity/A8kDirectCtrlPos.java
  10. 20
      src/main/java/a8k/service/db/entity/A8kGeneralConsumablesProperty.java
  11. 31
      src/main/java/a8k/service/db/entity/A8kTubeInfo.java
  12. 28
      src/main/java/a8k/service/db/entity/MotorParameter.java
  13. 132
      src/main/java/a8k/service/hardware/MotorTubeRackMoveService.java

BIN
app.db

108
src/main/java/a8k/a8k_can_protocol/ModuleId.java

@ -1,63 +1,63 @@
package a8k.a8k_can_protocol;
public class ModuleId {
public static final int ArmXYId = 11;//机械臂XY
public static final int ArmZId = 81;//机械臂Z
public static final int FeederId = 60;//出入料模块
public static final int IdCardReaderId = 101; //A8K读卡器
public static final int IncubatorTempCtrlId = 51;//温度控制
public static final int MaterialScannerId = 83;//物料扫码器
public static final int MotorCardWarehouseMoveId = 21;//板夹仓移动电机
public static final int MotorCardWarehousePushId = 22;//板夹仓推杆电机
public static final int MotorIncubatorRotateId = 71;//孵育盘旋转
public static final int MotorTestCardPullId = 92;//板卡推杆电机
public static final int MotorTestCardScanId = 91;//板卡扫描电机
public static final int MotorTubeBodyClipId = 31;//试管固定夹爪电机
public static final int MotorTubeMoveUpDownId = 32;//摇匀升降电机
public static final int MotorTubeRackExitId = 63;//出料电机
public static final int MotorTubeRackFeedId = 61;//入料电机
public static final int MotorTubeRackMoveId = 62;//试管架平移电机
public static final int MotorTubeShakeId = 33;//试管摇匀电机
public static final int PipetteId = 82;//移液枪
public static final int ScannerId = 93;//扫描仪
public static final int ServoTubeCapClipId = 35;//摇匀试管帽夹爪
public static final int ServoTubeMoveFrontBackId = 34;//摇匀前后电机
public static final int ServoTubeRackTubePushId = 36;//试管架旋转固定舵机
public static final int ServoTubeRackTubeRotateId = 37;//试管架旋转舵机
public static final int TestCardWarehouseId = 41;//测试板仓
public static final int TrashBoxId = 40;//废料盒
public static final int TubeRackScannerId = 64;//试管架扫码器
public static final int WbTubeFanId = 42;//气溶胶风扇
public static final int ArmXYModule = 11;//机械臂XY
public static final int ArmZModule = 81;//机械臂Z
public static final int FeederModule = 60;//出入料模块
public static final int IdCardReaderModule = 101; //A8K读卡器
public static final int IncubatorTempCtrlModule = 51;//温度控制
public static final int MaterialScannerModule = 83;//物料扫码器
public static final int MotorCardWarehouseMoveModule = 21;//板夹仓移动电机
public static final int MotorCardWarehousePushModule = 22;//板夹仓推杆电机
public static final int MotorIncubatorRotateModule = 71;//孵育盘旋转
public static final int MotorTestCardPullModule = 92;//板卡推杆电机
public static final int MotorTestCardScanModule = 91;//板卡扫描电机
public static final int MotorTubeBodyClipModule = 31;//试管固定夹爪电机
public static final int MotorTubeMoveUpDownModule = 32;//摇匀升降电机
public static final int MotorTubeRackExitModule = 63;//出料电机
public static final int MotorTubeRackFeedModule = 61;//入料电机
public static final int MotorTubeRackMoveModule = 62;//试管架平移电机
public static final int MotorTubeShakeModule = 33;//试管摇匀电机
public static final int PipetteModule = 82;//移液枪
public static final int ScannerModule = 93;//扫描仪
public static final int ServoTubeCapClipModule = 35;//摇匀试管帽夹爪
public static final int ServoTubeMoveFrontBackModule = 34;//摇匀前后电机
public static final int ServoTubeRackTubePushModule = 36;//试管架旋转固定舵机
public static final int ServoTubeRackTubeRotateModule = 37;//试管架旋转舵机
public static final int TestCardWarehouseModule = 41;//测试板仓
public static final int TrashBoxModule = 40;//废料盒
public static final int TubeRackScannerModule = 64;//试管架扫码器
public static final int WbTubeFanModule = 42;//气溶胶风扇
public static String ModuleId2Name(int moduleId) {
return switch (moduleId) {
case ArmXYId -> "ArmXYId";
case ArmZId -> "ArmZId";
case FeederId -> "FeederId";
case IdCardReaderId -> "IdCardReaderId";
case IncubatorTempCtrlId -> "IncubatorTempCtrlId";
case MaterialScannerId -> "MaterialScannerId";
case MotorCardWarehouseMoveId -> "MotorCardWarehouseMoveId";
case MotorCardWarehousePushId -> "MotorCardWarehousePushId";
case MotorIncubatorRotateId -> "MotorIncubatorRotateId";
case MotorTestCardPullId -> "MotorTestCardPullId";
case MotorTestCardScanId -> "MotorTestCardScanId";
case MotorTubeBodyClipId -> "MotorTubeBodyClipId";
case MotorTubeMoveUpDownId -> "MotorTubeMoveUpDownId";
case MotorTubeRackExitId -> "MotorTubeRackExitId";
case MotorTubeRackFeedId -> "MotorTubeRackFeedId";
case MotorTubeRackMoveId -> "MotorTubeRackMoveId";
case MotorTubeShakeId -> "MotorTubeShakeId";
case PipetteId -> "PipetteId";
case ScannerId -> "ScannerId";
case ServoTubeCapClipId -> "ServoTubeCapClipId";
case ServoTubeMoveFrontBackId -> "ServoTubeMoveFrontBackId";
case ServoTubeRackTubePushId -> "ServoTubeRackTubePushId";
case ServoTubeRackTubeRotateId -> "ServoTubeRackTubeRotateId";
case TestCardWarehouseId -> "TestCardWarehouseId";
case TrashBoxId -> "TrashBoxId";
case TubeRackScannerId -> "TubeRackScannerId";
case WbTubeFanId -> "WbTubeFanId";
case ArmXYModule -> "ArmXYModule";
case ArmZModule -> "ArmZModule";
case FeederModule -> "FeederModule";
case IdCardReaderModule -> "IdCardReaderModule";
case IncubatorTempCtrlModule -> "IncubatorTempCtrlModule";
case MaterialScannerModule -> "MaterialScannerModule";
case MotorCardWarehouseMoveModule -> "MotorCardWarehouseMoveModule";
case MotorCardWarehousePushModule -> "MotorCardWarehousePushModule";
case MotorIncubatorRotateModule -> "MotorIncubatorRotateModule";
case MotorTestCardPullModule -> "MotorTestCardPullModule";
case MotorTestCardScanModule -> "MotorTestCardScanModule";
case MotorTubeBodyClipModule -> "MotorTubeBodyClipModule";
case MotorTubeMoveUpDownModule -> "MotorTubeMoveUpDownModule";
case MotorTubeRackExitModule -> "MotorTubeRackExitModule";
case MotorTubeRackFeedModule -> "MotorTubeRackFeedModule";
case MotorTubeRackMoveModule -> "MotorTubeRackMoveModule";
case MotorTubeShakeModule -> "MotorTubeShakeModule";
case PipetteModule -> "PipetteModule";
case ScannerModule -> "ScannerModule";
case ServoTubeCapClipModule -> "ServoTubeCapClipModule";
case ServoTubeMoveFrontBackModule -> "ServoTubeMoveFrontBackModule";
case ServoTubeRackTubePushModule -> "ServoTubeRackTubePushModule";
case ServoTubeRackTubeRotateModule -> "ServoTubeRackTubeRotateModule";
case TestCardWarehouseModule -> "TestCardWarehouseModule";
case TrashBoxModule -> "TrashBoxModule";
case TubeRackScannerModule -> "TubeRackScannerModule";
case WbTubeFanModule -> "WbTubeFanModule";
default -> "UnknownModuleId(" + moduleId + ")";
};
}

12
src/main/java/a8k/appbean/PosBean.java

@ -0,0 +1,12 @@
package a8k.appbean;
public class PosBean {
public int x;
public int y;
public int z;
public PosBean(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
}

38
src/main/java/a8k/base_hardware/A8kCanBusService.java

@ -7,7 +7,6 @@ import a8k.appbean.HardwareException;
import a8k.appbean.appevent.A8kHardwareReport;
import a8k.service.AppEventBusService;
import a8k.utils.ByteArray;
import ch.qos.logback.core.model.processor.AppenderModelHandler;
import jakarta.annotation.PostConstruct;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.enums.ReadyState;
@ -126,12 +125,12 @@ 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) 0); // PacketIndex
buffer.putShort((short) mainCmdId); // MainCmdId
buffer.put((byte) subCmdId); // SubCmdId
buffer.put((byte) 0); // CmdType
@ -153,11 +152,11 @@ public class A8kCanBusService {
//调用sendCmd,
// 如果捕获到超时异常则重发最多重发三次
// 如果是其他异常则直接抛出异常
for ( int i=0; i<3; i++ ) {
for (int i = 0; i < 3; i++) {
try {
return this.sendCmd(pack, A8kPacket.CMD_OVERTIME);
} catch ( HardwareException e ) {
if ( e.getErrorCode() != Errorcode.kovertime ) {
} catch (HardwareException e) {
if (e.getErrorCode() != Errorcode.kovertime) {
throw e;
}
}
@ -166,7 +165,7 @@ public class A8kCanBusService {
}
//TODO
public void callblockcmd(Integer moduleId, Integer cmdId, Integer[] params,int acitionOvertime) throws HardwareException {
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);
@ -176,24 +175,19 @@ public class A8kCanBusService {
long startedAt = System.currentTimeMillis();
do {
var pack = this.callcmd(moduleId, 0x0104, new Integer[]{});
var content = pack.getCmdContent();
var status = content[0];
if ( 0 == status ) {
break ;
var pack = this.callcmd(moduleId, CmdId.kmodule_get_status, new Integer[]{});
var status = pack.getContentI32(0);
if (0 == status) {
break;
}
long now = System.currentTimeMillis();
if ( now - startedAt > acitionOvertime) {
if (now - startedAt > acitionOvertime) {
throw new HardwareException(pack.getModuleId(), Errorcode.kovertime);
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} while ( true );
Thread.sleep(100);
} while (true);
}
private A8kPacket sendCmd(A8kPacket pack, int overtime) throws HardwareException {

36
src/main/java/a8k/service/db/dao/A8KGeneralConsumablesPropertyDao.java

@ -0,0 +1,36 @@
package a8k.service.db.dao;
import a8k.service.db.entity.A8kGeneralConsumablesProperty;
import com.iflytop.uf.UfActiveRecord;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* 用于存储耗材的一些属性信息
*/
@Component
public class A8KGeneralConsumablesPropertyDao {
public float getValAsFloat(String propertyKey) {
A8kGeneralConsumablesProperty val = UfActiveRecord.findOne(A8kGeneralConsumablesProperty.class, Map.of("propertyKey", propertyKey));
assert val != null;
return Float.parseFloat(val.val);
}
public int getValAsInt(String propertyKey) {
A8kGeneralConsumablesProperty val = UfActiveRecord.findOne(A8kGeneralConsumablesProperty.class, Map.of("propertyKey", propertyKey));
assert val != null;
return Integer.parseInt(val.val);
}
public String getValAsString(String propertyKey) {
A8kGeneralConsumablesProperty val = UfActiveRecord.findOne(A8kGeneralConsumablesProperty.class, Map.of("propertyKey", propertyKey));
assert val != null;
return val.val;
}
}

47
src/main/java/a8k/service/db/dao/A8kDirectCtrlPosDao.java

@ -0,0 +1,47 @@
package a8k.service.db.dao;
import a8k.appbean.PosBean;
import a8k.service.db.entity.A8kDirectCtrlPos;
import com.iflytop.uf.UfActiveRecord;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
*
* 用于设备运行中的关键位置信息
*
*
*/
@Component
public class A8kDirectCtrlPosDao {
//
// 试管架移动相关坐标
// 1.零点参考点为零点光电
// 2.移动坐标参考点为从左往右数第一个试管
// 3.正方向为执行机构的正方向
//
public static final String kMotorTubeRackMotor_tubeScanPos = "kMotorTubeRackMotor_tubeScanPos"; //扫码位置
public static final String kMotorTubeRackMotor_tubeHeighJudgmentPos = "kMotorTubeRackMotor_tubeHeighJudgmentPos"; //高低试管判断位置
public static final String kMotorTubeRackMotor_tubePreProcessPos = "kMotorTubeRackMotor_tubePreProcessPos"; //试管预处理位置
public static final String kMotorTubeRackMotor_tubeExistJudgmentPos = "kMotorTubeRackMotor_tubeExistJudgmentPos";//试管有无
public static final String kMotorTubeRackMotor_tubeRackEnterPos = "kMotorTubeRackMotor_tubeRackEnterPos"; //入料位置
public static final String kMotorTubeRackMotor_tubeRackExitPos = "kMotorTubeRackMotor_tubeRackExitPos"; //出料位置
public static final String kMotorTubeRackMotor_tubeRackScanCodePos = "kMotorTubeRackMotor_tubeRackScanCodePos"; //出料位置
PosBean getPosBean(String posName) {
A8kDirectCtrlPos pos = UfActiveRecord.findOne(A8kDirectCtrlPos.class, Map.of("posName", posName));
assert pos != null;
return new PosBean(pos.posX, pos.posY, pos.posZ);
}
A8kDirectCtrlPos getPos(String posName) {
A8kDirectCtrlPos pos = UfActiveRecord.findOne(A8kDirectCtrlPos.class, Map.of("posName", posName));
assert pos != null;
return pos;
}
}

30
src/main/java/a8k/service/db/dao/A8kTubeInfoDao.java

@ -0,0 +1,30 @@
package a8k.service.db.dao;
import a8k.service.db.entity.A8kTubeInfo;
import com.iflytop.uf.UfActiveRecord;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class A8kTubeInfoDao {
public static final String BloodTubeCode = "0000"; //全血试管
public static final String MiniTubeCode = "1111"; //迷你试管
public static final String MiniBloodCode = "2222"; //阳普管
public static final String BulletTube1P5Code = "5555"; //子弹头试管1.5mL
public static final String BulletTube0P5Code = "4444"; //子弹头试管0.5mL
public static final String TubeType_HighBlood = "HighBloodTube"; //全血试管
public static final String TubeType_ShortBlood = "ShortBloodTube"; //全血试管
public static final String TubeType_Mini = "MiniTube"; //迷你试管
public static final String TubeType_MiniBlood = "MiniBloodTube"; //阳普管
public static final String TubeType_BulletTube1P5 = "BulletTube1P5"; //子弹头试管1.5mL
public static final String TubeType_BulletTube0P5 = "BulletTube0P5"; //子弹头试管0.5mL
public A8kTubeInfo getTubeInfo(String TypeName) {
var info = UfActiveRecord.findOne(A8kTubeInfo.class, Map.of("typeName", TypeName));
assert info != null;
return info;
}
}

17
src/main/java/a8k/service/db/dao/MotorParameterDao.java

@ -0,0 +1,17 @@
package a8k.service.db.dao;
import a8k.service.db.entity.MotorParameter;
import com.iflytop.uf.UfActiveRecord;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class MotorParameterDao {
MotorParameter getMotorParameter(int mid) {
var param = UfActiveRecord.findOne(MotorParameter.class, Map.of("mid", mid));
assert param != null;
return param;
}
}

27
src/main/java/a8k/service/db/entity/A8kDirectCtrlPos.java

@ -0,0 +1,27 @@
package a8k.service.db.entity;
import com.iflytop.uf.UfActiveRecord;
import com.iflytop.uf.UfActiveRecordField;
/**
* A8kDirectCtrlPos
*/
public class A8kDirectCtrlPos extends UfActiveRecord {
@UfActiveRecordField
public String posName; //位置名称
@UfActiveRecordField
public Integer mid;//模块ID
@UfActiveRecordField
public String midName; //模块ID
@UfActiveRecordField
public Integer posX; //位置X如果只有一个位置则使用位置X
@UfActiveRecordField
public Integer posY; //位置Y如果有两个位置则使用位置X,Y
@UfActiveRecordField
public Integer posZ; //位置Z如果有三个位置则使用位置X,YZ
public static String getTableName() {
return "A8kDirectCtrlPos" + "Table";
}
}

20
src/main/java/a8k/service/db/entity/A8kGeneralConsumablesProperty.java

@ -0,0 +1,20 @@
package a8k.service.db.entity;
import com.iflytop.uf.UfActiveRecord;
import com.iflytop.uf.UfActiveRecordField;
/**
* A8kDirectCtrlPos
*/
public class A8kGeneralConsumablesProperty extends UfActiveRecord {
@UfActiveRecordField
public String propertyKey;
@UfActiveRecordField
public String val;
public static String getTableName() {
return "A8kGeneralConsumablesProperty" + "Table";
}
}

31
src/main/java/a8k/service/db/entity/A8kTubeInfo.java

@ -0,0 +1,31 @@
package a8k.service.db.entity;
import com.iflytop.uf.UfActiveRecord;
import com.iflytop.uf.UfActiveRecordField;
public class A8kTubeInfo extends UfActiveRecord {
/**
* 所有高度均是距离试管架底部的高度
*/
@UfActiveRecordField
public String typeName; //试管类型编码
@UfActiveRecordField
public String scanCode;//试管对应的编码
@UfActiveRecordField
public Integer tubeNum; //试管数量
@UfActiveRecordField
public Double tubeSpacing; //试管之间的间隔 单位mm
@UfActiveRecordField
public Double tubeHight;//float mm 取试管帽高度试管帽的下编研
@UfActiveRecordField
public Double tubeHightWithCap;//float mm 取试管帽高度试管帽的下编研
@UfActiveRecordField
public String tubeCapHight;//试管帽高度
@UfActiveRecordField
public Double sampleHeight;//float mm 取样高度
@UfActiveRecordField
public Double sampleBottom;//float mm 取样低位
}

28
src/main/java/a8k/service/db/entity/MotorParameter.java

@ -0,0 +1,28 @@
package a8k.service.db.entity;
import com.iflytop.uf.UfActiveRecord;
import com.iflytop.uf.UfActiveRecordField;
public class MotorParameter extends UfActiveRecord {
@UfActiveRecordField
Integer mid; //模块ID
@UfActiveRecordField
String moduleName; //模块名称
@UfActiveRecordField
Integer zeroPosOff; //零点偏移
@UfActiveRecordField
Integer moveToZeroOvertime;// 回零超时时间
@UfActiveRecordField
Integer defaultVelocity; //默认速度
@UfActiveRecordField
Integer backToZeroVelocity; //回零速度
@UfActiveRecordField
Integer loseStepWarningJudgeDistance; //丢步异常警告距离
}

132
src/main/java/a8k/service/hardware/MotorTubeRackMoveService.java

@ -1,4 +1,136 @@
package a8k.service.hardware;
import a8k.service.db.dao.A8kDirectCtrlPosDao;
import a8k.service.db.dao.A8kTubeInfoDao;
import a8k.service.db.dao.MotorParameterDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MotorTubeRackMoveService {
/**
*
* 主要用来控制试管架的平移动作控制
*
* 编写注意事项:
* 1.坐标从数据库中拿一些关键点的坐标进行运算
* 2.直接调用A8kCanBusService的方法
* 3.利用光电和编码器检查设备是否运行到位
*
*/
// kMotorTubeRackMotor_tubeScanPos
// kMotorTubeRackMotor_tubeHeighJudgmentPos
// kMotorTubeRackMotor_tubePreProcessPos
// kMotorTubeRackMotor_tubeExistJudgmentPos
//
// kMotorTubeRackMotor_tubeRackEnterPos
// kMotorTubeRackMotor_tubeRackExitPos
// kMotorTubeRackMotor_tubeRackScanCodePos
@Autowired
A8kDirectCtrlPosDao directCtrlPosTableDao;
@Autowired
A8kTubeInfoDao tubeInfoDao;
@Autowired
MotorParameterDao motorParameterDao;
//
// 电机基础控制
//
void moveToZeroWhenDeviceSetup() {
}
void moveToZero() {
//先通过move_to 指令移动到零点
//再通过 move_to_zero 进行归零(设置超时时间)超时时间来源MotorParameterDao
//最后读取 寄存器dval,判断move_to_zero移动了多少距离如果dval过大则抛出电机丢步异常
}
//
// 试管架移动
//
/**
* 移动试管架到入口位置
*/
void moveTubeRackToEnterPos() {
}
/**
* 移动试管架到出口位置
*/
void moveTubeRackToExitPos() {
}
/**
* 移动试管架到试管架扫码位置
*/
void moveTubeRackToScanPos() {
}
//
// 试管移动
//
/**
* 移动试管到扫码位置
* @param tubeType
* @param tubeIndex
*/
void moveTubeToScanPos(String tubeType, Integer tubeIndex) {
}
/**
* 移动试管到试管高低判断位置
* @param tubeType
* @param tubeIndex
*/
void moveTubeToHeighJudgmentPos(String tubeType, Integer tubeIndex) {
}
/**
* 移动试管到试管预处理的位置
* @param tubeType
* @param tubeIndex
*/
void moveTubeToPreProcessPos(String tubeType, Integer tubeIndex) {
}
//
// 状态检测
//
/**
* 移动试管到试管有无判断位置
* @param tubeType
* @param tubeIndex
*/
void moveTubeToExistJudgmentPos(String tubeType, Integer tubeIndex) {
}
boolean isTubeRackExitInEnterPos() {
return false;
}
boolean isTubeRackExitInExitPos() {
return false;
}
/**
* 获取移动通道的光电状态
* @param photoelectricIndex 0:里光电1:外光电
* @return true, 光电触发 false,光电没有触发
*/
boolean getMoveChannelPhotoelectricState(int photoelectricIndex) {
return false;
}
}
Loading…
Cancel
Save