baoshiwei
5 天以前 2ad852ee08e21ee681950f1d6058499248baf88e
src/utils/dataFetcher.ts
@@ -1,68 +1,118 @@
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;
}