| | |
| | | import { getLatestWsData } from '../pipe_client'; |
| | | import { invoke } from '@tauri-apps/api/core'; |
| | | |
| | | // const pipeName = 'tauri-pipe-server'; |
| | | import * as math from 'mathjs'; |
| | | |
| | | // const dataSource = 'ws'; // pipe|ws |
| | | // 定义一个类型,用于存储所有注册的回调函数 |
| | | type DataCallback = (data: number[]) => void; |
| | | const dataCallbacks: DataCallback[] = []; |
| | | |
| | | export async function fetchForceData() { |
| | | try { |
| | | let response: string | null = null; |
| | | |
| | | // if (dataSource === 'pipe') { |
| | | // if (!pipeName) throw new Error('Pipe name is required for pipe data source'); |
| | | // response = await sendToPipe(pipeName, 'GET_FORCE_DATA'); |
| | | // } else if (dataSource === 'ws') { |
| | | response = await getLatestWsData(); |
| | | if (!response) return null; |
| | | // } |
| | | |
| | | if (!response) return null; |
| | | |
| | | const jsonData = JSON.parse(response); |
| | | const forceData = jsonData[0]; |
| | | if (Array.isArray(forceData) && forceData.length === 6) { |
| | | // 将数组中的每个数分别*4000/4194303 |
| | | for (let i = 0; i < forceData.length; i++) { |
| | | forceData[i] = forceData[i] * 4000 / 4194303; |
| | | } |
| | | return forceData; |
| | | } |
| | | |
| | | return null; |
| | | } catch (error) { |
| | | console.error('Error fetching force data:', error); |
| | | return null; |
| | | // 注册数据接收回调函数 |
| | | export function registerDataCallback(callback: DataCallback) { |
| | | dataCallbacks.push(callback); |
| | | } |
| | | |
| | | // 移除数据接收回调函数 |
| | | export function unregisterDataCallback(callback: DataCallback) { |
| | | const index = dataCallbacks.indexOf(callback); |
| | | if (index > -1) { |
| | | dataCallbacks.splice(index, 1); |
| | | } |
| | | } |
| | | |
| | | export function createDataReceiver( callback: (data: number[]) => void) { |
| | | let errorCount = 0; |
| | | const maxConsecutiveErrors = 5; |
| | | let showingError = false; |
| | | |
| | | return async () => { |
| | | try { |
| | | const forceData = await fetchForceData(); |
| | | console.log('forceData111', forceData); |
| | | if (forceData) { |
| | | // 重置错误计数 |
| | | errorCount = 0; |
| | | if (showingError) { |
| | | showingError = false; |
| | | console.log('数据通信已恢复'); |
| | | } |
| | | console.log('forceData222', forceData); |
| | | callback(forceData); |
| | | } |
| | | } catch (err) { |
| | | // 增加错误计数 |
| | | errorCount++; |
| | | |
| | | // 只在连续错误达到阈值时显示错误信息,避免日志刷屏 |
| | | if (errorCount >= maxConsecutiveErrors && !showingError) { |
| | | showingError = true; |
| | | console.error('数据通信持续失败,请检查服务端状态:', err); |
| | | } |
| | | // 处理从Rust后端接收到的串口数据 |
| | | export function processSerialData(data: number[]): number[] | undefined { |
| | | // 对接收到的数据进行crc校验,前两个字节是帧头,后两个字节是校验值 |
| | | // 校验数据是否正确 |
| | | // 去除前两个字节和后两个字节 |
| | | const dataWithoutHeaderAndCRC = data.slice(0, -2); |
| | | const crc16 = crc16modbus(dataWithoutHeaderAndCRC); |
| | | // 校验数据是否正确 |
| | | if (crc16[0] === data[data.length - 2] && crc16[1] === data[data.length - 1]) { |
| | | console.log('校验数据正确'); |
| | | } |
| | | |
| | | const dataWithoutHeader = data.slice(2, -2); |
| | | // dataWithoutHeader 中每三个字节转换成一个数 |
| | | const dataArray: number[] = []; |
| | | for (let i = 0; i < dataWithoutHeader.length; i += 3) { |
| | | const num = dataWithoutHeader[i] * 256 * 256 + dataWithoutHeader[i + 1] * 256 + dataWithoutHeader[i + 2]; |
| | | dataArray.push(num); |
| | | } |
| | | console.log('dataArray', dataArray); |
| | | invoke('log_data', { data: JSON.stringify(dataArray) }) |
| | | .then(() => console.log('Data logged successfully')) |
| | | .catch((e: any) => console.error('Failed to log data:', e)); |
| | | // 对接收到的数据进行处理 |
| | | if (Array.isArray(dataArray) && dataArray.length === 6) { |
| | | // 将数组中的每个数分别*4000/4194303 |
| | | for (let i = 0; i < dataArray.length; i++) { |
| | | dataArray[i] = dataArray[i] * 4000 / 4194303; |
| | | } |
| | | |
| | | // 定义B矩阵(从Excel文件中获取) |
| | | const B = [ |
| | | [-6.501014986, 49.89944483, -47.37512707, 3.306871125, -730.3864937, 731.892412], |
| | | [39.02334352, -20.01844412, -28.31245682, -846.7104044, 422.5886114, 423.8930456], |
| | | [1323.394066, 1311.347472, 1318.438012, -6.141452446, -5.309142718, -17.72182533], |
| | | [-0.461934807, 38.31359845, -37.51342676, -10.30786014, 5.431648347, -4.552001119], |
| | | [44.06827786, -21.49540034, -22.28032529, -0.447302394, -8.60890465, 9.325018254], |
| | | [1.125851578, 1.306669827, 1.532290446, -23.04749193, -23.05906062, -23.19316741] |
| | | ]; |
| | | |
| | | // 计算真实的力值:F = B * dataArray |
| | | const realForces = math.multiply(B, dataArray); |
| | | |
| | | // 将处理后的数据分发给所有注册的回调函数 |
| | | dataCallbacks.forEach(callback => callback(realForces as number[])); |
| | | // 返回真实的力值数组 |
| | | return realForces as number[]; |
| | | } else { |
| | | console.error("Data array must contain 6 elements."); |
| | | return undefined; |
| | | } |
| | | } |
| | | |
| | | export function createDataReceiver(callback: (data: number[]) => void) { |
| | | // 直接注册回调函数,不再需要轮询或错误计数 |
| | | registerDataCallback(callback); |
| | | |
| | | // 返回一个清理函数,用于在组件卸载时移除回调 |
| | | return () => { |
| | | unregisterDataCallback(callback); |
| | | }; |
| | | } |
| | | } |
| | | |
| | | // CRC-16/Modbus 查表法预生成 256 个 CRC 值 |
| | | function makeCRCTable() { |
| | | const table = new Array(256); |
| | | const polynomial = 0xA001; |
| | | |
| | | for (let i = 0; i < 256; i++) { |
| | | let crc = i; |
| | | for (let j = 0; j < 8; j++) { |
| | | if (crc & 0x0001) { |
| | | crc = (crc >>> 1) ^ polynomial; |
| | | } else { |
| | | crc >>>= 1; |
| | | } |
| | | } |
| | | table[i] = crc; |
| | | } |
| | | return table; |
| | | } |
| | | |
| | | const crcTable = makeCRCTable(); |
| | | |
| | | // CRC-16/Modbus 计算函数 |
| | | function crc16modbus(buffer: number[]) { |
| | | let crc = 0xFFFF; |
| | | |
| | | for (let i = 0; i < buffer.length; i++) { |
| | | let tableIndex = (crc ^ buffer[i]) & 0xFF; |
| | | crc = (crc >>> 8) ^ crcTable[tableIndex]; |
| | | } |
| | | |
| | | // 返回小端格式(Modbus 要求低位在前),以字节数组的形式返回 |
| | | const crcBytes = [crc & 0xFF, crc >>> 8]; |
| | | return crcBytes; |
| | | } |