Browse Source

ADD 硬件指令

master
HSZ_HeSongZhen 2 weeks ago
parent
commit
76ce02af3e
  1. 1
      src/main/java/com/iflytop/colortitration/common/enums/Action.java
  2. 85
      src/main/java/com/iflytop/colortitration/hardware/command/handlers/CeramicPumpHandler.java
  3. 64
      src/main/java/com/iflytop/colortitration/hardware/command/handlers/ClawHandler.java
  4. 0
      src/main/java/com/iflytop/colortitration/hardware/command/handlers/HeatRodHandler.java
  5. 55
      src/main/java/com/iflytop/colortitration/hardware/command/handlers/IOCtrlHandler.java
  6. 145
      src/main/java/com/iflytop/colortitration/hardware/command/handlers/MotorHandler.java
  7. 86
      src/main/java/com/iflytop/colortitration/hardware/command/handlers/TricolorLightHandler.java
  8. 225
      src/main/java/com/iflytop/colortitration/hardware/config/StepMotorConfig.java
  9. 84
      src/main/java/com/iflytop/colortitration/hardware/controller/AcidPumpController.java
  10. 91
      src/main/java/com/iflytop/colortitration/hardware/controller/DualRobotController.java
  11. 70
      src/main/java/com/iflytop/colortitration/hardware/controller/HeaterMotorController.java
  12. 2
      src/main/java/com/iflytop/colortitration/hardware/controller/IOController.java
  13. 267
      src/main/java/com/iflytop/colortitration/hardware/drivers/CeramicPumpDriver.java
  14. 53
      src/main/java/com/iflytop/colortitration/hardware/drivers/ColdTrapDriver.java
  15. 24
      src/main/java/com/iflytop/colortitration/hardware/drivers/DODriver/FanDriver.java
  16. 22
      src/main/java/com/iflytop/colortitration/hardware/drivers/DODriver/VentilatorDriver.java
  17. 22
      src/main/java/com/iflytop/colortitration/hardware/drivers/DODriver/WaterPumpDriver.java
  18. 23
      src/main/java/com/iflytop/colortitration/hardware/drivers/FillLightDriver.java
  19. 122
      src/main/java/com/iflytop/colortitration/hardware/drivers/HeaterRodDriver.java
  20. 2
      src/main/java/com/iflytop/colortitration/hardware/drivers/InputDetectDriver.java
  21. 28
      src/main/java/com/iflytop/colortitration/hardware/drivers/LeisaiServoDriver.java
  22. 64
      src/main/java/com/iflytop/colortitration/hardware/drivers/LiquidDistributionArmDriver.java
  23. 127
      src/main/java/com/iflytop/colortitration/hardware/drivers/MiniServoDriver.java
  24. 110
      src/main/java/com/iflytop/colortitration/hardware/drivers/MiniServoDriver/ClawDriver.java
  25. 180
      src/main/java/com/iflytop/colortitration/hardware/drivers/MiniServoDriver/DualRobotDriver.java
  26. 6
      src/main/java/com/iflytop/colortitration/hardware/drivers/ModuleEnableCtrlDriver.java
  27. 41
      src/main/java/com/iflytop/colortitration/hardware/drivers/MotorWrapperDriver.java
  28. 18
      src/main/java/com/iflytop/colortitration/hardware/drivers/OutputIOCtrlDriver.java
  29. 43
      src/main/java/com/iflytop/colortitration/hardware/drivers/StepMotorCtrlDriver.java
  30. 101
      src/main/java/com/iflytop/colortitration/hardware/drivers/StepMotorDriver/AcidPumpDriver.java
  31. 100
      src/main/java/com/iflytop/colortitration/hardware/drivers/StepMotorDriver/HBotDriver.java
  32. 79
      src/main/java/com/iflytop/colortitration/hardware/drivers/StepMotorDriver/HeaterMotorDriver.java
  33. 90
      src/main/java/com/iflytop/colortitration/hardware/drivers/StepMotorDriver/ShakeMotorDriver.java
  34. 98
      src/main/java/com/iflytop/colortitration/hardware/drivers/StepMotorDriver/TrayMotorDriver.java
  35. 2
      src/main/java/com/iflytop/colortitration/hardware/drivers/TricolorLightDriver.java
  36. 35
      src/main/java/com/iflytop/colortitration/hardware/type/CeramicPumpDriverSlaveId.java
  37. 15
      src/main/java/com/iflytop/colortitration/hardware/type/CmdId.java
  38. 24
      src/main/java/com/iflytop/colortitration/hardware/type/IO/OutputIOMId.java
  39. 92
      src/main/java/com/iflytop/colortitration/hardware/type/MId.java
  40. 4
      src/main/java/com/iflytop/colortitration/hardware/type/Servo/MiniServoMId.java
  41. 4
      src/main/java/com/iflytop/colortitration/hardware/type/StepMotor/MotorDirect.java
  42. 40
      src/main/java/com/iflytop/colortitration/hardware/type/StepMotor/StepMotorMId.java
  43. 122
      src/main/java/com/iflytop/colortitration/hardware/utils/ZJsonHelper.java

1
src/main/java/com/iflytop/colortitration/common/enums/Action.java

@ -19,6 +19,7 @@ public enum Action {
CLOSE_CLAMP("关闭抱闸"),
ENABLE("使能"),
DISABLE("失能"),
MOVE_END("移动到末端点"),
;
/**

85
src/main/java/com/iflytop/colortitration/hardware/command/handlers/CeramicPumpHandler.java

@ -0,0 +1,85 @@
package com.iflytop.colortitration.hardware.command.handlers;
import com.iflytop.colortitration.app.core.command.DeviceCommand;
import com.iflytop.colortitration.common.enums.Action;
import com.iflytop.colortitration.common.enums.Device;
import com.iflytop.colortitration.common.enums.MotorDirection;
import com.iflytop.colortitration.hardware.command.CommandHandler;
import com.iflytop.colortitration.hardware.drivers.CeramicPumpDriver;
import com.iflytop.colortitration.hardware.type.CeramicPumpDriverSlaveId;
import com.iflytop.colortitration.hardware.type.MId;
import com.iflytop.colortitration.hardware.type.StepMotor.MotorDirect;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static java.lang.Math.abs;
@Slf4j
@Component
@RequiredArgsConstructor
public class CeramicPumpHandler extends CommandHandler {
private final CeramicPumpDriver driver_;
private final Map<Device, CeramicPumpDriverSlaveId> stepMotorMIdMap_ = Map.ofEntries(
Map.entry(Device.CERAMIC_PUMP_1, CeramicPumpDriverSlaveId.CERAMIC_PUMP1_ID),
Map.entry(Device.CERAMIC_PUMP_2, CeramicPumpDriverSlaveId.CERAMIC_PUMP2_ID)
);
private final Map<Device, MId> supportCmdDeviceMIdMap = stepMotorMIdMap_.entrySet().stream().
collect(Collectors.toMap(Map.Entry::getKey, entry -> MId.NotSet));
private final Set<Action> supportActions = Set.of(
Action.SET, Action.CLOSE_CLAMP,
Action.MOVE_BY,
Action.STOP);
@Override
protected Map<Device, MId> getSupportCmdDeviceMIdMap() {
return supportCmdDeviceMIdMap;
}
@Override
protected Set<Action> getSupportActions() {
return supportActions;
}
public MotorDirect getMotorDirect(MotorDirection cmdDirection)
{
return switch (cmdDirection) {
case FORWARD -> MotorDirect.FORWARD;
case BACKWARD -> MotorDirect.BACKWARD;
};
}
@Override
public void handleCommand(DeviceCommand command) throws Exception {
// 发送命令
CeramicPumpDriverSlaveId slaveId = stepMotorMIdMap_.get(command.getDevice());
switch (command.getAction()) {
case MOVE_BY -> {
double distance = command.getParam().getPosition();
log.info("Motor {} Move By Distance {}", slaveId, distance);
CeramicPumpDriver.Direction direction = distance < 0 ?
CeramicPumpDriver.Direction.BACKWARD : CeramicPumpDriver.Direction.FORWARD;
driver_.moveByBlock(slaveId, direction, abs((int)(distance)));
}
case STOP -> {
log.info("Motor {} Stop", slaveId);
driver_.stop(slaveId);
}
case SET -> {
Double speed = command.getParam().getSpeed();
if (speed != null) {
double d_speed = speed;
log.info("Motor {} Set Speed {}", slaveId, speed);
driver_.setSpeed(slaveId, (int)d_speed);
}
}
}
}
}

64
src/main/java/com/iflytop/colortitration/hardware/command/handlers/ClawHandler.java

@ -1,64 +0,0 @@
package com.iflytop.colortitration.hardware.command.handlers;
import com.iflytop.colortitration.app.core.command.DeviceCommand;
import com.iflytop.colortitration.common.enums.Action;
import com.iflytop.colortitration.common.enums.Device;
import com.iflytop.colortitration.hardware.command.CommandHandler;
import com.iflytop.colortitration.hardware.drivers.MiniServoDriver.ClawDriver;
import com.iflytop.colortitration.hardware.type.MId;
import com.iflytop.colortitration.hardware.type.Servo.MiniServoMId;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Slf4j
@Component
@RequiredArgsConstructor
public class ClawHandler extends CommandHandler {
private final ClawDriver clawDriver_;
private final Map<Device, MiniServoMId> servoMIdMap_ = Map.ofEntries(
Map.entry(Device.CLAW, MiniServoMId.CLAW_MID)
);
private final Map<Device, MId> supportCmdDeviceMIdMap = servoMIdMap_.entrySet().stream().
collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().mid));
private final Set<Action> supportActions = Set.of(Action.SET, Action.ORIGIN, Action.MOVE, Action.STOP);
@Override
protected Map<Device, MId> getSupportCmdDeviceMIdMap()
{
return supportCmdDeviceMIdMap;
}
@Override
protected Set<Action> getSupportActions() {
return supportActions;
}
@Override
public void handleCommand(DeviceCommand command) throws Exception {
// 发送命令
MiniServoMId servoMId = servoMIdMap_.get(command.getDevice());
if (command.getAction() == Action.ORIGIN) {
clawDriver_.moveToHome(servoMId);
}
else if(command.getAction() == Action.STOP) {
clawDriver_.stop(servoMId);
}
else if(command.getAction() == Action.MOVE) {
double position = command.getParam().getPosition();
clawDriver_.moveTo(servoMId, position);
}
else if(command.getAction() == Action.SET) {
Double speed = command.getParam().getSpeed();
if(speed != null) {
clawDriver_.setSpeed(servoMId, speed);
}
}
}
}

0
src/main/java/com/iflytop/colortitration/hardware/command/handlers/HeatRodHandler.java

55
src/main/java/com/iflytop/colortitration/hardware/command/handlers/IOCtrlHandler.java

@ -0,0 +1,55 @@
package com.iflytop.colortitration.hardware.command.handlers;
import com.iflytop.colortitration.app.core.command.DeviceCommand;
import com.iflytop.colortitration.common.enums.Action;
import com.iflytop.colortitration.common.enums.Device;
import com.iflytop.colortitration.hardware.command.CommandHandler;
import com.iflytop.colortitration.hardware.drivers.OutputIOCtrlDriver;
import com.iflytop.colortitration.hardware.type.IO.OutputIOMId;
import com.iflytop.colortitration.hardware.type.MId;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
//
@Slf4j
@Component
@RequiredArgsConstructor
public class IOCtrlHandler extends CommandHandler {
private final OutputIOCtrlDriver driver_;
private final Map<Device, OutputIOMId> supportCmdDeviceIOOutputMap = Map.ofEntries(
);
private final Map<Device, MId> supportCmdDeviceMIdMap = supportCmdDeviceIOOutputMap.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().mid));
private final Set<Action> supportActions = Set.of(Action.OPEN, Action.CLOSE);
@Override
protected Map<Device, MId> getSupportCmdDeviceMIdMap()
{
return supportCmdDeviceMIdMap;
}
@Override
protected Set<Action> getSupportActions() {
return supportActions;
}
@Override
public void handleCommand(DeviceCommand command) throws Exception {
// 发送命令
if (command.getAction() == Action.OPEN) {
log.info("open {}", command.getDevice());
driver_.open(supportCmdDeviceIOOutputMap.get(command.getDevice()));
} else if (command.getAction() == Action.CLOSE) {
log.info("close {}", command.getDevice());
driver_.close(supportCmdDeviceIOOutputMap.get(command.getDevice()));
}
}
}

145
src/main/java/com/iflytop/colortitration/hardware/command/handlers/MotorHandler.java

@ -0,0 +1,145 @@
package com.iflytop.colortitration.hardware.command.handlers;
import com.iflytop.colortitration.app.core.command.DeviceCommand;
import com.iflytop.colortitration.common.enums.Action;
import com.iflytop.colortitration.common.enums.Device;
import com.iflytop.colortitration.common.enums.MotorDirection;
import com.iflytop.colortitration.hardware.command.CommandHandler;
import com.iflytop.colortitration.hardware.drivers.MotorWrapperDriver;
import com.iflytop.colortitration.hardware.type.MId;
import com.iflytop.colortitration.hardware.type.StepMotor.MotorDirect;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorMId;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Slf4j
@Component
@RequiredArgsConstructor
public class MotorHandler extends CommandHandler {
private final MotorWrapperDriver driver_;
private final Map<Device, StepMotorMId> stepMotorMIdMap_ = Map.ofEntries(
Map.entry(Device.ROBOTIC_ARM_BIG, StepMotorMId.DualRobot1M),
Map.entry(Device.ROBOTIC_ARM_SMALL, StepMotorMId.DualRobot2M),
Map.entry(Device.Z_MOTOR, StepMotorMId.RobotArmZM),
Map.entry(Device.BRUSHLESS_PUMP_1, StepMotorMId.BrushlessPump1M),
Map.entry(Device.BRUSHLESS_PUMP_2, StepMotorMId.BrushlessPump2M),
Map.entry(Device.BRUSHLESS_PUMP_3, StepMotorMId.BrushlessPump3M),
Map.entry(Device.BRUSHLESS_PUMP_4, StepMotorMId.BrushlessPump4M),
Map.entry(Device.BRUSHLESS_PUMP_5, StepMotorMId.BrushlessPump5M),
Map.entry(Device.BRUSHLESS_PUMP_6, StepMotorMId.BrushlessPump6M),
Map.entry(Device.BRUSHLESS_PUMP_7, StepMotorMId.BrushlessPump7M),
Map.entry(Device.BRUSHLESS_PUMP_8, StepMotorMId.BrushlessPump8M),
Map.entry(Device.BRUSHLESS_PUMP_9, StepMotorMId.BrushlessPump9M),
Map.entry(Device.BRUSHLESS_PUMP_10, StepMotorMId.BrushlessPump10M),
Map.entry(Device.STEP_PUMP_1, StepMotorMId.StepPump1M),
Map.entry(Device.STEP_PUMP_2, StepMotorMId.StepPump2M),
Map.entry(Device.STEP_PUMP_3, StepMotorMId.StepPump3M),
Map.entry(Device.STIR_MOTOR_1, StepMotorMId.TitratorStir1M),
Map.entry(Device.STIR_MOTOR_2, StepMotorMId.TitratorStir2M),
Map.entry(Device.TITRATION_MOTOR_1, StepMotorMId.Titrator1M),
Map.entry(Device.TITRATION_MOTOR_2, StepMotorMId.Titrator2M)
);
private final Map<Device, MId> supportCmdDeviceMIdMap = stepMotorMIdMap_.entrySet().stream().
collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().mid));
private final Set<Action> supportActions = Set.of(
Action.SET,
Action.ENABLE,
Action.DISABLE,
Action.OPEN_CLAMP,
Action.CLOSE_CLAMP,
Action.ORIGIN,
Action.MOVE,
Action.MOVE_BY,
Action.ROTATE,
Action.STOP,
Action.MOVE_END);
@Override
protected Map<Device, MId> getSupportCmdDeviceMIdMap() {
return supportCmdDeviceMIdMap;
}
@Override
protected Set<Action> getSupportActions() {
return supportActions;
}
public MotorDirect getMotorDirect(MotorDirection cmdDirection)
{
return switch (cmdDirection) {
case FORWARD -> MotorDirect.FORWARD;
case BACKWARD -> MotorDirect.BACKWARD;
};
}
@Override
public void handleCommand(DeviceCommand command) throws Exception {
// 发送命令
StepMotorMId stepMotorMId = stepMotorMIdMap_.get(command.getDevice());
switch (command.getAction()) {
case ENABLE -> {
log.info("Motor {} Enable", stepMotorMId.mid.getDescription());
driver_.motorEnable(stepMotorMId, true);
}
case DISABLE -> {
log.info("Motor {} Disable", stepMotorMId.mid.getDescription());
driver_.motorEnable(stepMotorMId, false);
}
case OPEN_CLAMP -> {
log.info("Motor {} Open Clamp", stepMotorMId.mid.getDescription());
driver_.openClamp(stepMotorMId);
}
case CLOSE_CLAMP -> {
log.info("Motor {} Close Clamp", stepMotorMId.mid.getDescription());
driver_.closeClamp(stepMotorMId);
}
case ORIGIN -> {
log.info("Motor {} Move To Origin", stepMotorMId.mid.getDescription());
driver_.moveToHome(stepMotorMId);
}
case MOVE -> {
double position = command.getParam().getPosition();
log.info("Motor {} Move To Position {}", stepMotorMId.mid.getDescription(), position);
driver_.moveTo(stepMotorMId, position);
}
case MOVE_BY -> {
double distance = command.getParam().getPosition();
log.info("Motor {} Move By Distance {}", stepMotorMId.mid.getDescription(), distance);
driver_.moveBy(stepMotorMId, distance);
}
case ROTATE -> {
MotorDirection cmdDirection = command.getParam().getDirection();
MotorDirect direct = getMotorDirect(cmdDirection);
log.info("Motor {} Rotate {}", stepMotorMId.mid.getDescription(), direct.name());
driver_.rotate(stepMotorMId, direct);
}
case STOP -> {
log.info("Motor {} Stop", stepMotorMId.mid.getDescription());
driver_.stop(stepMotorMId);
}
case SET -> {
Double speed = command.getParam().getSpeed();
if (speed != null) {
log.info("Motor {} Set Speed {}", stepMotorMId.mid.getDescription(), speed);
driver_.setSpeed(stepMotorMId, speed);
}
}
case MOVE_END -> {
driver_.moveToEnd(stepMotorMId);
}
}
}
}

86
src/main/java/com/iflytop/colortitration/hardware/command/handlers/TricolorLightHandler.java

@ -0,0 +1,86 @@
package com.iflytop.colortitration.hardware.command.handlers;
import com.iflytop.colortitration.app.core.command.DeviceCommand;
import com.iflytop.colortitration.common.enums.Action;
import com.iflytop.colortitration.common.enums.Device;
import com.iflytop.colortitration.common.enums.TricolorLightColor;
import com.iflytop.colortitration.hardware.command.CommandHandler;
import com.iflytop.colortitration.hardware.drivers.TricolorLightDriver;
import com.iflytop.colortitration.hardware.type.MId;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.security.InvalidParameterException;
import java.util.Map;
import java.util.Set;
import static java.awt.Color.blue;
/**
* 三色灯
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class TricolorLightHandler extends CommandHandler {
private final TricolorLightDriver tricolorLightDriver;
private final Map<Device, MId> supportCmdDeviceMIdMap = Map.ofEntries(
Map.entry(Device.TRICOLOR_LIGHT, MId.IO1_TriColorLight)
);
private final Set<Action> supportActions = Set.of(Action.OPEN, Action.CLOSE);
@Override
protected Map<Device, MId> getSupportCmdDeviceMIdMap()
{
return supportCmdDeviceMIdMap;
}
@Override
protected Set<Action> getSupportActions() {
return supportActions;
}
@Override
protected void checkParams(DeviceCommand command) throws Exception {
// 检查参数
if (command.getAction() == Action.OPEN) {
// 检查参数
TricolorLightColor cmdColor = command.getParam().getColor();
getCmdColor(cmdColor);
}
}
TricolorLightDriver.Color getCmdColor(TricolorLightColor cmdColor){
switch (cmdColor){
case RED:
return TricolorLightDriver.Color.RED;
case GREEN:
return TricolorLightDriver.Color.GREEN;
case BLUE:
return TricolorLightDriver.Color.BLUE;
default:
throw new InvalidParameterException("颜色参数错误");
}
}
MId getMId(Device cmdDevice){
return supportCmdDeviceMIdMap.get(cmdDevice);
}
@Override
public void handleCommand(DeviceCommand command) throws Exception {
// 发送命令
if (command.getAction() == Action.OPEN) {
TricolorLightColor cmdColor = command.getParam().getColor();
TricolorLightDriver.Color color = getCmdColor(cmdColor);
tricolorLightDriver.open(getMId(command.getDevice()), color);
} else if (command.getAction() == Action.CLOSE) {
tricolorLightDriver.close(getMId(command.getDevice()));
}
}
}

225
src/main/java/com/iflytop/colortitration/hardware/config/StepMotorConfig.java

@ -9,211 +9,12 @@ import java.util.Map;
@Slf4j
@Component
public class StepMotorConfig {
// 导程 配置
private final static double DEFAULT_LEAD = 10.0; // mm
final static Map<StepMotorMId, Double> stepMotorLeadMap = Map.ofEntries(
Map.entry(StepMotorMId.TRAY_MOTOR_MID, 5.0),
Map.entry(StepMotorMId.HBOT_X_MOTOR_MID, 5.0),
Map.entry(StepMotorMId.HBOT_Y_MOTOR_MID, 4.0),
Map.entry(StepMotorMId.HBOT_Z_MOTOR_MID, 5.0),
Map.entry(StepMotorMId.HEATER_1_MOTOR_MID, 5.0)
);
// 电流配置
final static int DEFAULT_CURRENT = 8; // [0-31]
final static int HEATER_MOTOR_DEFAULT_CURRENT = 20;
final static int ACID_PUMP_MOTOR_DEFAULT_CURRENT = 8;
final static Map<StepMotorMId, Integer> stepMotorCurrentMap = Map.ofEntries(
Map.entry(StepMotorMId.SHAKE_MOTOR_MID, 8),
Map.entry(StepMotorMId.HBOT_X_MOTOR_MID, 31),
Map.entry(StepMotorMId.HBOT_Y_MOTOR_MID, 31),
Map.entry(StepMotorMId.HBOT_Z_MOTOR_MID, 31),
Map.entry(StepMotorMId.HEATER_1_MOTOR_MID, HEATER_MOTOR_DEFAULT_CURRENT),
Map.entry(StepMotorMId.HEATER_2_MOTOR_MID, HEATER_MOTOR_DEFAULT_CURRENT),
Map.entry(StepMotorMId.HEATER_3_MOTOR_MID, HEATER_MOTOR_DEFAULT_CURRENT),
Map.entry(StepMotorMId.HEATER_4_MOTOR_MID, HEATER_MOTOR_DEFAULT_CURRENT),
Map.entry(StepMotorMId.HEATER_5_MOTOR_MID, HEATER_MOTOR_DEFAULT_CURRENT),
Map.entry(StepMotorMId.HEATER_6_MOTOR_MID, HEATER_MOTOR_DEFAULT_CURRENT),
Map.entry(StepMotorMId.ACID_PUMP_1_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_CURRENT),
Map.entry(StepMotorMId.ACID_PUMP_2_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_CURRENT),
Map.entry(StepMotorMId.ACID_PUMP_3_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_CURRENT),
Map.entry(StepMotorMId.ACID_PUMP_4_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_CURRENT),
Map.entry(StepMotorMId.ACID_PUMP_5_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_CURRENT),
Map.entry(StepMotorMId.ACID_PUMP_6_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_CURRENT),
Map.entry(StepMotorMId.ACID_PUMP_7_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_CURRENT),
Map.entry(StepMotorMId.ACID_PUMP_8_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_CURRENT)
);
// 速度配置
final static double DEFAULT_SPEED = 1.0; // mm/s
final static double HEATER_MOTOR_DEFAULT_SPEED = 1.0;
final static double ACID_PUMP_MOTOR_DEFAULT_SPEED = 1.0;
final static Map<StepMotorMId, Double> stepMotorSpeedMap = Map.ofEntries(
Map.entry(StepMotorMId.SHAKE_MOTOR_MID, 1.0),
Map.entry(StepMotorMId.HBOT_X_MOTOR_MID, 20.0),
Map.entry(StepMotorMId.HBOT_Y_MOTOR_MID, 20.0),
Map.entry(StepMotorMId.HBOT_Z_MOTOR_MID, 20.0),
Map.entry(StepMotorMId.HEATER_1_MOTOR_MID, HEATER_MOTOR_DEFAULT_SPEED),
Map.entry(StepMotorMId.HEATER_2_MOTOR_MID, HEATER_MOTOR_DEFAULT_SPEED),
Map.entry(StepMotorMId.HEATER_3_MOTOR_MID, HEATER_MOTOR_DEFAULT_SPEED),
Map.entry(StepMotorMId.HEATER_4_MOTOR_MID, HEATER_MOTOR_DEFAULT_SPEED),
Map.entry(StepMotorMId.HEATER_5_MOTOR_MID, HEATER_MOTOR_DEFAULT_SPEED),
Map.entry(StepMotorMId.HEATER_6_MOTOR_MID, HEATER_MOTOR_DEFAULT_SPEED),
Map.entry(StepMotorMId.ACID_PUMP_1_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_SPEED),
Map.entry(StepMotorMId.ACID_PUMP_2_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_SPEED),
Map.entry(StepMotorMId.ACID_PUMP_3_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_SPEED),
Map.entry(StepMotorMId.ACID_PUMP_4_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_SPEED),
Map.entry(StepMotorMId.ACID_PUMP_5_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_SPEED),
Map.entry(StepMotorMId.ACID_PUMP_6_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_SPEED),
Map.entry(StepMotorMId.ACID_PUMP_7_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_SPEED),
Map.entry(StepMotorMId.ACID_PUMP_8_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_SPEED)
);
// 最小限位配置
static final double DEFAULT_MIN_LIMIT = 0.0; // mm
static final double HEATER_MOTOR_DEFAULT_MIN_LIMIT = 0.0;
static final double ACID_PUMP_MOTOR_DEFAULT_MIN_LIMIT = 0.0;
final static Map<StepMotorMId, Double> stepMotorMinLimitMap = Map.ofEntries(
Map.entry(StepMotorMId.HBOT_X_MOTOR_MID, 0.0),
Map.entry(StepMotorMId.HBOT_Y_MOTOR_MID, 0.0),
Map.entry(StepMotorMId.HBOT_Z_MOTOR_MID, 0.0)
);
// 最大限位配置
static final double DEFAULT_MAX_LIMIT = 0.0; // mm
static final double HEATER_MOTOR_DEFAULT_MAX_LIMIT = 100.0;
static final double ACID_PUMP_MOTOR_DEFAULT_MAX_LIMIT = 1000000;
static final double DEFAULT_MAX_LIMIT = Double.POSITIVE_INFINITY; // mm
final static Map<StepMotorMId, Double> stepMotorMaxLimitMap = Map.ofEntries(
Map.entry(StepMotorMId.DOOR_MOTOR_MID, 500.0),
Map.entry(StepMotorMId.SHAKE_MOTOR_MID, 20000.0),
Map.entry(StepMotorMId.TRAY_MOTOR_MID, 385.0),
Map.entry(StepMotorMId.HBOT_X_MOTOR_MID, 1400.0),
Map.entry(StepMotorMId.HBOT_Y_MOTOR_MID, 700.0),
Map.entry(StepMotorMId.HBOT_Z_MOTOR_MID, 300.0),
Map.entry(StepMotorMId.HEATER_1_MOTOR_MID, HEATER_MOTOR_DEFAULT_MAX_LIMIT),
Map.entry(StepMotorMId.HEATER_2_MOTOR_MID, HEATER_MOTOR_DEFAULT_MAX_LIMIT),
Map.entry(StepMotorMId.HEATER_3_MOTOR_MID, HEATER_MOTOR_DEFAULT_MAX_LIMIT),
Map.entry(StepMotorMId.HEATER_4_MOTOR_MID, HEATER_MOTOR_DEFAULT_MAX_LIMIT),
Map.entry(StepMotorMId.HEATER_5_MOTOR_MID, HEATER_MOTOR_DEFAULT_MAX_LIMIT),
Map.entry(StepMotorMId.HEATER_6_MOTOR_MID, HEATER_MOTOR_DEFAULT_MAX_LIMIT),
Map.entry(StepMotorMId.ACID_PUMP_1_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_MAX_LIMIT),
Map.entry(StepMotorMId.ACID_PUMP_2_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_MAX_LIMIT),
Map.entry(StepMotorMId.ACID_PUMP_3_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_MAX_LIMIT),
Map.entry(StepMotorMId.ACID_PUMP_4_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_MAX_LIMIT),
Map.entry(StepMotorMId.ACID_PUMP_5_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_MAX_LIMIT),
Map.entry(StepMotorMId.ACID_PUMP_6_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_MAX_LIMIT),
Map.entry(StepMotorMId.ACID_PUMP_7_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_MAX_LIMIT),
Map.entry(StepMotorMId.ACID_PUMP_8_MOTOR_MID, ACID_PUMP_MOTOR_DEFAULT_MAX_LIMIT)
);
// 是否安装编码器
private final static boolean DEFAULT_ENCODER_INSTALLED = false;
static Map<StepMotorMId, Boolean> stepMotorEncoderMap = Map.ofEntries(
Map.entry(StepMotorMId.HBOT_X_MOTOR_MID, true),
Map.entry(StepMotorMId.HBOT_Y_MOTOR_MID, true),
Map.entry(StepMotorMId.HBOT_Z_MOTOR_MID, true)
);
/* ******************** ******************** ******************** */
/* ******************** 导程 ******************** */
/* ******************** ******************** ******************** */
// 从数据库拉取导程信息
private Double getLeadFromDB(StepMotorMId stepMotorId)
{
// TODO: 从数据库中获取导程
return null;
}
// 从默认配置中获取导程信息
private Double getLeadFromDefault(StepMotorMId stepMotorId)
{
return stepMotorLeadMap.getOrDefault(stepMotorId, DEFAULT_LEAD);
}
// 获取导程信息
public double getLead(StepMotorMId stepMotorId)
{
Double lead = getLeadFromDB(stepMotorId);
if (lead != null) {
return lead;
} else {
return getLeadFromDefault(stepMotorId);
}
}
/* ******************** ******************** ******************** */
/* ******************** 电流 ******************** */
/* ******************** ******************** ******************** */
// 从数据库拉取电流信息
private Integer getCurrentFromDB(StepMotorMId stepMotorId)
{
// TODO: 从数据库中获取电流
return null;
}
private Integer getCurrentFromDefault(StepMotorMId stepMotorId)
{
return stepMotorCurrentMap.getOrDefault(stepMotorId, DEFAULT_CURRENT);
}
public int getCurrent(StepMotorMId stepMotorId)
{
Integer current = getCurrentFromDB(stepMotorId);
if (current != null) {
return current;
} else {
return getCurrentFromDefault(stepMotorId);
}
}
/* ******************** ******************** ******************** */
/* ******************** 速度 ******************** */
/* ******************** ******************** ******************** */
// 从数据库拉取速度信息
private Double getSpeedFromDB(StepMotorMId stepMotorId)
{
// TODO: 从数据库中获取速度
return null;
}
private Double getSpeedFromDefault(StepMotorMId stepMotorId)
{
return stepMotorSpeedMap.getOrDefault(stepMotorId, DEFAULT_SPEED);
}
public double getSpeed(StepMotorMId stepMotorId)
{
Double speed = getSpeedFromDB(stepMotorId);
if (speed != null) {
return speed;
} else {
return getSpeedFromDefault(stepMotorId);
}
}
/* ******************** ******************** ******************** */
/* ******************** 最小限位 ******************** */
/* ******************** ******************** ******************** */
// 从数据库拉取最小限位信息
private Double getMinLimitFromDB(StepMotorMId stepMotorId)
{
// TODO: 从数据库中获取最小限位
return null;
}
private Double getMinLimitFromDefault(StepMotorMId stepMotorId)
{
return stepMotorMinLimitMap.getOrDefault(stepMotorId, DEFAULT_MIN_LIMIT);
}
public double getMinLimit(StepMotorMId stepMotorId)
{
Double minLimit = getMinLimitFromDB(stepMotorId);
if (minLimit != null) {
return minLimit;
} else {
return getMinLimitFromDefault(stepMotorId);
}
}
/* ******************** ******************** ******************** */
/* ******************** 最大限位 ******************** */
@ -240,28 +41,4 @@ public class StepMotorConfig {
}
}
/* ******************** ******************** ******************** */
/* ******************** 编码器 ******************** */
/* ******************** ******************** ******************** */
// 从数据库拉取编码器信息
private Boolean getEncoderFromDB(StepMotorMId stepMotorId)
{
//TODO: 从数据库中获取编码器
return null;
}
private Boolean getEncoderFromDefault(StepMotorMId stepMotorId)
{
return stepMotorEncoderMap.getOrDefault(stepMotorId, DEFAULT_ENCODER_INSTALLED);
}
public boolean isEncoderInstalled(StepMotorMId stepMotorId)
{
Boolean encoder = getEncoderFromDB(stepMotorId);
if (encoder != null) {
return encoder;
} else {
return getEncoderFromDefault(stepMotorId);
}
}
}

84
src/main/java/com/iflytop/colortitration/hardware/controller/AcidPumpController.java

@ -1,84 +0,0 @@
package com.iflytop.colortitration.hardware.controller;
import com.iflytop.colortitration.app.service.DeviceParamConfigService;
import com.iflytop.colortitration.hardware.drivers.StepMotorDriver.AcidPumpDriver;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorMId;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorRegIndex;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "加酸泵控制")
@RestController
@RequestMapping("/api/acid-pump")
@RequiredArgsConstructor
@Slf4j
public class AcidPumpController {
private final AcidPumpDriver driver;
private final DeviceParamConfigService deviceParamConfigService;
@PostMapping("/set-speed")
public void setSpeed(@RequestParam StepMotorMId stepMotorMId, @RequestParam int speed) {
log.info("Setting acid pump speed to: {}", speed);
try {
driver.setSpeed(stepMotorMId, speed);
deviceParamConfigService.setModuleAndReg(stepMotorMId.mid.name(), StepMotorRegIndex.kreg_step_motor_default_velocity.regIndex.name(),speed);
} catch (Exception e) {
log.error("Failed to set speed for acid pump: {}", e.getMessage());
}
}
@PostMapping("/motor-enable")
public void motorEnable(@RequestParam StepMotorMId stepMotorMId, @RequestParam boolean enable) {
log.info("Setting acid pump motor enable to: {}", enable);
try {
driver.motorEnable(stepMotorMId, enable);
} catch (Exception e) {
log.error("Failed to enable motor for acid pump: {}", e.getMessage());
}
}
@PostMapping("/move-to-home")
public void moveToHome(@RequestParam StepMotorMId stepMotorMId) {
log.info("Moving acid pump to home position");
try {
driver.moveToHome(stepMotorMId);
} catch (Exception e) {
log.error("Failed to move acid pump to home: {}", e.getMessage());
}
}
@PostMapping("/move-to")
public void moveTo(@RequestParam StepMotorMId stepMotorMId, @RequestParam int position) {
log.info("Moving acid pump to position: {}", position);
try {
driver.moveTo(stepMotorMId, position);
} catch (Exception e) {
log.error("Failed to move acid pump to position: {}", e.getMessage());
}
}
@PostMapping("/move-by")
public void moveBy(@RequestParam StepMotorMId stepMotorMId, @RequestParam int offset) {
log.info("Moving acid pump by offset: {}", offset);
try {
driver.moveBy(stepMotorMId, offset);
} catch (Exception e) {
log.error("Failed to move acid pump by offset: {}", e.getMessage());
}
}
@PostMapping("/stop")
public void stop(@RequestParam StepMotorMId stepMotorMId) {
log.info("Stopping acid pump");
try {
driver.stop(stepMotorMId);
} catch (Exception e) {
log.error("Failed to stop acid pump: {}", e.getMessage());
}
}
}

91
src/main/java/com/iflytop/colortitration/hardware/controller/DualRobotController.java

@ -1,91 +0,0 @@
package com.iflytop.colortitration.hardware.controller;
import com.iflytop.colortitration.hardware.drivers.MiniServoDriver.DualRobotDriver;
import com.iflytop.colortitration.hardware.drivers.MiniServoDriver.DualRobotDriver.Joint;
import com.iflytop.colortitration.hardware.type.Servo.MiniServoMId;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "双轴机械臂控制")
@RestController
@RequestMapping("/api/dual-robot")
@RequiredArgsConstructor
@Slf4j
public class DualRobotController {
private final DualRobotDriver driver;
@PostMapping("/move-joint-to")
public void moveJointTo(@RequestParam MiniServoMId sevoMid, @RequestParam double position) {
log.info("Moving joint {} to position {}", sevoMid, position);
try {
driver.moveJointTo(sevoMid, position);
} catch (Exception e) {
log.error("Failed to move joint {} to position {}: {}", sevoMid, position, e.getMessage());
}
}
@PostMapping("/stop-servo")
public void stop(@RequestParam MiniServoMId sevoMid) {
log.info("Stopping servo {}", sevoMid);
try {
driver.stop(sevoMid);
} catch (Exception e) {
log.error("Failed to stop servo {}: {}", sevoMid, e.getMessage());
}
}
@PostMapping("/set-speed")
public void setSpeed(@RequestParam Joint joint, @RequestParam double speed) {
log.info("Setting speed for joint {} to {}", joint, speed);
try {
driver.setSpeed(joint, speed);
} catch (Exception e) {
log.error("Failed to set speed for joint {}: {}", joint, e.getMessage());
}
}
@PostMapping("/move-to-point")
public void moveToPoint(@RequestParam double pointX, @RequestParam double pointY) {
log.info("Moving to point ({}, {})", pointX, pointY);
try {
driver.moveToPoint(pointX, pointY);
} catch (Exception e) {
log.error("Failed to move to point ({}, {}): {}", pointX, pointY, e.getMessage());
}
}
@PostMapping("/move-to-home")
public void moveToHome(@RequestParam Joint joint) {
log.info("Moving joint {} to home position", joint);
try {
driver.moveToHome(joint);
} catch (Exception e) {
log.error("Failed to move joint {} to home position: {}", joint, e.getMessage());
}
}
@PostMapping("/move-joint-to-position")
public void moveJointTo(@RequestParam Joint joint, @RequestParam double position) {
log.info("Moving joint {} to position {}", joint, position);
try {
driver.moveJointTo(joint, position);
} catch (Exception e) {
log.error("Failed to move joint {} to position {}: {}", joint, position, e.getMessage());
}
}
@PostMapping("/stop-joint")
public void stop(@RequestParam Joint joint) {
log.info("Stopping joint {}", joint);
try {
driver.stop(joint);
} catch (Exception e) {
log.error("Failed to stop joint {}: {}", joint, e.getMessage());
}
}
}

70
src/main/java/com/iflytop/colortitration/hardware/controller/HeaterMotorController.java

@ -1,70 +0,0 @@
package com.iflytop.colortitration.hardware.controller;
import com.iflytop.colortitration.hardware.drivers.StepMotorDriver.HeaterMotorDriver;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorMId;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "加热电机控制")
@RestController
@RequestMapping("/api/heater-motor")
@RequiredArgsConstructor
@Slf4j
public class HeaterMotorController {
private final HeaterMotorDriver driver;
@PostMapping("/motor-enable")
public void motorEnable(@RequestParam StepMotorMId stepMotorMId, @RequestParam boolean enable) {
log.info("Setting heater motor enable to: {}", enable);
try {
driver.motorEnable(stepMotorMId, enable);
} catch (Exception e) {
log.error("Failed to enable motor for heater motor: {}", e.getMessage());
}
}
@PostMapping("/move-to-home")
public void moveToHome(@RequestParam StepMotorMId stepMotorMId) {
log.info("Moving heater motor to home position");
try {
driver.moveToHome(stepMotorMId);
} catch (Exception e) {
log.error("Failed to move heater motor to home: {}", e.getMessage());
}
}
@PostMapping("/move-to")
public void moveTo(@RequestParam StepMotorMId stepMotorMId, @RequestParam int position) {
log.info("Moving heater motor to position: {}", position);
try {
driver.moveTo(stepMotorMId, position);
} catch (Exception e) {
log.error("Failed to move heater motor to position: {}", e.getMessage());
}
}
@PostMapping("/move-by")
public void moveBy(@RequestParam StepMotorMId stepMotorMId, @RequestParam int offset) {
log.info("Moving heater motor by offset: {}", offset);
try {
driver.moveBy(stepMotorMId, offset);
} catch (Exception e) {
log.error("Failed to move heater motor by offset: {}", e.getMessage());
}
}
@PostMapping("/stop")
public void stop(@RequestParam StepMotorMId stepMotorMId) {
log.info("Stopping heater motor");
try {
driver.stop(stepMotorMId);
} catch (Exception e) {
log.error("Failed to stop heater motor: {}", e.getMessage());
}
}
}

2
src/main/java/com/iflytop/colortitration/hardware/controller/IOController.java

@ -1,7 +1,7 @@
package com.iflytop.colortitration.hardware.controller;
import com.iflytop.colortitration.common.result.Result;
import com.iflytop.colortitration.hardware.drivers.DODriver.OutputIOCtrlDriver;
import com.iflytop.colortitration.hardware.drivers.OutputIOCtrlDriver;
import com.iflytop.colortitration.hardware.type.IO.OutputIOMId;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;

267
src/main/java/com/iflytop/colortitration/hardware/drivers/CeramicPumpDriver.java

@ -0,0 +1,267 @@
package com.iflytop.colortitration.hardware.drivers;
import com.iflytop.colortitration.hardware.comm.modbus.ModbusMasterService;
import com.iflytop.colortitration.hardware.type.CeramicPumpDriverSlaveId;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Component
@RequiredArgsConstructor
public class CeramicPumpDriver {
public enum CeramicPumpBaud {
CeramicPumpBaud_9600(0x04),
CeramicPumpBaud_115200(0x08);
int getId(){
return id;
}
private final int id;
CeramicPumpBaud(int id) {
this.id = id;
}
};
public enum Direction {
FORWARD(0x0000), // 正转
BACKWARD(0x0001); // 反转
private final int value;
Direction(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
private final ModbusMasterService modbusMaster;
private static final int DEFAULT_ADDRESS = 0x11;
private static final int ADDRESS_REGISTER = 0x000A;
private static final int BAUDRATE_REGISTER = 0x001C;
private static final int SPEED_REGISTER = 0x000C;
private static final int RESET_REGISTER = 0x0014;
private static final int MOVE_REGISTER = 0x0014;
private static final int STOP_RESUME_REGISTER = 0x0010;
private static final int DIRECTION_REGISTER = 0x000E; // 正反转控制寄存器
private static final int POSITION_REGISTER = 0x0012; // 当前圈数查询寄存器
private final ConcurrentHashMap<CeramicPumpDriverSlaveId, Boolean> runFlags = new ConcurrentHashMap<>();
/**
* 设置注射泵地址
*/
public void setDeviceAddress(CeramicPumpDriverSlaveId pumpId, int newAddress) throws Exception {
int slaveId = pumpId.getSlaveId();
if (!modbusMaster.writeRegister(slaveId, ADDRESS_REGISTER, newAddress)) {
throw new Exception("Failed to set device address for pump, slaveId: " + slaveId);
}
log.info("Pump[{}] address set to {}", slaveId, newAddress);
}
/**
* 设置波特率
*/
public void setBaudRate(CeramicPumpDriverSlaveId pumpId, CeramicPumpBaud baudRate) throws Exception {
int slaveId = pumpId.getSlaveId();
if (!modbusMaster.writeRegister(slaveId, BAUDRATE_REGISTER, baudRate.getId())) {
throw new Exception("Failed to set baud rate for pump, slaveId: " + slaveId);
}
log.info("Pump[{}] baud rate set to {}", slaveId, baudRate);
}
/**
* 设置注射泵速度
*/
public void setSpeed(CeramicPumpDriverSlaveId pumpId, int speed) throws Exception {
int slaveId = pumpId.getSlaveId();
if (!modbusMaster.writeRegister(slaveId, SPEED_REGISTER, speed)) {
throw new Exception("Failed to set speed for pump, slaveId: " + slaveId);
}
log.info("Pump[{}] speed set to {} rpm", slaveId, speed);
}
/**
* 获取注射泵速度
*/
public int getSpeed(CeramicPumpDriverSlaveId pumpId) throws Exception {
int slaveId = pumpId.getSlaveId();
short[] response = modbusMaster.readHoldingRegisters(slaveId, SPEED_REGISTER, 1);
if (response == null || response.length == 0) {
throw new Exception("Failed to read speed for pump, slaveId: " + slaveId);
}
return response[0];
}
/**
* 获取注射泵位置圈数
*/
public int getTargetPosition(CeramicPumpDriverSlaveId pumpId) throws Exception {
int slaveId = pumpId.getSlaveId();
short[] response = modbusMaster.readHoldingRegisters(slaveId, MOVE_REGISTER, 1);
if (response == null || response.length == 0) {
throw new Exception("Failed to read position for pump, slaveId: " + slaveId);
}
return response[0];
}
/**
* 查询注射泵当前地址ID
*/
public int getDeviceAddress(CeramicPumpDriverSlaveId pumpId) throws Exception {
int slaveId = pumpId.getSlaveId();
short[] response = modbusMaster.readHoldingRegisters(slaveId, ADDRESS_REGISTER, 1);
if (response == null || response.length == 0) {
throw new Exception("Failed to read device address for pump, slaveId: " + slaveId);
}
return response[0];
}
/**
* 复位
*/
public void reset(CeramicPumpDriverSlaveId pumpId) throws Exception {
int slaveId = pumpId.getSlaveId();
if (!modbusMaster.writeRegister(slaveId, RESET_REGISTER, 0)) {
throw new Exception("Failed to reset pump, slaveId: " + slaveId);
}
log.info("Pump[{}] reset", slaveId);
}
/**
* 定量运动
*/
public void moveBy(CeramicPumpDriverSlaveId pumpId, int r) throws Exception {
int slaveId = pumpId.getSlaveId();
if (!modbusMaster.writeRegister(slaveId, MOVE_REGISTER, r)) {
throw new Exception("Failed to move pump, slaveId: " + slaveId + ", r: " + r);
}
log.info("Pump[{}] move {} turns", slaveId, r);
}
/**
* 设置正反转方向
* @param direction 正转(FORWARD)或反转(REVERSE)
*/
public void setDirection(CeramicPumpDriverSlaveId pumpId, Direction direction) throws Exception {
int slaveId = pumpId.getSlaveId();
if (!modbusMaster.writeRegister(slaveId, DIRECTION_REGISTER, direction.getValue())) {
throw new Exception("Failed to set direction for pump, slaveId: " + slaveId);
}
log.info("Pump[{}] direction set to {}", slaveId, direction);
}
public int getCurrentPosition(CeramicPumpDriverSlaveId pumpId) throws Exception {
int slaveId = pumpId.getSlaveId();
short[] response = modbusMaster.readHoldingRegisters(slaveId, POSITION_REGISTER, 1);
if (response == null || response.length == 0) {
throw new Exception("Failed to read current position for pump, slaveId: " + slaveId);
}
return response[0];
}
// 停止运动
public void stop(CeramicPumpDriverSlaveId pumpId) throws Exception {
int slaveId = pumpId.getSlaveId();
if (!modbusMaster.writeRegister(slaveId, STOP_RESUME_REGISTER, 0x0000)) {
throw new Exception("Failed to stop pump, slaveId: " + slaveId);
}
log.info("Pump[{}] stopped", slaveId);
}
/**
* 继续运动
*/
public void resume(CeramicPumpDriverSlaveId pumpId) throws Exception {
int slaveId = pumpId.getSlaveId();
if (!modbusMaster.writeRegister(slaveId, STOP_RESUME_REGISTER, 0x0001)) {
throw new Exception("Failed to resume pump, slaveId: " + slaveId);
}
log.info("Pump[{}] resumed", slaveId);
}
public void moveByBlock(CeramicPumpDriverSlaveId pumpId, Direction direction, int r)
{
final int targetPosition = r; // 目标位置圈数
int currentPosition = 0; // 当前位置圈数
int currentSpeed = 0; // 当前速度转速
if (runFlags.getOrDefault(pumpId, false)) {
log.warn("Pump {} is already running, skipping moveByBlock", pumpId);
return;
}
runFlags.put(pumpId, true);
try {
// 初始化
currentSpeed = getSpeed(pumpId);
this.reset(pumpId);
this.setDirection(pumpId, direction);
// 计算移动目标位置的时间 速度单位 rpm, 距离 r,
int expectedMs = (int) ((targetPosition - currentPosition) * 60.0 * 1000.0 / currentSpeed) ;
log.info("Pump {} moveByBlock, targetPosition: {}, currentPosition: {}, currentSpeed: {}, expectedMs: {}",
pumpId, targetPosition, currentPosition, currentSpeed, expectedMs);
this.moveBy(pumpId, targetPosition);
int timoutMs = (int)(expectedMs * 1.5); // 设置超时时间为预期时间的两倍
int pollCurrentPosMs = (int)(expectedMs * 0.9); // 轮询当前位置的时间为预期时间的90%后开始
long startTime = System.currentTimeMillis();
int elapsedTime = 0; // 已用时间
while (elapsedTime < timoutMs) {
if (!runFlags.getOrDefault(pumpId, false)) {
log.info("Pump {} stopped before reaching target position", pumpId);
return; // 如果在等待过程中被停止退出
}
elapsedTime = (int)(System.currentTimeMillis() - startTime);
if (elapsedTime >= pollCurrentPosMs) {
currentPosition = getCurrentPosition(pumpId);
if (currentPosition >= targetPosition) {
log.info("Pump {} reached target position: {}", pumpId, targetPosition);
break;
}
}
Thread.sleep(20); // 每100ms检查一次
}
}
catch (Exception e) {
log.error("Error initializing pump position: {}", e.getMessage());
throw new RuntimeException("Error initializing pump position", e);
}
finally {
runFlags.put(pumpId, false);
}
}
public void stopBlock(CeramicPumpDriverSlaveId pumpId) {
if (!runFlags.getOrDefault(pumpId, false)) {
log.warn("Pump {} is not running, cannot stop", pumpId);
return;
}
runFlags.put(pumpId, false);
try {
this.stop(pumpId);
} catch (Exception e) {
log.error("Error stopping pump {}: {}", pumpId, e.getMessage());
} finally {
runFlags.put(pumpId, false);
}
}
}

53
src/main/java/com/iflytop/colortitration/hardware/drivers/ColdTrapDriver.java

@ -1,53 +0,0 @@
package com.iflytop.colortitration.hardware.drivers;
import com.iflytop.colortitration.hardware.drivers.DODriver.OutputIOCtrlDriver;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import static com.iflytop.colortitration.hardware.type.IO.OutputIOMId.DO_COLD_TRAP_POWER;
/**
* 物理冷阱
*/
@Component
@RequiredArgsConstructor
public class ColdTrapDriver {
private final OutputIOCtrlDriver outputIOCtrlDriver_;
public void setTemperature(Double temperature) throws Exception {
}
public void openPower() throws Exception{
outputIOCtrlDriver_.setIOState(DO_COLD_TRAP_POWER, true);
}
public void closePower() throws Exception{
outputIOCtrlDriver_.setIOState(DO_COLD_TRAP_POWER, false);
}
public boolean openCircle() {
return false;
}
public boolean closeCircle() {
return false;
}
public boolean openHeart() {
return false;
}
public boolean closeHeart() {
return false;
}
public boolean openCool() {
return false;
}
public boolean closeCool() {
return false;
}
}

24
src/main/java/com/iflytop/colortitration/hardware/drivers/DODriver/FanDriver.java

@ -1,24 +0,0 @@
package com.iflytop.colortitration.hardware.drivers.DODriver;
import com.iflytop.colortitration.hardware.type.IO.OutputIOMId;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class FanDriver {
private final OutputIOCtrlDriver outputIOCtrlDriver_;
public void open(OutputIOMId outputIOMId) throws Exception
{
log.info("Opening FanD {}", outputIOMId.mid.getDescription());
outputIOCtrlDriver_.setIOState(outputIOMId, true);
}
public void close(OutputIOMId outputIOMId) throws Exception
{
log.info("Closing FanD {}", outputIOMId.mid.getDescription());
outputIOCtrlDriver_.setIOState(outputIOMId, false);
}
}

22
src/main/java/com/iflytop/colortitration/hardware/drivers/DODriver/VentilatorDriver.java

@ -1,22 +0,0 @@
package com.iflytop.colortitration.hardware.drivers.DODriver;
import com.iflytop.colortitration.hardware.type.IO.OutputIOMId;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class VentilatorDriver {
private final OutputIOCtrlDriver outputIOCtrlDriver_;
public void openPower(OutputIOMId outputIOMId) throws Exception
{
outputIOCtrlDriver_.setIOState(outputIOMId, true);
}
public void closePower(OutputIOMId outputIOMId) throws Exception
{
outputIOCtrlDriver_.setIOState(outputIOMId, false);
}
}

22
src/main/java/com/iflytop/colortitration/hardware/drivers/DODriver/WaterPumpDriver.java

@ -1,22 +0,0 @@
package com.iflytop.colortitration.hardware.drivers.DODriver;
import com.iflytop.colortitration.hardware.type.IO.OutputIOMId;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class WaterPumpDriver {
private final OutputIOCtrlDriver outputIOCtrlDriver_;
public void openPower(OutputIOMId outputIOMId) throws Exception
{
outputIOCtrlDriver_.setIOState(outputIOMId, true);
}
public void closePower(OutputIOMId outputIOMId) throws Exception
{
outputIOCtrlDriver_.setIOState(outputIOMId, false);
}
}

23
src/main/java/com/iflytop/colortitration/hardware/drivers/FillLightDriver.java

@ -1,23 +0,0 @@
package com.iflytop.colortitration.hardware.drivers;
import com.iflytop.colortitration.hardware.comm.can.A8kCanBusService;
import com.iflytop.colortitration.hardware.type.CmdId;
import com.iflytop.colortitration.hardware.type.MId;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class FillLightDriver {
private final A8kCanBusService canBus;
public void open(MId mId, Integer brightness) throws Exception {
// 模拟打开
canBus.callcmd(mId, CmdId.pwm_light_on, brightness);
}
public void close(MId mId) throws Exception {
canBus.callcmd(mId, CmdId.pwm_light_off);
}
}

122
src/main/java/com/iflytop/colortitration/hardware/drivers/HeaterRodDriver.java

@ -1,122 +0,0 @@
package com.iflytop.colortitration.hardware.drivers;
import cn.hutool.core.util.StrUtil;
import com.iflytop.colortitration.hardware.comm.can.A8kCanBusService;
import com.iflytop.colortitration.hardware.comm.modbus.ModbusMasterService;
import com.iflytop.colortitration.hardware.exception.HardwareException;
import com.iflytop.colortitration.hardware.type.A8kPacket;
import com.iflytop.colortitration.hardware.type.CmdId;
import com.iflytop.colortitration.hardware.type.driver.HeaterRodSlavedId;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Component
@RequiredArgsConstructor
public class HeaterRodDriver {
private final A8kCanBusService canBus;
private final ModbusMasterService modbusMaster;
private static final int SV_ADDRESS = 0x2000;
private static final int PV_ADDRESS = 0x2010;
private static final int CONTROL_REGISTER = 0x2106;
private static final int DP_ADDRESS = 0x2107;
private static final int DEVICE_ADDRESS_REGISTER = 0x2112;
private final Map<Integer, Integer> dpCache = new ConcurrentHashMap<>();
private static final int DEFAULT_DP = 1;
public void setDeviceAddress(HeaterRodSlavedId heaterRodId, int newAddress) throws Exception {
int slaveId = heaterRodId.getSlaveId();
if (!modbusMaster.writeRegister(slaveId, DEVICE_ADDRESS_REGISTER, newAddress)) {
throw new Exception("Failed to set device address for heater rod with ID: " + heaterRodId.name());
}
log.info("Device address for heater rod with ID: {} set to: {}", heaterRodId.name(), newAddress);
}
private int getDecimalPoint(int slaveId) throws Exception {
return dpCache.computeIfAbsent(slaveId, id -> {
try {
short[] response = modbusMaster.readHoldingRegisters(id, DP_ADDRESS, 1);
if (response != null && response.length > 0) {
return (int) response[0];
}
} catch (Exception e) {
log.warn("Failed to read DP for slave ID: {}, using default DP: {}", id, DEFAULT_DP);
}
return DEFAULT_DP;
});
}
public void openPower(HeaterRodSlavedId heaterRodId) throws Exception
{
int slaveId = heaterRodId.getSlaveId();
if (!modbusMaster.writeRegister(slaveId, CONTROL_REGISTER, 1)) { // 1 = Start
throw new Exception("Failed to start heater rod with ID: " + heaterRodId.name());
}
}
public void closePower(HeaterRodSlavedId heaterRodId) throws Exception
{
int slaveId = heaterRodId.getSlaveId();
if (!modbusMaster.writeRegister(slaveId, CONTROL_REGISTER, 2)) { // 2 = Stop
throw new Exception("Failed to stop heater rod with ID: " + heaterRodId.name());
}
log.info("{} stopped.", heaterRodId.name());
}
public void setTemperature(HeaterRodSlavedId heaterRodId, double temperature) throws Exception {
int slaveId = heaterRodId.getSlaveId();
int decimalPoint = getDecimalPoint(slaveId);
int scaledTemperature = (int) (temperature * Math.pow(10, decimalPoint));
if (!modbusMaster.writeRegister(slaveId, SV_ADDRESS, scaledTemperature)) {
throw new Exception("Failed to set temperature for heater rod with ID: " + heaterRodId.name());
}
log.info("{} started with temperature: {}", heaterRodId.name(), temperature);
}
public double getTemperature(HeaterRodSlavedId heaterRodId) throws Exception {
int slaveId = heaterRodId.getSlaveId();
int decimalPoint = getDecimalPoint(slaveId);
short[] response = modbusMaster.readHoldingRegisters(slaveId, PV_ADDRESS, 1);
if (response == null || response.length == 0) {
throw new Exception(StrUtil.format("Failed to read temperature {}", heaterRodId.name()));
}
double temperature = response[0] / Math.pow(10, decimalPoint);
log.info("{} GET temperature {}", heaterRodId.name(), temperature);
return temperature;
}
/**
* 获取电流
* @return
*/
public Integer getCurrent(HeaterRodSlavedId heaterRodId) throws HardwareException
{
A8kPacket packet = canBus.callcmd(heaterRodId.getMid(), CmdId.adc_read_adc, heaterRodId.getAdcCurrentIndex());
Integer current = packet.getContentI32(0);
return current;
}
// ==== ==== ==== ==== ==== ==== application ==== ==== ==== ==== ==== ====
public void open(HeaterRodSlavedId heaterRodId, double temperature) throws Exception {
this.openPower(heaterRodId);
this.setTemperature(heaterRodId, temperature);
}
public void close(HeaterRodSlavedId heaterRodId) throws Exception {
this.closePower(heaterRodId);
}
}

2
src/main/java/com/iflytop/colortitration/hardware/drivers/DIDriver/InputDetectDriver.java → src/main/java/com/iflytop/colortitration/hardware/drivers/InputDetectDriver.java

@ -1,4 +1,4 @@
package com.iflytop.colortitration.hardware.drivers.DIDriver;
package com.iflytop.colortitration.hardware.drivers;
import com.iflytop.colortitration.hardware.comm.can.A8kCanBusService;
import com.iflytop.colortitration.hardware.exception.HardwareException;

28
src/main/java/com/iflytop/colortitration/hardware/drivers/LeisaiServoDriver.java

@ -1,5 +1,6 @@
package com.iflytop.colortitration.hardware.drivers;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.iflytop.colortitration.hardware.comm.can.A8kCanBusService;
import com.iflytop.colortitration.hardware.constants.ActionOvertimeConstant;
import com.iflytop.colortitration.hardware.exception.HardwareException;
@ -8,6 +9,7 @@ import com.iflytop.colortitration.hardware.type.CmdId;
import com.iflytop.colortitration.hardware.type.Servo.LeisaiRegIndex;
import com.iflytop.colortitration.hardware.type.Servo.LeisaiServoMId;
import com.iflytop.colortitration.hardware.type.Servo.LeisaiServoSpeedLevel;
import com.iflytop.colortitration.hardware.utils.ZJsonHelper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@ -18,7 +20,6 @@ import org.springframework.stereotype.Component;
public class LeisaiServoDriver {
final private A8kCanBusService canBus;
private final ActionOvertimeConstant actionOvertimeConstant;
static public final Integer actionOvertime = 10000;
public void moduleStop(LeisaiServoMId id) throws HardwareException {
log.info("moduleStop called with id: {}", id);
@ -36,10 +37,10 @@ public class LeisaiServoDriver {
return packet.getContentI32(0);
}
public Boolean readIoState(LeisaiServoMId id, Integer io_index) throws HardwareException {
public Integer readIoState(LeisaiServoMId id, Integer io_index) throws HardwareException {
log.info("readIoState called with id: {}, io_index: {}", id, io_index);
A8kPacket packet = canBus.callcmd(id.mid, CmdId.leisai_servo_read_io_state, io_index);
return packet.getContentI32(0) != 0;
return packet.getContentI32(0);
}
public void moveTo(LeisaiServoMId id, LeisaiServoSpeedLevel speedLevel, Integer pos) throws HardwareException {
@ -62,6 +63,11 @@ public class LeisaiServoDriver {
canBus.callcmd(id.mid, CmdId.leisai_servo_move_to_zero);
}
public void setReg(LeisaiServoMId id, LeisaiRegIndex regindex, int val) throws HardwareException {
log.info("setReg called with id: {}, regindex: {}, val: {}", id, regindex, val);
canBus.moduleSetReg(id.mid, regindex.regIndex, val);
}
// ====== ===== ====== ===== ====== ===== Block ====== ===== ====== ===== ====== =====
public void moveToBlock(LeisaiServoMId id, LeisaiServoSpeedLevel speedLevel, Integer pos) throws HardwareException {
log.info("moveToBlock called with id: {}, speedLevel: {}, pos: {}", id, speedLevel, pos);
@ -85,14 +91,20 @@ public class LeisaiServoDriver {
canBus.waitForMod(id.mid, overtime);
}
public void setReg(LeisaiServoMId id, LeisaiRegIndex regindex, int val) throws HardwareException {
log.info("setReg called with id: {}, regindex: {}, val: {}", id, regindex, val);
canBus.moduleSetReg(id.mid, regindex.regIndex, val);
}
public Integer getReg(LeisaiServoMId id, LeisaiRegIndex regindex) throws HardwareException {
log.info("getReg called with id: {}, regindex: {}", id, regindex);
return canBus.moduleGetReg(id.mid, regindex.regIndex);
}
public Object getAllReg(LeisaiServoMId id) throws HardwareException {
log.info("getAllReg called with id: {}", id);
ObjectNode node = ZJsonHelper.createObjectNode();
for (LeisaiRegIndex regIndex : LeisaiRegIndex.values()) {
Integer regVal = getReg(id, regIndex);
log.info("read reg {} -> {}", regIndex, regVal);
node.put(regIndex.name(), getReg(id, regIndex));
}
return node;
}
}

64
src/main/java/com/iflytop/colortitration/hardware/drivers/LiquidDistributionArmDriver.java

@ -1,54 +1,34 @@
package com.iflytop.colortitration.hardware.drivers;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.iflytop.colortitration.hardware.comm.can.A8kCanBusService;
import com.iflytop.colortitration.hardware.constants.ActionOvertimeConstant;
import com.iflytop.colortitration.hardware.exception.HardwareException;
import com.iflytop.colortitration.hardware.type.CmdId;
import com.iflytop.colortitration.hardware.type.Servo.LiquidArmMId;
import com.iflytop.colortitration.hardware.type.Servo.LiquidArmRegIndex;
import com.iflytop.colortitration.hardware.utils.ZJsonHelper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 加液臂接口
*/
@Component
@Slf4j
@RequiredArgsConstructor
public class LiquidDistributionArmDriver {
private final ActionOvertimeConstant actionOvertimeConstant;
final private A8kCanBusService canBus;
/**
* 使能
* @param id
* @param enable
* @throws HardwareException
*/
private final ActionOvertimeConstant actionOvertimeConstant;
public void liquidDistributionArmEnable(LiquidArmMId id, int enable) throws HardwareException {
log.info("liquidDistributionArmEnable called with id: {}, enable: {}", id, enable);
canBus.callcmd(id.mid, CmdId.liquid_distribution_arm_enable, enable);
}
/**
* 移动到指定试管架
* @param id
* @param index
* @throws HardwareException
*/
public void liquidDistributionArmMoveTo(LiquidArmMId id, int index) throws HardwareException {
log.info("liquidDistributionArmMoveTo called with id: {}, index: {}", id, index);
canBus.callcmd(id.mid, CmdId.liquid_distribution_arm_move_to, index);
}
public void liquidDistributionArmMoveToBlock(LiquidArmMId id, int index) throws HardwareException {
liquidDistributionArmMoveTo(id,index);
waitForMod(id, actionOvertimeConstant.get(id.mid, CmdId.liquid_distribution_arm_move_to));
}
public void waitForMod(LiquidArmMId id, Integer overtime) throws HardwareException {
canBus.waitForMod(id.mid, overtime);
}
public int liquidDistributionReadPos(LiquidArmMId id) throws HardwareException {
log.info("liquidDistributionReadPos called with id: {}", id);
var packet = canBus.callcmd(id.mid, CmdId.liquid_distribution_arm_read_pos);
@ -65,16 +45,22 @@ public class LiquidDistributionArmDriver {
canBus.callcmd(id.mid, CmdId.liquid_distribution_arm_set_cur_pos_as_mid_pos);
}
/**
* 停止
* @param id
* @throws HardwareException
*/
public void moduleStop(LiquidArmMId id) throws HardwareException {
log.info("moduleStop called with id: {}", id);
canBus.moduleStop(id.mid);
}
// ====== ===== ====== ===== ====== ===== Block ====== ===== ====== ===== ====== =====
public void liquidDistributionArmMoveToBlock(LiquidArmMId id, int index) throws HardwareException {
liquidDistributionArmMoveTo(id, index);
waitForMod(id, actionOvertimeConstant.get(id.mid, CmdId.liquid_distribution_arm_move_to));
}
public void waitForMod(LiquidArmMId id, Integer overtime) throws HardwareException {
canBus.waitForMod(id.mid, overtime);
}
public void setReg(LiquidArmMId id, LiquidArmRegIndex regindex, int val) throws HardwareException {
log.info("setReg called with id: {}, regindex: {}, val: {}", id, regindex, val);
canBus.moduleSetReg(id.mid, regindex.regIndex, val);
@ -85,14 +71,14 @@ public class LiquidDistributionArmDriver {
return canBus.moduleGetReg(id.mid, regindex.regIndex);
}
// public Object getAllReg(LiquidArmMId id) throws HardwareException {
// log.info("getAllReg called with id: {}", id);
// ObjectNode node = ZJsonHelper.createObjectNode();
// for (LiquidArmRegIndex regIndex : LiquidArmRegIndex.values()) {
// Integer regVal = getReg(id, regIndex);
// log.info("read reg {} -> {}", regIndex, regVal);
// node.put(regIndex.name(), getReg(id, regIndex));
// }
// return node;
// }
public Object getAllReg(LiquidArmMId id) throws HardwareException {
log.info("getAllReg called with id: {}", id);
ObjectNode node = ZJsonHelper.createObjectNode();
for (LiquidArmRegIndex regIndex : LiquidArmRegIndex.values()) {
Integer regVal = getReg(id, regIndex);
log.info("read reg {} -> {}", regIndex, regVal);
node.put(regIndex.name(), getReg(id, regIndex));
}
return node;
}
}

127
src/main/java/com/iflytop/colortitration/hardware/drivers/MiniServoDriver/MiniServoDriver.java → src/main/java/com/iflytop/colortitration/hardware/drivers/MiniServoDriver.java

@ -1,14 +1,17 @@
package com.iflytop.colortitration.hardware.drivers.MiniServoDriver;
package com.iflytop.colortitration.hardware.drivers;
import com.iflytop.colortitration.hardware.comm.can.A8kCanBusService;
import com.iflytop.colortitration.hardware.constants.MiniServoConstant;
import com.iflytop.colortitration.hardware.exception.HardwareException;
import com.iflytop.colortitration.hardware.type.A8kPacket;
import com.iflytop.colortitration.hardware.type.CmdId;
import com.iflytop.colortitration.hardware.type.MId;
import com.iflytop.colortitration.hardware.type.RegIndex;
import com.iflytop.colortitration.hardware.type.Servo.MiniServoMId;
import com.iflytop.colortitration.hardware.type.Servo.MiniServoRegIndex;
import com.iflytop.colortitration.hardware.type.error.A8kEcode;
import com.iflytop.colortitration.hardware.type.error.AEHardwareError;
import com.iflytop.colortitration.hardware.utils.OS;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@ -19,6 +22,8 @@ import org.springframework.stereotype.Component;
@RequiredArgsConstructor
public class MiniServoDriver {
final private A8kCanBusService canBus;
static public final Integer actionOvertime = 10000;
public void moduleStop(MiniServoMId id) throws HardwareException {
canBus.moduleStop(id.mid);
@ -26,7 +31,7 @@ public class MiniServoDriver {
public void miniServoEnable(MiniServoMId id, int enable) throws HardwareException {
log.debug("{} miniServoEnable {}", id.mid, enable);
canBus.callcmd(id.mid, CmdId.mini_servo_enable, enable);
callcmd(id.mid, CmdId.mini_servo_enable, enable);
}
public void miniServoForceEnable(MiniServoMId id, int enable) {
@ -47,66 +52,73 @@ public class MiniServoDriver {
}
public int miniServoReadPos(MiniServoMId id) throws HardwareException {
var packet = canBus.callcmd(id.mid, CmdId.mini_servo_read_pos);
var packet = callcmd(id.mid, CmdId.mini_servo_read_pos);
return packet.getContentI32(0);
}
public void miniServoMoveToZeroBlock(MiniServoMId id) throws HardwareException {
log.debug("{} miniServoMoveToZeroBlock", id.mid);
miniServoMoveToBlock(id, MiniServoConstant.getZeroPos(id));
private void miniServoMoveTo(MiniServoMId id, int pos) throws HardwareException {
callcmd(id.mid, CmdId.mini_servo_move_to, pos);
}
public void miniServoMoveToZero(MiniServoMId id) throws HardwareException {
log.debug("{} miniServoMoveToZero", id.mid);
miniServoMoveTo(id, MiniServoConstant.getZeroPos(id));
public void miniServoMoveToBlock(MiniServoMId id, int pos) throws HardwareException {
log.debug("{} miniServoMoveTo {}", id.mid, pos);
int retry = 0;
do {
try {
miniServoMoveTo(id, pos);
canBus.waitForMod(id.mid, actionOvertime);
return;
} catch (HardwareException e) {
if (e.getError().code.equals(A8kEcode.LOW_ERROR_SUBDEVICE_OVERTIME)) {
log.warn("CALL miniServoMoveToBlock {} FAIL, SUB DEVICE OVERTIME", id);
if (retry > 3) {
throw e;
}
} else {
throw e;
}
}
OS.hsleep(1000);
retry++;
} while (true);
}
public void miniServoRotate(MiniServoMId id, int direction) throws HardwareException {
log.debug("{} miniServoRotate {}", id.mid, direction);
callcmd(id.mid, CmdId.mini_servo_rotate, direction);
}
public void miniServoActiveCfg(MiniServoMId id) throws HardwareException {
canBus.callcmd(id.mid, CmdId.mini_servo_active_cfg);
callcmd(id.mid, CmdId.mini_servo_active_cfg);
}
public void miniServoStop(MiniServoMId id) throws HardwareException {
canBus.callcmd(id.mid, CmdId.mini_servo_stop);
callcmd(id.mid, CmdId.mini_servo_stop);
}
public void miniServoSetMidPoint(MiniServoMId id) throws HardwareException {
canBus.callcmd(id.mid, CmdId.mini_servo_set_mid_point);
callcmd(id.mid, CmdId.mini_servo_set_mid_point);
}
public int miniServoReadIoState(MiniServoMId id) throws HardwareException {
var packet = canBus.callcmd(id.mid, CmdId.mini_servo_read_io_state);
var packet = callcmd(id.mid, CmdId.mini_servo_read_io_state);
return packet.getContentI32(0);
}
public void miniServoMoveTo(MiniServoMId id, int pos) throws HardwareException {
canBus.callcmd(id.mid, CmdId.mini_servo_move_to, pos);
}
public void miniServoMoveToBlock(MiniServoMId id, int pos) throws HardwareException {
log.debug("{} miniServoMoveTo {}", id.mid, pos);
miniServoMoveTo(id, pos);
canBus.waitForMod(id.mid, MiniServoConstant.actionOvertime);
}
public void miniServoRotate(MiniServoMId id, int direction) throws HardwareException {
log.debug("{} miniServoRotate {}", id.mid, direction);
canBus.callcmd(id.mid, CmdId.mini_servo_rotate, direction);
}
public void miniServoRotateBlock(MiniServoMId id, int direction) throws HardwareException {
miniServoRotate(id, direction);
canBus.waitForMod(id.mid, MiniServoConstant.actionOvertime);
canBus.waitForMod(id.mid, actionOvertime);
}
public void miniServoRotateWithTorque(MiniServoMId id, int torque) throws HardwareException {
log.debug("{} miniServoRotateWithTorque {}", id.mid, torque);
canBus.callcmd(id.mid, CmdId.mini_servo_rotate_with_torque, torque);
callcmd(id.mid, CmdId.mini_servo_rotate_with_torque, torque);
}
public void waitForMod(MiniServoMId mid) throws HardwareException {
canBus.waitForMod(mid.mid, MiniServoConstant.actionOvertime);
canBus.waitForMod(mid.mid, actionOvertime);
}
public void waitForMod(MiniServoMId... mid) throws HardwareException {
@ -119,13 +131,10 @@ public class MiniServoDriver {
// kmini_servo_set_cur_pos
private void miniServoSetCurPos(MiniServoMId id, Integer pos) throws HardwareException {
log.debug("{} miniServoSetCurPos {}", id.mid, pos);
canBus.callcmd2(id.mid, CmdId.mini_servo_set_cur_pos, 5000, pos);
callcmd2(id.mid, CmdId.mini_servo_set_cur_pos, 5000, pos);
}
public Integer miniServoSetRefPos(MiniServoMId id) throws HardwareException {
miniServoSetCurPos(id, MiniServoConstant.getRefPos(id));
return MiniServoConstant.getRefPos(id);
}
public void setReg(MiniServoMId id, MiniServoRegIndex regindex, int val) throws HardwareException {
log.debug("{} setReg {} {}", id.mid, regindex, val);
@ -159,4 +168,46 @@ public class MiniServoDriver {
} while (true);
}
private A8kPacket callcmd(MId id, CmdId cmdId, Integer... args) throws HardwareException {
int retry = 0;
do {
try {
return canBus.callcmd(id, cmdId, args);
} catch (HardwareException e) {
if (e.getError().code.equals(A8kEcode.LOW_ERROR_SUBDEVICE_OVERTIME)) {
log.warn("CALL CMD {} FAIL, SUB DEVICE OVERTIME", cmdId);
if (retry > 3) {
throw e;
}
} else {
throw e;
}
}
OS.hsleep(1000);
retry++;
} while (true);
}
private A8kPacket callcmd2(MId id, CmdId cmdId, Integer timeout, Integer... args) throws HardwareException {
int retry = 0;
do {
try {
return canBus.callcmd2(id, cmdId, timeout, args);
} catch (HardwareException e) {
if (e.getError().code.equals(A8kEcode.LOW_ERROR_SUBDEVICE_OVERTIME)) {
log.warn("CALL CMD2 {} FAIL, SUB DEVICE OVERTIME", cmdId);
if (retry > 3) {
throw e;
}
} else {
throw e;
}
}
OS.hsleep(1000);
retry++;
} while (true);
}
}

110
src/main/java/com/iflytop/colortitration/hardware/drivers/MiniServoDriver/ClawDriver.java

@ -1,110 +0,0 @@
package com.iflytop.colortitration.hardware.drivers.MiniServoDriver;
import com.iflytop.colortitration.hardware.exception.HardwareException;
import com.iflytop.colortitration.hardware.type.Servo.MiniServoMId;
import com.iflytop.colortitration.hardware.utils.Math.ServoPositionConverter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.security.InvalidParameterException;
@Slf4j
@Component
@RequiredArgsConstructor
public class ClawDriver {
private static final double MIN_DISTANCE = 34.0;
private static final double MAX_DISTANCE = 54.0;
private static double MIN_SERVO_POSITION = 2048;
private static double MAX_SERVO_POSITION = 3000;
private final MiniServoDriver miniServoDriver;
private double speed_ = 10.0; // mm/s
// ==== ==== ==== ==== ==== ==== convert ==== ==== ==== ==== ==== ====
/**
* 将距离转换为舵机位置
* @param distance 距离值范围在 MIN_DISTANCE MAX_DISTANCE 之间
* @return 对应的舵机位置范围在 MIN_SERVO_POSITION MAX_SERVO_POSITION 之间
*/
public static double distanceToServoPosition(double distance) {
if (distance < MIN_DISTANCE) {
distance = MIN_DISTANCE;
} else if (distance > MAX_DISTANCE) {
distance = MAX_DISTANCE;
}
return MIN_SERVO_POSITION + (distance - MIN_DISTANCE) * (MAX_SERVO_POSITION - MIN_SERVO_POSITION) / (MAX_DISTANCE - MIN_DISTANCE);
}
/**
* 将舵机位置转换为距离
* @param servoPosition 舵机位置值范围在 MIN_SERVO_POSITION MAX_SERVO_POSITION 之间
* @return 对应的距离范围在 MIN_DISTANCE MAX_DISTANCE 之间
*/
public static double servoPositionToDistance(double servoPosition) {
if (servoPosition < MIN_SERVO_POSITION) {
servoPosition = MIN_SERVO_POSITION;
} else if (servoPosition > MAX_SERVO_POSITION) {
servoPosition = MAX_SERVO_POSITION;
}
return MIN_DISTANCE + (servoPosition - MIN_SERVO_POSITION) * (MAX_DISTANCE - MIN_DISTANCE) / (MAX_SERVO_POSITION - MIN_SERVO_POSITION);
}
private int toServoPosition(double position) {
int servoPosition = 0;
servoPosition = (int)distanceToServoPosition(position);
servoPosition = (int) ServoPositionConverter.convert4096To3600(servoPosition);
return servoPosition;
}
private int toServoSpeed(double speed) {
int servoSpeed = 0;
servoSpeed = (int)speed;
return servoSpeed;
}
// ==== ==== ==== ==== ==== ==== Get ==== ==== ==== ==== ==== ====
private double getSpeed(MiniServoMId servoMid)
{
// TODO: 从数据库中获取门的速度
return speed_;
}
// ==== ==== ==== ==== ==== ==== Set ==== ==== ==== ==== ==== ====
public void setSpeed(MiniServoMId servoMid, double speed) {
log.info("[ {} ] Setting speed to {}", servoMid.mid.getDescription(), speed);
// 检查速度是否合法
speed_ = speed;
// TODO: 写入数据库
}
// ==== ==== ==== ==== ==== ==== Ctrl ==== ==== ==== ==== ==== ====
public void moveToHome(MiniServoMId servoMid) throws HardwareException
{
log.info("[ {} ] moveToHome", servoMid.mid.getDescription());
this.moveTo(servoMid, MIN_DISTANCE);
}
public void moveTo(MiniServoMId servoMid, double position) throws HardwareException
{
// 检查位置是否合法
if (position < MIN_DISTANCE || position > MAX_DISTANCE) {
log.error("[ {} ] Position is out of range", servoMid.mid.getDescription());
throw new InvalidParameterException("Position is out of range");
}
miniServoDriver.miniServoEnable(servoMid, 1);
int servoPosition = toServoPosition(position);
log.info("[ {} ] moveTo {}, servo position {} ...", servoMid, position, servoPosition);
miniServoDriver.miniServoMoveToBlock(servoMid, servoPosition);
log.info("[ {} ] moveTo {}, servo position {} end", servoMid, position, servoPosition);
}
public void stop(MiniServoMId servoMid) throws HardwareException {
log.info("[ {} ] stop", servoMid.mid.getDescription());
miniServoDriver.miniServoStop(servoMid);
}
}

180
src/main/java/com/iflytop/colortitration/hardware/drivers/MiniServoDriver/DualRobotDriver.java

@ -1,180 +0,0 @@
package com.iflytop.colortitration.hardware.drivers.MiniServoDriver;
import com.iflytop.colortitration.hardware.exception.HardwareException;
import com.iflytop.colortitration.hardware.type.Servo.MiniServoMId;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.awt.geom.Point2D;
@Slf4j
@Component
@RequiredArgsConstructor
public class DualRobotDriver {
public enum Joint {
JOINT_1,
JOINT_2
}
// 舵机角度范围常量
public static final double MIN_ANGLE_DEG = -180.0;
public static final double MAX_ANGLE_DEG = 180.0;
// 舵机位置值范围常量
public static final int MIN_SERVO_POSITION = 0;
public static final int MAX_SERVO_POSITION = 3600;
private final MiniServoDriver miniServoDriver;
private double speed_ = 10.0; // mm/s
// ==== ==== ==== ==== ==== ==== convert ==== ==== ==== ==== ==== ====
/**
* 将舵机角度-180 180 转换为位置值0 - 4096
* @param angle 舵机角度范围在 -180 180 度之间
* @return 对应的位置值范围在 0 4096 之间
* @throws IllegalArgumentException 如果输入角度超出范围
*/
public static int angleToServoPosition(double angle) {
if (angle < MIN_ANGLE_DEG || angle > MAX_ANGLE_DEG) {
throw new IllegalArgumentException("角度必须在 " + MIN_ANGLE_DEG + " 到 " + MAX_ANGLE_DEG + " 度之间");
}
// 线性映射公式position = minPos + (angle - minAngle) * (maxPos - minPos) / (maxAngle - minAngle)
return (int) Math.round(
MIN_SERVO_POSITION +
(angle - MIN_ANGLE_DEG) *
(MAX_SERVO_POSITION - MIN_SERVO_POSITION) /
(MAX_ANGLE_DEG - MIN_ANGLE_DEG)
);
}
/**
* 将位置值0 - 4096转换为舵机角度-180 180
* @param servoPosition 设置值范围在 0 4096 之间
* @return 对应的舵机角度范围在 -180 180 度之间
* @throws IllegalArgumentException 如果输入位置值超出范围
*/
public static double servoPositionToAngle(int servoPosition) {
if (servoPosition < MIN_SERVO_POSITION || servoPosition > MAX_SERVO_POSITION) {
throw new IllegalArgumentException("位置值必须在 " + MIN_SERVO_POSITION + " 到 " + MAX_SERVO_POSITION + " 之间");
}
// 线性映射公式angle = minAngle + (position - minPos) * (maxAngle - minAngle) / (maxPos - minPos)
return MIN_ANGLE_DEG +
(servoPosition - MIN_SERVO_POSITION) *
(MAX_ANGLE_DEG - MIN_ANGLE_DEG) /
(MAX_SERVO_POSITION - MIN_SERVO_POSITION);
}
private int toServoPosition(double angle) {
int servoPosition = angleToServoPosition(angle);
return servoPosition;
}
private double toAngle(Integer position)
{
double angle = servoPositionToAngle(position);
return angle;
}
private Point2D toServoPosition(Point2D point) {
Point2D servoPosition = new Point2D.Double(0, 0);
servoPosition.setLocation(point.getX(), point.getY());
return servoPosition;
}
private int toServoSpeed(double speed) {
int servoSpeed = 0;
servoSpeed = (int)speed;
return servoSpeed;
}
// ==== ==== ==== ==== ==== ==== Get ==== ==== ==== ==== ==== ====
private double getSpeed(MiniServoMId servoMid)
{
// TODO: 从数据库中获取门的速度
return speed_;
}
// ==== ==== ==== ==== ==== ==== Set ==== ==== ==== ==== ==== ====
public void setSpeed(MiniServoMId servoMid, double speed) {
// 检查速度是否合法
speed_ = speed;
// TODO: 写入数据库
}
public MiniServoMId getMiniServoMId(Joint joint) {
switch (joint) {
case JOINT_1:
return MiniServoMId.DUAL_ROBOT_AXIS1_MID;
case JOINT_2:
return MiniServoMId.DUAL_ROBOT_AXIS2_MID;
default:
return null;
}
}
// ==== ==== ==== ==== ==== ==== Ctrl ==== ==== ==== ==== ==== ====
public void servoEnable(MiniServoMId servoMId, boolean enable) throws HardwareException
{
miniServoDriver.miniServoEnable(servoMId, enable ? 1 : 0);
}
public void moveToHome(MiniServoMId servoMid) throws HardwareException
{
log.info("Servo {} Move To Home", servoMid.mid.getDescription());
this.servoEnable(servoMid, true);
}
public void moveJointTo(MiniServoMId servoMid, double position) throws HardwareException
{
// 检查位置是否合法
Integer servoPosition = toServoPosition(position);
log.info("Servo {} Move To position {}, Servo Position {}", servoMid.mid.getDescription(), position, servoPosition);
this.servoEnable(servoMid, true);
miniServoDriver.miniServoMoveToBlock(servoMid, servoPosition);
}
public void stop(MiniServoMId servoMid) throws HardwareException {
log.info("Servo {} Stop", servoMid.mid.getDescription());
miniServoDriver.miniServoStop(servoMid);
}
// ==== ==== ==== ==== ==== ==== Application ==== ==== ==== ==== ==== ====
public void setSpeed(Joint joint, double speed) throws HardwareException {
MiniServoMId servoMId = getMiniServoMId(joint);
setSpeed(servoMId, speed);
log.info("Set speed for {} to {}", joint, speed);
}
public void moveToPoint(double pointX, double pointY) throws HardwareException {
// Point2D point = getServoPosition(new Point2D.Double(pointX, pointY));
//
// miniServoDriver.miniServoMoveToBlock(MiniServoMId.DUAL_ROBOT_AXIS1_MID, (int)point.getX());
// miniServoDriver.miniServoMoveToBlock(MiniServoMId.DUAL_ROBOT_AXIS2_MID, (int)point.getY());
}
public void moveToHome(Joint joint) throws HardwareException {
MiniServoMId servoMId = getMiniServoMId(joint);
log.info("Servo {} Move To Home", servoMId.mid.getDescription());
moveToHome(servoMId);
}
public void moveJointTo(Joint joint, double position) throws HardwareException {
MiniServoMId servoMId = getMiniServoMId(joint);
log.info("Servo {} Move To position {}", servoMId.mid.getDescription(), position);
moveJointTo(servoMId, position);
}
public void stop(Joint joint) throws HardwareException {
MiniServoMId servoMId = getMiniServoMId(joint);
log.info("Servo {} Stop", servoMId.mid.getDescription());
stop(servoMId);
}
}

6
src/main/java/com/iflytop/colortitration/hardware/drivers/ModuleEnableCtrlDriver.java

@ -1,8 +1,6 @@
package com.iflytop.colortitration.hardware.drivers;
import com.iflytop.colortitration.hardware.comm.can.A8kCanBusService;
import com.iflytop.colortitration.hardware.drivers.MiniServoDriver.MiniServoDriver;
import com.iflytop.colortitration.hardware.drivers.StepMotorDriver.StepMotorCtrlDriver;
import com.iflytop.colortitration.hardware.exception.HardwareException;
import com.iflytop.colortitration.hardware.type.Servo.MiniServoMId;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorMId;
@ -16,7 +14,7 @@ import org.springframework.stereotype.Component;
public class ModuleEnableCtrlDriver {
private final StepMotorCtrlDriver stepMotorCtrlDriver;
private final MiniServoDriver miniServoDriver;
private final MiniServoDriver miniServoDriver;
private final A8kCanBusService canBus;
public void forceDisableAllMotor() {
@ -36,6 +34,8 @@ public class ModuleEnableCtrlDriver {
log.info("disableMiniServo: {} failed, {}", miniServoMId, e.getMessage());
}
}
}
public void disableAllModule() throws HardwareException {

41
src/main/java/com/iflytop/colortitration/hardware/drivers/StepMotorDriver/DoorDriver.java → src/main/java/com/iflytop/colortitration/hardware/drivers/MotorWrapperDriver.java

@ -1,7 +1,8 @@
package com.iflytop.colortitration.hardware.drivers.StepMotorDriver;
package com.iflytop.colortitration.hardware.drivers;
import com.iflytop.colortitration.hardware.config.StepMotorConfig;
import com.iflytop.colortitration.hardware.exception.HardwareException;
import com.iflytop.colortitration.hardware.type.StepMotor.MotorDirect;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorMId;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorRegIndex;
import com.iflytop.colortitration.hardware.utils.Math.StepMotorConverter;
@ -14,7 +15,7 @@ import java.security.InvalidParameterException;
@Slf4j
@Component
@RequiredArgsConstructor
public class DoorDriver{
public class MotorWrapperDriver {
private final StepMotorConfig config_;
private final StepMotorCtrlDriver stepMotorCtrlDriver_;
@ -29,23 +30,37 @@ public class DoorDriver{
public void setSpeed(StepMotorMId stepMotorMId, double speed) throws HardwareException {
// 检查速度是否合法
// 设置速度到单片机
int motorSpeed = StepMotorConverter.toMotorSpeed(Math.abs(speed), config_.getLead(stepMotorMId));
int motorSpeed = (int) Math.abs(speed); // 转换速度为整数
stepMotorCtrlDriver_.setReg(stepMotorMId, StepMotorRegIndex.kreg_step_motor_default_velocity, motorSpeed);
}
// ==== ==== ==== ==== ==== ==== Ctrl ==== ==== ==== ==== ==== ====
public void motorEnable(StepMotorMId stepMotorMId, Boolean enable) throws Exception {
public void motorEnable(StepMotorMId stepMotorMId, Boolean enable) throws HardwareException {
Integer i_enable = enable ? 1 : 0;
stepMotorCtrlDriver_.stepMotorEnable(stepMotorMId, i_enable);
}
public void moveToHome(StepMotorMId stepMotorMId) throws Exception {
public void openClamp(StepMotorMId stepMotorMId) throws HardwareException
{
log.info("Motor {} Open Clamp", stepMotorMId.mid.getDescription());
motorEnable(stepMotorMId, true);
stepMotorCtrlDriver_.stepMotorOpenClamp(stepMotorMId);
}
public void closeClamp(StepMotorMId stepMotorMId) throws HardwareException
{
log.info("Motor {} Close Clamp", stepMotorMId.mid.getDescription());
motorEnable(stepMotorMId, true);
stepMotorCtrlDriver_.stepMotorCloseClamp(stepMotorMId);
}
public void moveToHome(StepMotorMId stepMotorMId) throws HardwareException {
log.info("Motor {} Move To Home", stepMotorMId.mid.getDescription());
motorEnable(stepMotorMId, true);
stepMotorCtrlDriver_.stepMotorEasyMoveToZeroBlock(stepMotorMId);
}
public void moveTo(StepMotorMId stepMotorMId, double position) throws Exception {
public void moveTo(StepMotorMId stepMotorMId, double position) throws HardwareException {
// 检查位置是否合法
if (Math.abs(position) > Math.abs(config_.getMaxLimit(stepMotorMId))) {
log.error("Motor {} Move To position out of range, position {}, limit {}", stepMotorMId.mid.getDescription(), position, config_.getMaxLimit(stepMotorMId));
@ -58,7 +73,7 @@ public class DoorDriver{
stepMotorCtrlDriver_.stepMotorEasyMoveToBlock(stepMotorMId, motorPosition);
}
public void moveBy(StepMotorMId stepMotorMId, double distance) throws Exception {
public void moveBy(StepMotorMId stepMotorMId, double distance) throws HardwareException {
// 检查位置是否合法
if (Math.abs(distance) > Math.abs(config_.getMaxLimit(stepMotorMId))) {
log.error("Motor {} Move By distance out of range, distance {}, limit {}", stepMotorMId.mid.getDescription(), distance, config_.getMaxLimit(stepMotorMId));
@ -71,14 +86,20 @@ public class DoorDriver{
stepMotorCtrlDriver_.stepMotorEasyMoveByBlock(stepMotorMId, motorPosition);
}
public void stop(StepMotorMId stepMotorMId) throws Exception {
public void rotate(StepMotorMId stepMotorMId, MotorDirect direct) throws Exception
{
motorEnable(stepMotorMId, true);
stepMotorCtrlDriver_.stepMotorEasyRotate(stepMotorMId, direct.getValue());
}
public void stop(StepMotorMId stepMotorMId) throws HardwareException {
log.info("Motor {} Stop", stepMotorMId.mid.getDescription());
stepMotorCtrlDriver_.stepMotorStop(stepMotorMId);
motorEnable(stepMotorMId, true);
}
public void moveToEnd(StepMotorMId stepMotorMId) throws Exception {
public void moveToEnd(StepMotorMId stepMotorMId) throws HardwareException {
log.info("Motor {} Move To End", stepMotorMId.mid.getDescription());
stepMotorCtrlDriver_.stepMotorEasyMoveToEndPointBlock(stepMotorMId);
stepMotorCtrlDriver_.stepMotorEasyMoveToEndPoint(stepMotorMId);
}
}

18
src/main/java/com/iflytop/colortitration/hardware/drivers/DODriver/OutputIOCtrlDriver.java → src/main/java/com/iflytop/colortitration/hardware/drivers/OutputIOCtrlDriver.java

@ -1,4 +1,4 @@
package com.iflytop.colortitration.hardware.drivers.DODriver;
package com.iflytop.colortitration.hardware.drivers;
import com.iflytop.colortitration.hardware.comm.can.A8kCanBusService;
@ -11,20 +11,26 @@ import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class OutputIOCtrlDriver {
private final A8kCanBusService canBus;
public void setIOState(OutputIOMId IOOutput, Boolean state) throws HardwareException {
canBus.callcmd(IOOutput.mid, CmdId.write_out_io, IOOutput.ioIndex, state ? 1 : 0);
}
public void open(OutputIOMId IOOutput) throws HardwareException
{
public boolean getIOState(OutputIOMId IOOutput) throws HardwareException {
boolean isOpen = canBus.callcmd(IOOutput.mid, CmdId.read_out_io, IOOutput.ioIndex).getContentI32(0) != 0;
if(IOOutput.mirror)
{
isOpen = !isOpen;
}
return isOpen;
}
public void open(OutputIOMId IOOutput) throws HardwareException {
this.setIOState(IOOutput, true);
}
public void close(OutputIOMId IOOutput) throws HardwareException
{
public void close(OutputIOMId IOOutput) throws HardwareException {
this.setIOState(IOOutput, false);
}
}

43
src/main/java/com/iflytop/colortitration/hardware/drivers/StepMotorDriver/StepMotorCtrlDriver.java → src/main/java/com/iflytop/colortitration/hardware/drivers/StepMotorCtrlDriver.java

@ -1,21 +1,21 @@
package com.iflytop.colortitration.hardware.drivers.StepMotorDriver;
package com.iflytop.colortitration.hardware.drivers;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.iflytop.colortitration.hardware.comm.can.A8kCanBusService;
import com.iflytop.colortitration.hardware.constants.ActionOvertimeConstant;
import com.iflytop.colortitration.hardware.exception.HardwareException;
import com.iflytop.colortitration.hardware.type.A8kPacket;
import com.iflytop.colortitration.hardware.type.CmdId;
import com.iflytop.colortitration.hardware.type.ModuleStatus;
import com.iflytop.colortitration.hardware.type.RegIndex;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorMId;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorRegIndex;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorSpeedLevel;
import com.iflytop.colortitration.hardware.utils.ZJsonHelper;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
@RequiredArgsConstructor
public class StepMotorCtrlDriver {
@ -53,6 +53,14 @@ public class StepMotorCtrlDriver {
canBus.callcmd(mid.mid, CmdId.step_motor_enable, enable);
}
public void stepMotorOpenClamp(StepMotorMId id) throws HardwareException {
canBus.callcmd(id.mid, CmdId.step_motor_set_clamp, 1);
}
public void stepMotorCloseClamp(StepMotorMId id) throws HardwareException {
canBus.callcmd(id.mid, CmdId.step_motor_set_clamp, 0);
}
public Integer stepMotorReadPos(StepMotorMId id) throws HardwareException {
A8kPacket packet = canBus.callcmd(id.mid, CmdId.step_motor_read_pos);
return packet.getContentI32(0);
@ -94,6 +102,7 @@ public class StepMotorCtrlDriver {
stepMotorEasyMoveToZeroBlock(id);
Integer nowpos = stepMotorReadPos(id);
Integer measurepos = -canBus.moduleGetReg(id.mid, RegIndex.kreg_step_motor_dpos) + nowpos;
stepMotorEnable(id, 0);
return measurepos;
}
@ -106,6 +115,12 @@ public class StepMotorCtrlDriver {
canBus.callcmd(id.mid, CmdId.step_motor_stop, 0);
}
// 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"), //
public void moveByBlock(StepMotorMId id, Integer dpos, StepMotorSpeedLevel speedLevel) throws HardwareException {
canBus.callcmd(id.mid, CmdId.step_motor_move_by, dpos, speedLevel.ordinal());
waitForMod(id, actionOvertimeConstant.get(id, CmdId.step_motor_move_by));
@ -161,23 +176,17 @@ public class StepMotorCtrlDriver {
canBus.callcmd(id.mid, CmdId.module_reset_reg);
}
// public Object getAllReg(StepMotorMId id) throws HardwareException {
// ObjectNode node = ZJsonHelper.createObjectNode();
// for (StepMotorRegIndex regIndex : StepMotorRegIndex.values()) {
// Integer regVal = getReg(id, regIndex);
// logger.debug("read reg {} -> {}", regIndex, regVal);
// node.put(regIndex.name(), getReg(id, regIndex));
// }
// return node;
// }
public ModuleStatus readStatus(StepMotorMId id) throws HardwareException {
return canBus.moduleGetStatus(id.mid);
}
public Map<String, Integer> getAllReg(StepMotorMId id) throws HardwareException {
Map<String, Integer> map = new HashMap<String, Integer>();
public Object getAllReg(StepMotorMId id) throws HardwareException {
ObjectNode node = ZJsonHelper.createObjectNode();
for (StepMotorRegIndex regIndex : StepMotorRegIndex.values()) {
Integer regVal = getReg(id, regIndex);
logger.debug("read reg {} -> {}", regIndex, regVal);
map.put(regIndex.name(), regVal);
node.put(regIndex.name(), getReg(id, regIndex));
}
return map;
return node;
}
}

101
src/main/java/com/iflytop/colortitration/hardware/drivers/StepMotorDriver/AcidPumpDriver.java

@ -1,101 +0,0 @@
package com.iflytop.colortitration.hardware.drivers.StepMotorDriver;
import com.iflytop.colortitration.hardware.config.StepMotorConfig;
import com.iflytop.colortitration.hardware.exception.HardwareException;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorDirect;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorMId;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorRegIndex;
import com.iflytop.colortitration.hardware.utils.Math.StepMotorConverter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.security.InvalidParameterException;
@Slf4j
@Component
@RequiredArgsConstructor
public class AcidPumpDriver {
private final StepMotorConfig config_;
private final StepMotorCtrlDriver stepMotorCtrlDriver_;
// ==== ==== ==== ==== ==== ==== Get ==== ==== ==== ==== ==== ====
private double getSpeed(StepMotorMId stepMotorMId)
{
// TODO: 从单片机中获取速度
return 0.0;
}
// ==== ==== ==== ==== ==== ==== Set ==== ==== ==== ==== ==== ====
public void setSpeed(StepMotorMId stepMotorMId, double speed) throws HardwareException {
// 检查速度是否合法
// 设置速度到单片机
int motorSpeed = StepMotorConverter.toMotorSpeed(Math.abs(speed), config_.getLead(stepMotorMId));
log.info("Motor {} speed set to {}, motorSpeed {}", stepMotorMId.mid.getDescription(), speed, motorSpeed);
stepMotorCtrlDriver_.setReg(stepMotorMId, StepMotorRegIndex.kreg_step_motor_default_velocity, motorSpeed);
}
// ==== ==== ==== ==== ==== ==== Ctrl ==== ==== ==== ==== ==== ====
public void motorEnable(StepMotorMId stepMotorMId, Boolean enable) throws Exception
{
Integer i_enable = enable ? 1 : 0;
stepMotorCtrlDriver_.stepMotorEnable(stepMotorMId, i_enable);
}
public void moveToHome(StepMotorMId stepMotorMId) throws Exception
{
log.info("Motor {} Move To Home", stepMotorMId.mid.getDescription());
motorEnable(stepMotorMId, true);
stepMotorCtrlDriver_.stepMotorEasyMoveToZeroBlock(stepMotorMId);
motorEnable(stepMotorMId, false);
}
public void moveTo(StepMotorMId stepMotorMId, double position) throws Exception
{
// 检查位置是否合法
if (Math.abs(position) > Math.abs(config_.getMaxLimit(stepMotorMId))) {
log.error("Motor {} Move To position out of range, position {} , limit {}", stepMotorMId.mid.getDescription(), position , config_.getMaxLimit(stepMotorMId));
throw new InvalidParameterException("position is out of range");
}
motorEnable(stepMotorMId, true);
int motorPosition = StepMotorConverter.toMotorPosition(position);
log.info("Motor {} Move To position {}, Motor Positon {}", stepMotorMId.mid.getDescription(), position, motorPosition);
stepMotorCtrlDriver_.stepMotorEasyMoveToBlock(stepMotorMId, motorPosition);
motorEnable(stepMotorMId, false);
}
public void moveBy(StepMotorMId stepMotorMId, double distance) throws Exception
{
// 检查位置是否合法
if (Math.abs(distance) > Math.abs(config_.getMaxLimit(stepMotorMId))) {
log.error("Motor {} Move By position out of range, position {} , limit {}", stepMotorMId.mid.getDescription(), distance , config_.getMaxLimit(stepMotorMId));
throw new InvalidParameterException("Distance is out of range");
}
motorEnable(stepMotorMId, true);
int motorPosition = StepMotorConverter.toMotorPosition(distance);
log.info("Motor {} Move By position {}, Motor Positon {}", stepMotorMId.mid.getDescription(), distance, motorPosition);
stepMotorCtrlDriver_.stepMotorEasyMoveByBlock(stepMotorMId, motorPosition);
motorEnable(stepMotorMId, false);
}
/**
* 正转加液 反转排液
* @param stepMotorMId
* @param direct
* @throws Exception
*/
public void rotate(StepMotorMId stepMotorMId, StepMotorDirect direct) throws Exception
{
motorEnable(stepMotorMId, true);
stepMotorCtrlDriver_.stepMotorEasyRotate(stepMotorMId, direct.getValue());
}
public void stop(StepMotorMId stepMotorMId) throws Exception {
log.info("Motor {} Stop", stepMotorMId.mid.getDescription());
stepMotorCtrlDriver_.stepMotorStop(stepMotorMId);
motorEnable(stepMotorMId, true);
}
}

100
src/main/java/com/iflytop/colortitration/hardware/drivers/StepMotorDriver/HBotDriver.java

@ -1,100 +0,0 @@
package com.iflytop.colortitration.hardware.drivers.StepMotorDriver;
import com.iflytop.colortitration.hardware.config.StepMotorConfig;
import com.iflytop.colortitration.hardware.drivers.DODriver.OutputIOCtrlDriver;
import com.iflytop.colortitration.hardware.exception.HardwareException;
import com.iflytop.colortitration.hardware.type.IO.OutputIOMId;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorMId;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorRegIndex;
import com.iflytop.colortitration.hardware.utils.Math.StepMotorConverter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.security.InvalidParameterException;
@Slf4j
@Component
@RequiredArgsConstructor
public class HBotDriver {
private final StepMotorConfig config_;
private final OutputIOCtrlDriver doDriver_;
private final StepMotorCtrlDriver stepMotorCtrlDriver_;
// ==== ==== ==== ==== ==== ==== Get ==== ==== ==== ==== ==== ====
private double getSpeed(StepMotorMId stepMotorMId)
{
// TODO: 从单片机中获取速度
return 0.0;
}
// ==== ==== ==== ==== ==== ==== Set ==== ==== ==== ==== ==== ====
public void setSpeed(StepMotorMId stepMotorMId, double speed) throws HardwareException {
// 检查速度是否合法
// 设置速度到单片机
int motorSpeed = StepMotorConverter.toMotorSpeed(Math.abs(speed), config_.getLead(stepMotorMId));
stepMotorCtrlDriver_.setReg(stepMotorMId, StepMotorRegIndex.kreg_step_motor_default_velocity, motorSpeed);
}
// ==== ==== ==== ==== ==== ==== Ctrl ==== ==== ==== ==== ==== ====
public void motorEnable(StepMotorMId stepMotorMId, Boolean enable) throws Exception {
Integer i_enable = enable ? 1 : 0;
stepMotorCtrlDriver_.stepMotorEnable(stepMotorMId, i_enable);
}
public void moveToHome(StepMotorMId stepMotorMId) throws Exception {
log.info("Motor {} Move To Home", stepMotorMId.mid.getDescription());
motorEnable(stepMotorMId, true);
stepMotorCtrlDriver_.stepMotorEasyMoveToZeroBlock(stepMotorMId);
}
public void moveTo(StepMotorMId stepMotorMId, double position) throws Exception {
// 检查位置是否合法
if (Math.abs(position) > Math.abs(config_.getMaxLimit(stepMotorMId))) {
log.error("Motor {} Move To position out of range, position {}, limit {}", stepMotorMId.mid.getDescription(), position, config_.getMaxLimit(stepMotorMId));
throw new InvalidParameterException("position is out of range");
}
motorEnable(stepMotorMId, true);
int motorPosition = StepMotorConverter.toMotorPosition(position);
log.info("Motor {} Move To position {}, Motor Position {}", stepMotorMId.mid.getDescription(), position, motorPosition);
stepMotorCtrlDriver_.stepMotorEasyMoveToBlock(stepMotorMId, motorPosition);
}
public void moveBy(StepMotorMId stepMotorMId, double distance) throws Exception {
// 检查位置是否合法
if (Math.abs(distance) > Math.abs(config_.getMaxLimit(stepMotorMId))) {
log.error("Motor {} Move By distance out of range, distance {}, limit {}", stepMotorMId.mid.getDescription(), distance, config_.getMaxLimit(stepMotorMId));
throw new InvalidParameterException("Distance is out of range");
}
motorEnable(stepMotorMId, true);
int motorPosition = StepMotorConverter.toMotorPosition(distance);
log.info("Motor {} Move By distance {}, Motor Position {}", stepMotorMId.mid.getDescription(), distance, motorPosition);
stepMotorCtrlDriver_.stepMotorEasyMoveByBlock(stepMotorMId, motorPosition);
}
public void stop(StepMotorMId stepMotorMId) throws Exception {
log.info("Motor {} Stop", stepMotorMId.mid.getDescription());
stepMotorCtrlDriver_.stepMotorStop(stepMotorMId);
motorEnable(stepMotorMId, true);
}
// ==== ==== ==== ==== ==== ==== IO Ctrl ==== ==== ==== ==== ====
public void openClamp(OutputIOMId iomId) throws Exception
{
if(iomId == null) {
return;
}
doDriver_.open(iomId);
}
public void closeClamp(OutputIOMId iomId) throws Exception
{
if(iomId == null) {
return;
}
doDriver_.close(iomId);
}
}

79
src/main/java/com/iflytop/colortitration/hardware/drivers/StepMotorDriver/HeaterMotorDriver.java

@ -1,79 +0,0 @@
package com.iflytop.colortitration.hardware.drivers.StepMotorDriver;
import com.iflytop.colortitration.hardware.config.StepMotorConfig;
import com.iflytop.colortitration.hardware.exception.HardwareException;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorMId;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorRegIndex;
import com.iflytop.colortitration.hardware.utils.Math.StepMotorConverter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.security.InvalidParameterException;
@Slf4j
@Component
@RequiredArgsConstructor
public class HeaterMotorDriver {
private final StepMotorConfig config_;
private final StepMotorCtrlDriver stepMotorCtrlDriver_;
// ==== ==== ==== ==== ==== ==== Get ==== ==== ==== ==== ==== ====
private double getSpeed(StepMotorMId stepMotorMId)
{
// TODO: 从单片机中获取速度
return 0.0;
}
// ==== ==== ==== ==== ==== ==== Set ==== ==== ==== ==== ==== ====
public void setSpeed(StepMotorMId stepMotorMId, double speed) throws HardwareException {
// 检查速度是否合法
// 设置速度到单片机
int motorSpeed = StepMotorConverter.toMotorSpeed(Math.abs(speed), config_.getLead(stepMotorMId));
stepMotorCtrlDriver_.setReg(stepMotorMId, StepMotorRegIndex.kreg_step_motor_default_velocity, motorSpeed);
}
// ==== ==== ==== ==== ==== ==== Ctrl ==== ==== ==== ==== ==== ====
public void motorEnable(StepMotorMId stepMotorMId, Boolean enable) throws Exception {
Integer i_enable = enable ? 1 : 0;
stepMotorCtrlDriver_.stepMotorEnable(stepMotorMId, i_enable);
}
public void moveToHome(StepMotorMId stepMotorMId) throws Exception {
log.info("Motor {} Move To Home", stepMotorMId.mid.getDescription());
motorEnable(stepMotorMId, true);
stepMotorCtrlDriver_.stepMotorEasyMoveToZeroBlock(stepMotorMId);
}
public void moveTo(StepMotorMId stepMotorMId, double position) throws Exception {
// 检查位置是否合法
if (Math.abs(position) > Math.abs(config_.getMaxLimit(stepMotorMId))) {
log.error("Motor {} Move To position out of range, position {}, limit {}", stepMotorMId.mid.getDescription(), position, config_.getMaxLimit(stepMotorMId));
throw new InvalidParameterException("position is out of range");
}
motorEnable(stepMotorMId, true);
int motorPosition = StepMotorConverter.toMotorPosition(position);
log.info("Motor {} Move To position {}, Motor Position {}", stepMotorMId.mid.getDescription(), position, motorPosition);
stepMotorCtrlDriver_.stepMotorEasyMoveToBlock(stepMotorMId, motorPosition);
}
public void moveBy(StepMotorMId stepMotorMId, double distance) throws Exception {
// 检查位置是否合法
if (Math.abs(distance) > Math.abs(config_.getMaxLimit(stepMotorMId))) {
log.error("Motor {} Move By distance out of range, distance {}, limit {}", stepMotorMId.mid.getDescription(), distance, config_.getMaxLimit(stepMotorMId));
throw new InvalidParameterException("Distance is out of range");
}
motorEnable(stepMotorMId, true);
int motorPosition = StepMotorConverter.toMotorPosition(distance);
log.info("Motor {} Move By distance {}, Motor Position {}", stepMotorMId.mid.getDescription(), distance, motorPosition);
stepMotorCtrlDriver_.stepMotorEasyMoveByBlock(stepMotorMId, motorPosition);
}
public void stop(StepMotorMId stepMotorMId) throws Exception {
log.info("Motor {} Stop", stepMotorMId.mid.getDescription());
stepMotorCtrlDriver_.stepMotorStop(stepMotorMId);
motorEnable(stepMotorMId, true);
}
}

90
src/main/java/com/iflytop/colortitration/hardware/drivers/StepMotorDriver/ShakeMotorDriver.java

@ -1,90 +0,0 @@
package com.iflytop.colortitration.hardware.drivers.StepMotorDriver;
import com.iflytop.colortitration.hardware.config.StepMotorConfig;
import com.iflytop.colortitration.hardware.exception.HardwareException;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorDirect;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorMId;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorRegIndex;
import com.iflytop.colortitration.hardware.utils.Math.StepMotorConverter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.security.InvalidParameterException;
@Slf4j
@Component
@RequiredArgsConstructor
public class ShakeMotorDriver {
private final StepMotorConfig config_;
private final StepMotorCtrlDriver stepMotorCtrlDriver_;
// ==== ==== ==== ==== ==== ==== Get ==== ==== ==== ==== ==== ====
private double getSpeed(StepMotorMId stepMotorMId)
{
// TODO: 从单片机中获取速度
return 0.0;
}
// ==== ==== ==== ==== ==== ==== Set ==== ==== ==== ==== ==== ====
public void setSpeed(StepMotorMId stepMotorMId, double speed) throws HardwareException {
// 检查速度是否合法
// 设置速度到单片机
int motorSpeed = StepMotorConverter.toMotorSpeed(Math.abs(speed), config_.getLead(stepMotorMId));
stepMotorCtrlDriver_.setReg(stepMotorMId, StepMotorRegIndex.kreg_step_motor_default_velocity, motorSpeed);
}
// ==== ==== ==== ==== ==== ==== Ctrl ==== ==== ==== ==== ==== ====
public void motorEnable(StepMotorMId stepMotorMId, Boolean enable) throws Exception {
Integer i_enable = enable ? 1 : 0;
stepMotorCtrlDriver_.stepMotorEnable(stepMotorMId, i_enable);
}
public void moveToHome(StepMotorMId stepMotorMId) throws Exception {
log.info("Motor {} Move To Home", stepMotorMId.mid.getDescription());
motorEnable(stepMotorMId, true);
stepMotorCtrlDriver_.stepMotorEasyMoveToZeroBlock(stepMotorMId);
}
public void moveTo(StepMotorMId stepMotorMId, double position) throws Exception {
// 检查位置是否合法
if (Math.abs(position) > Math.abs(config_.getMaxLimit(stepMotorMId))) {
log.error("Motor {} Move To position out of range, position {}, limit {}", stepMotorMId.mid.getDescription(), position, config_.getMaxLimit(stepMotorMId));
throw new InvalidParameterException("position is out of range");
}
motorEnable(stepMotorMId, true);
int motorPosition = StepMotorConverter.toMotorPosition(position);
log.info("Motor {} Move To position {}, Motor Position {}", stepMotorMId.mid.getDescription(), position, motorPosition);
stepMotorCtrlDriver_.stepMotorEasyMoveToBlock(stepMotorMId, motorPosition);
}
public void moveBy(StepMotorMId stepMotorMId, double distance) throws Exception {
// 检查位置是否合法
if (Math.abs(distance) > Math.abs(config_.getMaxLimit(stepMotorMId))) {
log.error("Motor {} Move By distance out of range, distance {}, limit {}", stepMotorMId.mid.getDescription(), distance, config_.getMaxLimit(stepMotorMId));
throw new InvalidParameterException("Distance is out of range");
}
motorEnable(stepMotorMId, true);
int motorPosition = StepMotorConverter.toMotorPosition(distance);
log.info("Motor {} Move By distance {}, Motor Position {}", stepMotorMId.mid.getDescription(), distance, motorPosition);
stepMotorCtrlDriver_.stepMotorEasyMoveByBlock(stepMotorMId, motorPosition);
}
public void stop(StepMotorMId stepMotorMId) throws Exception {
log.info("Motor {} Stop", stepMotorMId.mid.getDescription());
stepMotorCtrlDriver_.stepMotorStop(stepMotorMId);
motorEnable(stepMotorMId, true);
}
public void startShake(StepMotorMId stepMotorMId, StepMotorDirect direct) throws Exception {
motorEnable(stepMotorMId, true);
stepMotorCtrlDriver_.stepMotorEasyRotate(stepMotorMId, direct.getValue());
}
public void stopShake(StepMotorMId stepMotorMId) throws Exception {
this.stop(stepMotorMId);
this.moveToHome(stepMotorMId);
}
}

98
src/main/java/com/iflytop/colortitration/hardware/drivers/StepMotorDriver/TrayMotorDriver.java

@ -1,98 +0,0 @@
package com.iflytop.colortitration.hardware.drivers.StepMotorDriver;
import com.iflytop.colortitration.hardware.config.StepMotorConfig;
import com.iflytop.colortitration.hardware.drivers.DODriver.OutputIOCtrlDriver;
import com.iflytop.colortitration.hardware.exception.HardwareException;
import com.iflytop.colortitration.hardware.type.IO.OutputIOMId;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorMId;
import com.iflytop.colortitration.hardware.type.StepMotor.StepMotorRegIndex;
import com.iflytop.colortitration.hardware.utils.Math.StepMotorConverter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.security.InvalidParameterException;
@Slf4j
@Component
@RequiredArgsConstructor
public class TrayMotorDriver {
private final StepMotorConfig config_;
private final OutputIOCtrlDriver doDriver_;
private final StepMotorCtrlDriver stepMotorCtrlDriver_;
// ==== ==== ==== ==== ==== ==== Get ==== ==== ==== ==== ==== ====
private double getSpeed(StepMotorMId stepMotorMId)
{
// TODO: 从单片机中获取速度
return 0.0;
}
// ==== ==== ==== ==== ==== ==== Set ==== ==== ==== ==== ==== ====
public void setSpeed(StepMotorMId stepMotorMId, double speed) throws HardwareException {
// 检查速度是否合法
// 设置速度到单片机
int motorSpeed = StepMotorConverter.toMotorSpeed(Math.abs(speed), config_.getLead(stepMotorMId));
stepMotorCtrlDriver_.setReg(stepMotorMId, StepMotorRegIndex.kreg_step_motor_default_velocity, motorSpeed);
}
// ==== ==== ==== ==== ==== ==== Ctrl ==== ==== ==== ==== ==== ====
public void motorEnable(StepMotorMId stepMotorMId, Boolean enable) throws Exception {
Integer i_enable = enable ? 1 : 0;
stepMotorCtrlDriver_.stepMotorEnable(stepMotorMId, i_enable);
}
public void moveToHome(StepMotorMId stepMotorMId) throws Exception {
log.info("Motor {} Move To Home", stepMotorMId.mid.getDescription());
motorEnable(stepMotorMId, true);
stepMotorCtrlDriver_.stepMotorEasyMoveToZeroBlock(stepMotorMId);
}
public void moveTo(StepMotorMId stepMotorMId, double position) throws Exception {
// 检查位置是否合法
if (Math.abs(position) > Math.abs(config_.getMaxLimit(stepMotorMId))) {
log.error("Motor {} Move To position out of range, position {}, limit {}", stepMotorMId.mid.getDescription(), position, config_.getMaxLimit(stepMotorMId));
throw new InvalidParameterException("position is out of range");
}
motorEnable(stepMotorMId, true);
int motorPosition = StepMotorConverter.toMotorPosition(position);
log.info("Motor {} Move To position {}, Motor Position {}", stepMotorMId.mid.getDescription(), position, motorPosition);
stepMotorCtrlDriver_.stepMotorEasyMoveToBlock(stepMotorMId, motorPosition);
}
public void moveBy(StepMotorMId stepMotorMId, double distance) throws Exception {
// 检查位置是否合法
if (Math.abs(distance) > Math.abs(config_.getMaxLimit(stepMotorMId))) {
log.error("Motor {} Move By distance out of range, distance {}, limit {}", stepMotorMId.mid.getDescription(), distance, config_.getMaxLimit(stepMotorMId));
throw new InvalidParameterException("Distance is out of range");
}
motorEnable(stepMotorMId, true);
int motorPosition = StepMotorConverter.toMotorPosition(distance);
log.info("Motor {} Move By distance {}, Motor Position {}", stepMotorMId.mid.getDescription(), distance, motorPosition);
stepMotorCtrlDriver_.stepMotorEasyMoveByBlock(stepMotorMId, motorPosition);
}
public void stop(StepMotorMId stepMotorMId) throws Exception {
log.info("Motor {} Stop", stepMotorMId.mid.getDescription());
stepMotorCtrlDriver_.stepMotorStop(stepMotorMId);
}
// ==== ==== ==== ==== ==== ==== IO Ctrl ==== ==== ==== ==== ====
public void openClamp(OutputIOMId iomId) throws Exception
{
if(iomId == null) {
return;
}
doDriver_.open(iomId);
}
public void closeClamp(OutputIOMId iomId) throws Exception
{
if(iomId == null) {
return;
}
doDriver_.close(iomId);
}
}

2
src/main/java/com/iflytop/colortitration/hardware/drivers/TricolorLightDriver.java

@ -19,10 +19,12 @@ public class TricolorLightDriver {
}
public void open(MId mid, Color color) throws HardwareException {
log.info("Open TricolorLight driver Color {}", color);
canBus.callcmd(mid, CmdId.tricolor_light_on, color.ordinal());
}
public void close(MId mid) throws HardwareException{
log.info("Close TricolorLight driver Color");
canBus.callcmd(mid, CmdId.tricolor_light_off);
}
}

35
src/main/java/com/iflytop/colortitration/hardware/type/CeramicPumpDriverSlaveId.java

@ -0,0 +1,35 @@
package com.iflytop.colortitration.hardware.type;
import com.iflytop.colortitration.common.enums.Device;
public enum CeramicPumpDriverSlaveId {
CERAMIC_PUMP1_ID(Device.CERAMIC_PUMP_1, 0x11),
CERAMIC_PUMP2_ID(Device.CERAMIC_PUMP_2, 0x12),
;
private final Device cmdDevice;
private final Integer slaveId;
CeramicPumpDriverSlaveId(Device cmdDevice, Integer slaveId) {
this.cmdDevice = cmdDevice;
this.slaveId = slaveId;
}
public Device getCmdDevice() {
return cmdDevice;
}
public Integer getSlaveId() {
return slaveId;
}
static public CeramicPumpDriverSlaveId getByCmdDevice(Device cmdDevice) {
for (CeramicPumpDriverSlaveId value : CeramicPumpDriverSlaveId.values()) {
if (value.cmdDevice == cmdDevice) {
return value;
}
}
return null;
}
}

15
src/main/java/com/iflytop/colortitration/hardware/type/CmdId.java

@ -53,6 +53,7 @@ public enum CmdId {
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"),
step_motor_set_clamp(0x022f, "STEP_MOTOR_SET_CLAMP"),//
mini_servo_enable(0x3601, "MINI_SERVO_ENABLE"),
@ -96,6 +97,20 @@ public enum CmdId {
adc_enable_log(0x05301, "ADC_ENABLE_LOG"),
adc_read_adc(0x05302, "ADC_READ_ADC"),
adc_read_multi_adc(0x05303, "ADC_READ_MULTI_ADC"),
// Chime Buzzer
chime_buzzer_turn_on_info(0x5601, "CHIME_BUZZER_TURN_ON_INFO"),
chime_buzzer_turn_on_alarm(0x5602, "CHIME_BUZZER_TURN_ON_ALARM"),
chime_buzzer_turn_off(0x5603, "CHIME_BUZZER_TURN_OFF"),
// Liquid Valve
liquid_valve_read_valve_pos(0x05701, "LIQUID_VALVE_READ_VALVE_POS"),
liquid_valve_read_motor_state(0x05702, "LIQUID_VALVE_READ_MOTOR_STATE"),
liquid_valve_switch_valve(0x5703, "LIQUID_VALVE_SWITCH_VALVE"),
liquid_valve_stop(0x5704, "LIQUID_VALVE_STOP"),
liquid_valve_reset(0x5705, "LIQUID_VALVE_RESET"),
liquid_valve_home_reset(0x5706, "LIQUID_VALVE_HOME_RESET"),
liquid_valve_force_stop(0x5707, "LIQUID_VALVE_FORCE_STOP");
;
public final static int ATTACH_IS_BYTES = 1;

24
src/main/java/com/iflytop/colortitration/hardware/type/IO/OutputIOMId.java

@ -2,24 +2,13 @@ package com.iflytop.colortitration.hardware.type.IO;
import com.iflytop.colortitration.hardware.type.MId;
public enum OutputIOMId {
DO_FAN1("FAN1", MId.IO1_IO, 0,false),
DO_FAN2("FAN2", MId.IO1_IO, 1,false),
DO_FAN3("FAN3", MId.IO1_IO, 2,false),
DO_FAN4("FAN4", MId.IO1_IO, 3,false),
DO_FAN5("FAN5", MId.IO1_IO, 4,false),
DO_FAN6("FAN6", MId.IO1_IO, 5,false),
DO_TRAY_MOTOR_CLAMP("TRAY_MOTOR_CLAMP [ 托盘电机 ] ", MId.IO1_IO, 6,false),
DO_HBOTZ_MOTOR_CLAMP("HBOTZ_MOTOR_CLAMP [ 龙门架Z轴 ] ", MId.IO1_IO, 7,false),
DO_VACUUM_VALVE3("VACUUM_PUMP_VALVE3 [ 真空阀3 ] ", MId.IO1_IO, 8,false),
DO_VACUUM_VALVE4("VACUUM_PUMP_VALVE4 [ 真空阀4 ] ", MId.IO1_IO, 9,false),
DO_VACUUM_VALVE5("VACUUM_PUMP_VALVE5 [ 真空阀5 ] ", MId.IO1_IO, 10,false),
DO_VACUUM_VALVE6("VACUUM_PUMP_VALVE6 [ 真空阀6 ] ", MId.IO1_IO, 11,false),
DO_WATER_PUMP("WATER_PUMP [ 水泵 ] ", MId.IO1_IO, 12,false),
DO_VENTILATOR("VENTILATOR [ 风机电源 ]", MId.IO1_IO, 13,false),
DO_COLD_TRAP_POWER("COLD_TRAP_POWER[ 冷阱 电源 ]", MId.IO1_IO, 14,false),
DO_BEEP("DO_BEEP [ 蜂鸣器 ]", MId.IO1_IO, 16,false),
DO_OUT17("DO_OUT17", MId.IO1_IO, 17,false),
DO_FAN1("FAN1", MId.IO1_IO, 0, false),
DO_FAN2("FAN2", MId.IO1_IO, 1, false),
DO_FAN3("FAN3", MId.IO1_IO, 2, false),
DO_FAN4("FAN4", MId.IO1_IO, 3, false),
SYSTEM_POWER("SYSTEM_POWER", MId.IO1_IO, 4, false),
;
final public String description;
@ -36,3 +25,4 @@ public enum OutputIOMId {
}
}

92
src/main/java/com/iflytop/colortitration/hardware/type/MId.java

@ -6,64 +6,40 @@ package com.iflytop.colortitration.hardware.type;
public enum MId {
NotSet(0, "未设置"),
IO1Board(5, "台面 IO 板模块"),
PWMLight(6, "PWM 灯"),
TriColorLight(7, "三色灯"),
HBotClawSV(8, "夹爪舵机"),//
DualRobotAxis1SV(9, "双轴机械臂1舵机"),
DualRobotAxis2SV(10, "双轴机械臂2舵机"),
IO1_IO(11, "台面 IO 板模块"),
IO1_ADC(12, "台面 ADC 板模块"),
LiquidDistributionArm(13, "加液臂"),
MainXSV(14, "X轴Leisai舵机"),//
MainYSV(15, "Y轴Leisai舵机"),//
// IO2Board(25, "台下 IO 板模块"),
DoorBoard(40, "门电机板模块"),//
DoorM(41, "门电机"),
ShakeModBoard(45, "摇匀模组板"), //
ShakeM(46, "加液位摇匀电机"), //
CapStorageBoard(50, "拍子存放板模块"), //
CapStorageM(51, "拍子存放电机"), //
HBotXBoard(65, "X轴板模块"),//
HBotXM(66, "X轴电机"),
HBotYBoard(70, "Y轴板模块"),//
HBotYM(71, "Y轴电机"),
HBotZBoard(75, "Z轴板模块"),//
HBotZM(76, "Z轴电机"),
Heater1Board(80, "加热1板模块"),//
Heater1M(81, "加热1电机"),
Heater2Board(85, "加热2板模块"),//
Heater2M(86, "加热2电机"),
Heater3Board(90, "加热3板模块"),//
Heater3M(91, "加热3电机"),
Heater4Board(95, "加热4板模块"),//
Heater4M(96, "加热4电机"),
Heater5Board(100, "加热5板模块"),//
Heater5M(101, "加热5电机"),
Heater6Board(105, "加热6板模块"),//
Heater6M(106, "加热6电机"),
AcidPump1Board(110, "加酸泵1板模块"),//
AcidPump1M(111, "加酸泵1电机"),
AcidPump2Board(115, "加酸泵2板模块"),//
AcidPump2M(116, "加酸泵2电机"),
AcidPump3Board(120, "加酸泵3板模块"),//
AcidPump3M(121, "加酸泵3电机"),
AcidPump4Board(125, "加酸泵4板模块"),//
AcidPump4M(126, "加酸泵4电机"),
AcidPump5Board(130, "加酸泵5板模块"),//
AcidPump5M(131, "加酸泵5电机"),
AcidPump6Board(135, "加酸泵6板模块"),//
AcidPump6M(136, "加酸泵6电机"),
AcidPump7Board(140, "加酸泵7板模块"),//
AcidPump7M(141, "加酸泵7电机"),
AcidPump8Board(145, "加酸泵8板模块"),//
AcidPump8M(146, "加酸泵8电机"),
IO1_IO(6, "台面 IO 板模块"),
IO1_TriColorLight(7, "三色灯"),
IO1_ADC(9, "台面 ADC 板模块"),
RobotArmBoard(40, "机械臂控制板"),
DualRobot1M(41, "机械臂X轴电机"),
DualRobot2M(42, "机械臂Y轴电机"),
RobotArmZM(43, "机械臂Z轴电机"),
RobotArmClawSV(44, "机械臂夹爪伺服"),
BrushlessPumpBoard(50, "无刷泵控制板"),
BrushlessPump1M(51, "无刷泵1号电机"),
BrushlessPump2M(52, "无刷泵2号电机"),
BrushlessPump3M(53, "无刷泵3号电机"),
BrushlessPump4M(54, "无刷泵4号电机"),
BrushlessPump5M(55, "无刷泵5号电机"),
BrushlessPump6M(56, "无刷泵6号电机"),
BrushlessPump7M(57, "无刷泵7号电机"),
BrushlessPump8M(58, "无刷泵8号电机"),
BrushlessPump9M(59, "无刷泵9号电机"),
BrushlessPump10M(60, "无刷泵10号电机"),
StepPumpBoard(65, "步进泵控制板"),
StepPump1M(66, "步进泵1号"),
StepPump2M(67, "步进泵2号"),
StepPump3M(68, "步进泵3号"),
TitratorBoard(75, "滴定仪控制板"),
TitratorStir1M(76, "滴定仪搅拌1泵"),
TitratorStir2M(77, "滴定仪搅拌2泵"),
Titrator1M(78, "滴定仪1泵"),
Titrator2M(79, "滴定仪2泵"),
;
final public String description;

4
src/main/java/com/iflytop/colortitration/hardware/type/Servo/MiniServoMId.java

@ -4,9 +4,7 @@ import com.iflytop.colortitration.hardware.type.MId;
public enum MiniServoMId {
NotSet(MId.NotSet),//
DUAL_ROBOT_AXIS1_MID(MId.DualRobotAxis1SV),//
DUAL_ROBOT_AXIS2_MID(MId.DualRobotAxis2SV),
CLAW_MID(MId.HBotClawSV)
RobotArmClawSV(MId.RobotArmClawSV),
;
final public MId mid;

4
src/main/java/com/iflytop/colortitration/hardware/type/StepMotor/StepMotorDirect.java → src/main/java/com/iflytop/colortitration/hardware/type/StepMotor/MotorDirect.java

@ -1,13 +1,13 @@
package com.iflytop.colortitration.hardware.type.StepMotor;
public enum StepMotorDirect {
public enum MotorDirect {
FORWARD(1), // 正转
BACKWARD(0), // 反转
;
private final int value;
StepMotorDirect(int value) {
MotorDirect(int value) {
this.value = value;
}

40
src/main/java/com/iflytop/colortitration/hardware/type/StepMotor/StepMotorMId.java

@ -3,26 +3,26 @@ package com.iflytop.colortitration.hardware.type.StepMotor;
import com.iflytop.colortitration.hardware.type.MId;
public enum StepMotorMId {
DOOR_MOTOR_MID(MId.DoorM),
SHAKE_MOTOR_MID(MId.ShakeM),
TRAY_MOTOR_MID(MId.CapStorageM),
HBOT_X_MOTOR_MID(MId.HBotXM),
HBOT_Y_MOTOR_MID(MId.HBotYM),
HBOT_Z_MOTOR_MID(MId.HBotZM),
HEATER_1_MOTOR_MID(MId.Heater1M),
HEATER_2_MOTOR_MID(MId.Heater2M),
HEATER_3_MOTOR_MID(MId.Heater3M),
HEATER_4_MOTOR_MID(MId.Heater4M),
HEATER_5_MOTOR_MID(MId.Heater5M),
HEATER_6_MOTOR_MID(MId.Heater6M),
ACID_PUMP_1_MOTOR_MID(MId.AcidPump1M),
ACID_PUMP_2_MOTOR_MID(MId.AcidPump2M),
ACID_PUMP_3_MOTOR_MID(MId.AcidPump3M),
ACID_PUMP_4_MOTOR_MID(MId.AcidPump4M),
ACID_PUMP_5_MOTOR_MID(MId.AcidPump5M),
ACID_PUMP_6_MOTOR_MID(MId.AcidPump6M),
ACID_PUMP_7_MOTOR_MID(MId.AcidPump7M),
ACID_PUMP_8_MOTOR_MID(MId.AcidPump8M),
DualRobot1M(MId.DualRobot1M),
DualRobot2M(MId.DualRobot2M),
RobotArmZM(MId.RobotArmZM),
BrushlessPump1M(MId.BrushlessPump1M),
BrushlessPump2M(MId.BrushlessPump2M),
BrushlessPump3M(MId.BrushlessPump3M),
BrushlessPump4M(MId.BrushlessPump4M),
BrushlessPump5M(MId.BrushlessPump5M),
BrushlessPump6M(MId.BrushlessPump6M),
BrushlessPump7M(MId.BrushlessPump7M),
BrushlessPump8M(MId.BrushlessPump8M),
BrushlessPump9M(MId.BrushlessPump9M),
BrushlessPump10M(MId.BrushlessPump10M),
StepPump1M(MId.StepPump1M),
StepPump2M(MId.StepPump2M),
StepPump3M(MId.StepPump3M),
TitratorStir1M(MId.TitratorStir1M),
TitratorStir2M(MId.TitratorStir2M),
Titrator1M(MId.Titrator1M),
Titrator2M(MId.Titrator2M)
;
final public MId mid;

122
src/main/java/com/iflytop/colortitration/hardware/utils/ZJsonHelper.java

@ -0,0 +1,122 @@
package com.iflytop.colortitration.hardware.utils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class ZJsonHelper {
public static String objectToJson(Object obj) {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.writeValueAsString(obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String objToPrettyJson(Object obj) {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static ObjectNode createObjectNode() {
return new ObjectMapper().createObjectNode();
}
public static ObjectNode readTree(String node) {
ObjectMapper mapper = new ObjectMapper();
if(node == null) {
return null;
}
if(node.isEmpty()) {
return null;
}
try {
return (ObjectNode) mapper.readTree(node);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static <T> T objectFromJson(String node, Class<T> tClass) {
return objectFromJson(readTree(node), tClass);
}
public static <T> T objectFromJson(ObjectNode node, Class<T> tClass) {
ObjectMapper mapper = new ObjectMapper();
if (node == null) {
return null;
}
if (tClass.getTypeName().equals(Integer.class.getTypeName())) {
if (node.get("value") == null)
return null;
return (T) Integer.valueOf(node.get("value").asInt());
}
if (tClass.getTypeName().equals(String.class.getTypeName())) {
if (node.get("value") == null)
return null;
return (T) node.get("value").asText();
}
if (tClass.getTypeName().equals(Boolean.class.getTypeName())) {
if (node.get("value") == null)
return null;
return (T) Boolean.valueOf(node.get("value").asBoolean());
}
if (tClass.getTypeName().equals(Double.class.getTypeName())) {
if (node.get("value") == null)
return null;
return (T) Double.valueOf(node.get("value").asDouble());
}
if (tClass.getTypeName().equals(Float.class.getTypeName())) {
if (node.get("value") == null)
return null;
return (T) Float.valueOf(node.get("value").floatValue());
}
if (tClass.isEnum()) {
if (node.get("value") == null)
return null;
return (T) Enum.valueOf((Class<Enum>) tClass, node.get("value").asText());
}
try {
return (T) mapper.treeToValue(node, tClass);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static ObjectNode createObjectNode(Object obj) {
ObjectMapper ObjectMapper = new ObjectMapper();
if (obj == null) {
return null;
}
if (obj instanceof Integer) {
return ObjectMapper.createObjectNode().put("value", (Integer) obj);
}
if (obj instanceof String) {
return ObjectMapper.createObjectNode().put("value", (String) obj);
}
if (obj instanceof Boolean) {
return ObjectMapper.createObjectNode().put("value", (Boolean) obj);
}
if (obj instanceof Double) {
return ObjectMapper.createObjectNode().put("value", (Double) obj);
}
if (obj instanceof Float) {
return ObjectMapper.createObjectNode().put("value", (Float) obj);
}
if (obj instanceof Enum) {
return ObjectMapper.createObjectNode().put("value", obj.toString());
}
return ObjectMapper.valueToTree(obj);
}
}
Loading…
Cancel
Save