张世豪
8 天以前 c57cb0cd9feb4495c89246b2faec6d5e45c23c30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
package yaokong;
 
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
 
import chuankou.SerialPortService;
import chuankou.sendmessage;
 
/**
 * Control06.java - 遥控割草刀盘升降指令类
 * 
 * 指令类型: 0x06
 * 功能: 控制割草机刀盘的升降高度
 * 
 * 数据格式:
 *   升降值(1字节): -100~100,正数表示向上提升
 *   保留字段(3字节): 0x00填充
 * 
 * 示例用法:
 *   1. 提升刀盘50%: Control06.buildBladeCommandHex("50")
 *   2. 降低刀盘30%: Control06.buildBladeCommandHex("-30")
 *   3. 发送提升指令: Control06.sendBladeUpIfDebugSerialOpen(50)
 *   4. 发送降低指令: Control06.sendBladeDownIfDebugSerialOpen(30)
 */
public class Control06 {
    
    private static final int MAX_BLADE_VALUE = 100;
    private static final int MIN_BLADE_VALUE = -100;
    private static final int BLADE_STEP = 10; // 默认步进值
    
    private static int currentBladeHeight = 0; // 当前刀盘高度百分比
    
    /**
     * 构建遥控割草刀盘升降指令(指令类型0x06)的HEX格式字符串
     * 
     * @param bladeValueStr 刀盘高度值字符串,范围-100到100,正数表示向上提升
     * @return 刀盘升降指令的HEX格式字符串
     */
    public static String buildBladeCommandHex(String bladeValueStr) {
        int bladeValue = parseBladeValue(bladeValueStr);
        byte[] commandBytes = buildBladeCommandBytes((byte) bladeValue);
        return bytesToHex(commandBytes);
    }
    
    /**
     * 构建遥控割草刀盘升降指令的字节数组
     * 
     * @param bladeValue 刀盘高度值:-100~100,正数表示向上提升
     * @return 刀盘升降指令的字节数组
     */
    public static byte[] buildBladeCommandBytes(byte bladeValue) {
        // 验证刀盘高度范围
        if (bladeValue < -100 || bladeValue > 100) {
            throw new IllegalArgumentException("刀盘高度值必须在-100到100之间");
        }
        
        int dataLength = 4; // 升降值1字节 + 保留字段3字节
        
        ByteBuffer buffer = ByteBuffer.allocate(14); // 总长度14字节
        buffer.order(ByteOrder.LITTLE_ENDIAN);
        
        // 帧头
        buffer.put(BluetoothProtocol.FRAME_HEADER);
        
        // 指令类型 (0x06)
        buffer.put((byte) 0x06);
        
        // 数据长度
        buffer.putShort((short) dataLength);
        
        // 序列号
        short sequence = (short) BluetoothProtocol.getNextSequence();
        buffer.putShort(sequence);
        
        // 刀盘高度值
        buffer.put(bladeValue);
        
        // 保留字段 (3字节,全部填0)
        buffer.put((byte) 0x00);
        buffer.put((byte) 0x00);
        buffer.put((byte) 0x00);
        
        // 计算CRC16(从指令类型开始到数据内容结束)
        byte[] dataForCRC = new byte[9];
        ByteBuffer tempBuffer = ByteBuffer.allocate(9);
        tempBuffer.order(ByteOrder.LITTLE_ENDIAN);
        tempBuffer.put((byte) 0x06); // 指令类型
        tempBuffer.putShort((short) dataLength); // 数据长度
        tempBuffer.putShort(sequence); // 序列号
        tempBuffer.put(bladeValue); // 刀盘高度值
        tempBuffer.put((byte) 0x00); // 保留字段1
        tempBuffer.put((byte) 0x00); // 保留字段2
        tempBuffer.put((byte) 0x00); // 保留字段3
        
        dataForCRC = tempBuffer.array();
        int crc = CRC16.calculateCRC16(dataForCRC, 0, dataForCRC.length);
        buffer.putShort((short) crc);
        
        // 帧尾
        buffer.put((byte) 0x0D);
        
        return buffer.array();
    }
    
    /**
     * 当调试串口打开时发送提升刀盘指令
     * 
     * @param value 提升百分比值(0-100)
     * @return 发送成功返回true,否则返回false
     */
    public static boolean sendBladeUpIfDebugSerialOpen(int value) {
        int targetHeight = Math.min(currentBladeHeight + value, MAX_BLADE_VALUE);
        return sendBladeHeightIfDebugSerialOpen(targetHeight);
    }
    
    /**
     * 当调试串口打开时发送降低刀盘指令
     * 
     * @param value 降低百分比值(0-100)
     * @return 发送成功返回true,否则返回false
     */
    public static boolean sendBladeDownIfDebugSerialOpen(int value) {
        int targetHeight = Math.max(currentBladeHeight - value, MIN_BLADE_VALUE);
        return sendBladeHeightIfDebugSerialOpen(targetHeight);
    }
    
    /**
     * 当调试串口打开时发送刀盘归零指令
     * 
     * @return 发送成功返回true,否则返回false
     */
    public static boolean sendBladeResetIfDebugSerialOpen() {
        return sendBladeHeightIfDebugSerialOpen(0);
    }
    
    /**
     * 快捷方法:构建提升刀盘指令
     * 
     * @param value 提升百分比值(0-100)
     * @return 提升指令的HEX字符串
     */
    public static String bladeUp(int value) {
        int targetValue = Math.min(Math.max(value, 0), MAX_BLADE_VALUE);
        return buildBladeCommandHex(String.valueOf(targetValue));
    }
    
    /**
     * 快捷方法:构建降低刀盘指令
     * 
     * @param value 降低百分比值(0-100)
     * @return 降低指令的HEX字符串
     */
    public static String bladeDown(int value) {
        int targetValue = Math.max(Math.min(-value, 0), MIN_BLADE_VALUE);
        return buildBladeCommandHex(String.valueOf(targetValue));
    }
    
    /**
     * 解析刀盘高度值字符串
     */
    private static int parseBladeValue(String bladeStr) {
        try {
            int value = Integer.parseInt(bladeStr.trim());
            if (value < MIN_BLADE_VALUE || value > MAX_BLADE_VALUE) {
                throw new IllegalArgumentException("刀盘高度值必须在-100到100之间");
            }
            return value;
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("刀盘高度值必须是整数: " + bladeStr);
        }
    }
    
    /**
     * 发送刀盘高度控制指令(内部方法)
     */
    private static boolean sendBladeHeightIfDebugSerialOpen(int targetHeight) {
        SerialPortService service = sendmessage.getActiveService();
        if (service == null || !service.isOpen()) {
            return false;
        }
        byte[] payload = buildBladeCommandBytes((byte) targetHeight);
        
        // 调试:打印发送的数据
        System.out.println("发送刀盘升降指令: " + bytesToHex(payload));
        
        boolean success = sendmessage.sendViaActive(payload);
        if (success) {
            currentBladeHeight = targetHeight;
        }
        return success;
    }
    
    /**
     * 获取当前刀盘高度
     * 
     * @return 当前刀盘高度百分比(-100到100)
     */
    public static int getCurrentBladeHeight() {
        return currentBladeHeight;
    }
    
    /**
     * 重置刀盘高度为0
     */
    public static void resetBladeHeight() {
        currentBladeHeight = 0;
    }
    
    /**
     * 字节数组转换为HEX字符串
     */
    private static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
            if (i < bytes.length - 1) {
                hexString.append(' ');
            }
        }
        return hexString.toString().toUpperCase();
    }
    
    /**
     * 测试函数:验证刀盘升降指令构建
     */
    public static void testBuildBladeCommand() {
        System.out.println("=== 测试刀盘升降指令构建 ===");
        
        // 测试1:提升指令
        byte[] cmd1 = buildBladeCommandBytes((byte)50);
        System.out.println("提升50%: " + bytesToHex(cmd1));
        
        // 测试2:降低指令
        byte[] cmd2 = buildBladeCommandBytes((byte)-30);
        System.out.println("降低30%: " + bytesToHex(cmd2));
        
        // 测试3:归零指令
        byte[] cmd3 = buildBladeCommandBytes((byte)0);
        System.out.println("归零: " + bytesToHex(cmd3));
    }
}