41 Commits

Author SHA1 Message Date
b731c31241 test 2026-06-03 13:51:00 +08:00
382a5f6c34 chore: 从 git 跟踪中移除 cmake-build 构建产物并清理 .gitignore
- 将 .gitignore 中 18 行重复的 cmake-build 条目合并为 1 行通配规则
  /myis11/project/*/cmake-build-*
- 使用 git rm --cached -r 将 4 个被跟踪的构建目录从索引移除
- 磁盘文件未受任何影响
2026-06-03 13:49:34 +08:00
xin
f99647775c test 2026-06-03 13:43:27 +08:00
90b1fe2f7a 补充提交 2025-09-18 17:34:12 +08:00
c414e66e2b fix:修改测试出的问题 2025-09-18 17:23:05 +08:00
77ed33e66c nMerge branch 'main' of http://git.iris-rs.cn/xin/SpectralPlot 2025-08-11 14:34:55 +08:00
a41a611975 fix:完成数据查看模块 2025-08-11 14:21:39 +08:00
xin
4d067e62ea 添加is112022 2025-07-21 11:34:02 +08:00
xin
5104d09674 添加liux编译 2025-07-02 11:15:46 +08:00
xin
7efa0e210b rust 适配linux 2025-06-30 17:04:27 +08:00
xin
2492e4b650 去除了test 2025-06-30 16:03:57 +08:00
xin
c9f4412f89 去除了test 2025-06-30 16:02:51 +08:00
xin
d111649c41 去除了test 2025-06-30 16:01:28 +08:00
xin
a3cf0f610e 去除了test 2025-06-30 15:57:02 +08:00
xin
e5bf2d35cd 去除了test 2025-06-30 15:56:19 +08:00
xin
78c34a0e57 去除了test 2025-06-30 15:55:05 +08:00
xin
353ff3353e 修复 2025-06-30 15:52:38 +08:00
xin
978dcf8abf 修复 2025-06-30 15:51:34 +08:00
xin
023dd01e29 修复 2025-06-30 15:49:32 +08:00
xin
5279134836 修复 2025-06-30 15:48:46 +08:00
xin
bd5fac5ec8 修复 2025-06-30 15:46:21 +08:00
xin
8c594933b9 修复 2025-06-30 15:45:46 +08:00
xin
8e72b0b12c 修复 2025-06-30 15:43:48 +08:00
xin
e52359f321 修改gitignore 2025-06-30 15:42:20 +08:00
xin
9ccfe6c75f 修改该linux下dll导出 2025-06-30 15:41:52 +08:00
xin
cb1d44f616 替换strcpy_s 为snprintf 2025-06-30 15:35:27 +08:00
xin
7ccd30e3c7 修复 memcpy 2025-06-30 15:28:41 +08:00
xin
ca18d29829 取消linux下is3test 2025-06-30 15:27:04 +08:00
xin
781361acd5 取消linux下is3test 2025-06-30 15:23:14 +08:00
xin
c45fc5d7b3 重复提交 2025-06-30 15:12:03 +08:00
xin
a2033b2132 修改dll该路径 2025-06-30 15:10:49 +08:00
xin
d7c7acb018 windows提交 2025-06-30 13:51:45 +08:00
xin
94336c9ba1 rust 2025-05-07 11:13:56 +08:00
xin
fb037dbf6f adfasdfa 2025-05-07 11:10:44 +08:00
xin
8820b28ab8 修复连续采集时没有时间间隔导致通讯失败从而导致无有法正常连续采集的问题 修改如下 2025-03-31 13:53:01 +08:00
xin
62a5415e97 增加了is3的支持 2025-03-31 13:42:44 +08:00
xin
9e8566d158 Remove incorrect submodule myis11/src/third 2025-02-19 16:47:26 +08:00
xin
4c6b3fc4d7 Attempt to remove incorrect submodule myis11/src/third (path not found by rm) 2025-02-19 16:39:23 +08:00
xin
e8d98f155d 修复连续采集时没有时间间隔导致通讯失败从而导致无有法正常连续采集的问题 修改如下 2024-09-27 16:16:03 +08:00
6d47134dac 再次提交 2024-08-21 14:19:40 +08:00
fb3257bb75 界面修改 兼容is11 2024-08-21 14:16:54 +08:00
139 changed files with 19041 additions and 1390 deletions

7
.gitignore vendored
View File

@ -22,3 +22,10 @@ dist-ssr
*.njsproj *.njsproj
*.sln *.sln
*.sw? *.sw?
/myis11/project/*/cmake-build-*
/myis11/project/is11/vscode/
/myis11/.vscode/
/myis11/.cmake/
/.vscode/
/src-tauri/.cargo/

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "myis11/src/thirdpart/iris_proto_tool"]
path = myis11/src/thirdpart/iris_proto_tool
url = http://172.16.0.230:3000/xin/IRIS_Communication_Protocol.git

12
.roo/mcp.json Normal file
View File

@ -0,0 +1,12 @@
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"./"
]
}
}
}

View File

@ -1,3 +1,5 @@
# 通用光谱采集软件 # 通用光谱采集软件
插入复选框
aaa <input disabled="" type="checkbox"> Checkbox 1

BIN
README.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@ -0,0 +1,3 @@
1 函数 invoke("getoneirisfile",{path:"iris_data_example.iris"}) 返回一次数据
2 fs

View File

@ -23,7 +23,7 @@
padding: 0px; padding: 0px;
} }
</style> </style>
<script src="http://172.16.0.84:8098"></script> <!-- <script src="http://localhost:8098"></script> -->
</head> </head>
<body> <body>

Binary file not shown.

View File

@ -0,0 +1,33 @@
cmake_minimum_required(VERSION 3.5)
project(is11lib)
if (MSVC)
# 静态链接多线程版本的运行时库
set(CMAKE_CXX_FLAGS "/MT")
set(CMAKE_C_FLAGS "/MT")
endif()
include_directories(../../src/test)
include_directories(../../src/IRIS_IS3)
include_directories(../../src/comman)
include_directories(../../src/is11)
add_library(is11lib SHARED
../../src/test/test.cpp
../../src/is11/SensorIS11.cpp
../../src/is11/SensorIS11.h
../../src/is11/IS11Comon.cpp
../../src/is11/IS11Comon.h
../../src/is11/IS11_INST.cpp
../../src/is11/IS11_INST.h
)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
add_executable(is11test
testmain.cpp
)
target_link_libraries(is11test is11lib)

View File

@ -0,0 +1,18 @@
/**
******************************************************************************
* @file : testmain.cpp
* @author : xin
* @brief : None
* @attention : None
* @date : 2024/8/14
******************************************************************************
*/
#include "IS11_INST.h"
int main() {
// IS11SensorInit();
Set_Serial_FUN(NULL,NULL);
return 0;
}
//
// Created by xin on 2024/8/14.
//

View File

@ -0,0 +1,45 @@
cmake_minimum_required(VERSION 3.5)
#vcpkg config
if (MSVC)
set(CMAKE_TOOLCHAIN_FILE "E:/01MyCode/vcpkg/vcpkgclion/scripts/buildsystems/vcpkg.cmake")
endif()
project(is11lib)
if (MSVC)
find_package(cserialport REQUIRED)
# 静态链接多线程版本的运行时库
set(CMAKE_CXX_FLAGS "/MT")
set(CMAKE_C_FLAGS "/MT")
include_directories(${CSerialPort_INCLUDE_DIR})
message(STATUS "CSerialPort_INCLUDE_DIR: ${CSerialPort_INCLUDE_DIR}")
endif()
include_directories(../../src/test)
include_directories(../../src/IRIS_IS3)
include_directories(../../src/comman)
include_directories(../../src/thirdpart/iris_proto_tool/src)
add_library(iris_is3lib SHARED
../../src/thirdpart/iris_proto_tool/src/IRIS_Method.cpp
../../src/IRIS_IS3/SensorIS3.cpp
../../src/IRIS_IS3/IS3_INST.cpp
../../src/IRIS_IS3/IS3Comon.cpp
)
if (MSVC)
add_executable(is3test
testmain.cpp
)
target_link_libraries(is3test iris_is3lib ${CSerialPort_LIBRARY})
message(STATUS "CSerialPort_LIBRARY: ${CSerialPort_LIBRARY}")
#add_executable(is11test
# testmain.cpp
#)
endif()
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

View File

@ -0,0 +1,129 @@
/**
******************************************************************************
* @file : testmain.cpp
* @author : xin
* @brief : None
* @attention : None
* @date : 2024/8/14
******************************************************************************
*/
#include "IS3_INST.h"
#include "CSerialPort/SerialPort.h"
#include "CSerialPort/SerialPortInfo.h"
#include "stdio.h"
#include "vector"
using namespace itas109;
CSerialPort *serialport;
size_t SerialWrite(u_char* data,size_t lenth)
{
printf("write data:");
for (int i = 0; i < lenth; ++i) {
printf("%02x ",data[i]);
}
printf("\n");
fflush(stdout);
serialport->flushReadBuffers();
return serialport->writeData(data,lenth);
}
size_t SerailRead(u_char* data,size_t lenth)
{
size_t lenthread=serialport->readData(data,lenth);
// printf("read data:");
// for (int i = 0; i < lenthread; ++i)
// {
// printf("%02x ",data[i]);
// }
// printf("\n");
// printf("read data: %d\n",lenthread);
// int indexnow=serialport->getReadBufferUsedLen();
// printf("read data index: %d\n",indexnow);
//fflush(stdout);
return lenthread;
}
int main() {
serialport = new CSerialPort();
//获取串口列表
std::vector<SerialPortInfo> portNameList = CSerialPortInfo::availablePortInfos();
for (int i = 0; i < portNameList.size(); ++i) {
printf("portName:%s\n",portNameList[i].portName);
}
std::string portname="COM24";
serialport->init(portname.c_str(),BaudRate921600 ,ParityNone,DataBits8,StopOne,FlowNone,512*512);
serialport->setOperateMode(SynchronousOperate);
//serialport->setReadIntervalTimeout(10000);
if (serialport->open())
{ printf("open success\n");
}else {
printf("open fail \n may be port: %s is busy or not exist\n",portname.c_str());
return 0;
}
// IS11SensorInit();
printf("Hello World\n");
IS3Set_Serial_FUN(SerialWrite,SerailRead);
IS3SensorInit();
uint16_t *buffforread=new uint16_t[1000];
// while (1) {
// IS3SetShutterOpen(0);
// IS3GetData(buffforread,1000);
// IS3SetShutterOpen(1);
// }
STRsensorinfo_C info= IS3Get_SensorInfo();
//输出info
printf("--------------------------------------\nSensorName:%s\n",info.SensorName);
printf("serialnumber:%s\n",info.serialnumber);
printf("maxValue:%d\n",info.maxValue);
printf("a1:%f\n",info.a1);
printf("a2:%f\n",info.a2);
printf("a3:%f\n",info.a3);
printf("a4:%f\n",info.a4 );
double a[4]={0.0,0.001,1,350};
IS3SetWeaveLenthCoeff(a,4);
info= IS3Get_SensorInfo();
//输出info
printf("SensorName:%s\n",info.SensorName);
printf("serialnumber:%s\n",info.serialnumber);
printf("maxValue:%d\n",info.maxValue);
printf("a1:%f\n",info.a1);
printf("a2:%f\n",info.a2);
printf("a3:%f\n",info.a3);
printf("a4:%f\n",info.a4 );
IS3OptSnenser(80);
while (1) {
IS3GetData(buffforread,200);
}
return 0;
}
//
// Created by xin on 2024/8/14.
//

View File

@ -0,0 +1,336 @@
#include "IS3Comon.h"
#ifdef _WIN32
#include <windows.h>
void delay(int ms){
Sleep(ms);
}
#else
#include <unistd.h> // For usleep
void delay(int ms){
usleep(ms * 1000); // Convert milliseconds to microseconds
}
#include <unistd.h>
#include <time.h>
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 199309L
#endif
#endif
#include <cstring>
#include <Communication_Protocol.h>
unsigned long long get_system_uptime_ms() {
#ifdef _WIN32
return GetTickCount64();
#else
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (unsigned long long)(ts.tv_sec) * 1000 + ts.tv_nsec / 1000000;
#endif
}
u_char BufferForRead[10000];
int TotalIndexNow = 0;
u_char BufferFortempWrite[1000];
// MySerialWrite=nullptr;
SERIALWRITE MySerialWrite = nullptr;
SERIALREAD MySerialRead = nullptr;
bool isIS3Init = false;
uint16_t crc16(const uint8_t *data, size_t len, uint16_t polynomial)
{
uint16_t i, j, tmp, CRC16;
CRC16 = 0xFFFF; // CRC<52>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ʼֵ
for (i = 0; i < len; i++)
{
CRC16 ^= data[i];
for (j = 0; j < 8; j++)
{
tmp = (uint16_t)(CRC16 & 0x0001);
CRC16 >>= 1;
if (tmp == 1)
{
CRC16 ^= polynomial; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ
}
}
}
return CRC16;
}
size_t SendSettingCommand(u_char Command, size_t CommandLenth, u_char *Value, size_t ValueLenth)
{
int lenthforwrite = IRIS_Protocol_Pack(Command, (uint16_t)ValueLenth, Value, (uint8_t *)BufferFortempWrite);
SerialWrite(BufferFortempWrite, lenthforwrite);
// for 5 <20><>
for (int i = 0; i < 10; i++)
{
size_t retunnumber = GetInfoBackFromSensorinTime(Command,1000);
if (retunnumber!=OVERTIME ) {
return retunnumber;
}
if (i%2==0) {
printf("send command again\n");
SerialWrite(BufferFortempWrite, lenthforwrite);
}
// <20><>I<EFBFBD>γ<EFBFBD><CEB3><EFBFBD> <20><><EFBFBD>ݻظ<DDBB><D8B8><20><><EFBFBD><EFBFBD>ȷʵ <20><>Ӣ<EFBFBD>Ĵ<EFBFBD>ӡ
printf("warning try %d times: date not enough,try again!!\n",i);
}
printf("ERROR date not enough,retunr !!\n");
return OVERTIME;
}
size_t SendGetData(int shutter)
{
uint8_t dataforsend=NONE_DATA;
int lenthforwrite=IRIS_Protocol_Pack(GET_DATA_FROM_SENSOR, (uint16_t)01, &dataforsend, (uint8_t *)BufferFortempWrite );
SerialWrite(BufferFortempWrite, lenthforwrite);
for (int i=0;i<10;i++)
{
size_t retunnumber = GetInfoBackFromSensorinTime(GET_DATA_FROM_SENSOR,3*shutter);
//size_t retunnumber = GetInfoBackFromSensorinTime(GET_DATA_FROM_SENSOR,2*shutter+2000);
if (retunnumber<OVERTIME) {
return retunnumber;
}
if (i%2==0) {
printf("send command again\n");
SerialWrite(BufferFortempWrite, lenthforwrite);
}
// <20><>I<EFBFBD>γ<EFBFBD><CEB3><EFBFBD> <20><><EFBFBD>ݻظ<DDBB><D8B8><20><><EFBFBD><EFBFBD>ȷʵ <20><>Ӣ<EFBFBD>Ĵ<EFBFBD>ӡ
printf("warning try %d times: date not enough,try again!!\n",i);
}
// size_t retunnumber = GetInfoBackFromSensor(GET_DATA_FROM_SENSOR);
return OVERTIME;
}
size_t SendGetSensorInfo(u_char Command, size_t lenth)
{
uint8_t dataforsend=NONE_DATA;
int lenthforwrite= IRIS_Protocol_Pack(Command,(uint16_t)01,&dataforsend,(uint8_t *)BufferFortempWrite);
//delay(200);
SerialWrite(BufferFortempWrite, lenthforwrite);
size_t retunnumber = GetInfoBackFromSensor(Command);
return retunnumber;
}
size_t GetSetBackFromSensor()
{
return 0;
}
size_t GetInfoBackFromSensor(uint8_t Command) // big <20><>ָ<EFBFBD>ü<EFBFBD><C3BC><EFBFBD><EFBFBD>ֽڱ<D6BD>ʾ<EFBFBD><CABE><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD> <20><>ʱֻ<CAB1><D6BB><EFBFBD>ֲɼ<D6B2><C9BC><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
{
delay(1);
TotalIndexNow = 0;
BufferForRead[0] = 0x00;
memset(BufferForRead, 0, 200);
size_t retrunlenth=SerailRead(BufferForRead + TotalIndexNow, 2);
TotalIndexNow += retrunlenth;
// TotalIndexNow=IRIS_Cut_Befor_Header(BufferForRead,TotalIndexNow);
while (TotalIndexNow<5) {
size_t retrunlenth=SerailRead(BufferForRead + TotalIndexNow, 5-TotalIndexNow);
TotalIndexNow += retrunlenth;
// if (retrunlenth!=0) {
// //<2F><><EFBFBD>bufferforread
// for (int i = 0; i < TotalIndexNow; i++) {
// printf("%02x ", BufferForRead[i]);
// }
// printf("here3 %d\n",retrunlenth);
// fflush(stdout);
// }
TotalIndexNow=IRIS_Cut_Befor_Header(BufferForRead,TotalIndexNow);
// if (retrunlenth!=10) {
// delay(1000);
// }
}
int lenth = BufferForRead[3] * 256 + BufferForRead[4];
while (TotalIndexNow < lenth + 7)
{
int sizeread=SerailRead(BufferForRead + TotalIndexNow, 10);
//printf("Data from sensor: %d\n",sizeread);
TotalIndexNow +=sizeread;
if (sizeread!=10) {
//delay(10);
}
//delay(10);
//delay(10);
}
// <20><><EFBFBD>bufferforread
printf("Data from sensor: ");
int maxoutput= TotalIndexNow>50 ? 50 : TotalIndexNow;
for (int i = 0; i <maxoutput; i++) {
printf("%02x ", BufferForRead[i]);
}
printf("\n");
TotalIndexNow= IRIS_Protocol_Unpack(BufferForRead,TotalIndexNow,Command,BufferForRead);
return TotalIndexNow;
}
#include <chrono>
size_t GetInfoBackFromSensorinTime(uint8_t Command,uint32_t waittime) // big <20><>ָ<EFBFBD>ü<EFBFBD><C3BC><EFBFBD><EFBFBD>ֽڱ<D6BD>ʾ<EFBFBD><CABE><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD> <20><>ʱֻ<CAB1><D6BB><EFBFBD>ֲɼ<D6B2><C9BC><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
{
// delay(1);
//<2F><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
size_t begintime= get_system_uptime_ms();
TotalIndexNow = 0;
BufferForRead[0] = 0x00;
memset(BufferForRead, 0, 200);
size_t retrunlenth=SerailRead(BufferForRead + TotalIndexNow, 2);
TotalIndexNow += retrunlenth;
// TotalIndexNow=IRIS_Cut_Befor_Header(BufferForRead,TotalIndexNow);
while (TotalIndexNow<5) {
size_t retrunlenth=SerailRead(BufferForRead + TotalIndexNow, 5-TotalIndexNow);
TotalIndexNow += retrunlenth;
// if (retrunlenth!=0) {
// //<2F><><EFBFBD>bufferforread
// for (int i = 0; i < TotalIndexNow; i++) {
// printf("%02x ", BufferForRead[i]);
// }
// printf("here3 %d\n",retrunlenth);
// fflush(stdout);
// }
TotalIndexNow=IRIS_Cut_Befor_Header(BufferForRead,TotalIndexNow);
if (get_system_uptime_ms()-begintime>waittime) return OVERTIME;
// if (retrunlenth!=10) {
// delay(1000);
// }
}
if (BufferForRead[2]==0x40) {
printf("warning: sensor busy\n");
return SENSORBUSY;
}
int lenth = BufferForRead[3] * 256 + BufferForRead[4];
while (TotalIndexNow < lenth + 7)
{
int sizeread=SerailRead(BufferForRead + TotalIndexNow, 10);
//printf("Data from sensor: %d\n",sizeread);
TotalIndexNow +=sizeread;
if (sizeread!=10) {
//delay(10);
}
if (get_system_uptime_ms()-begintime>waittime) return OVERTIME;
//delay(10);
//delay(10);
}
// <20><><EFBFBD>bufferforread
printf("Data from sensor: ");
int maxoutput= TotalIndexNow>50 ? 50 : TotalIndexNow;
for (int i = 0; i <maxoutput; i++) {
printf("%02x ", BufferForRead[i]);
}
printf("\n");
TotalIndexNow= IRIS_Protocol_Unpack(BufferForRead,TotalIndexNow,Command,BufferForRead);
return TotalIndexNow;
}
size_t SerialWrite(u_char *data, size_t lenth)
{
if (MySerialWrite != nullptr)
{
// Serial.println("init ok");
return MySerialWrite(data, lenth);
}
return 0;
}
size_t SerailRead(u_char *data, size_t lenth)
{
if (MySerialRead != nullptr)
{
size_t aa= MySerialRead(data, lenth);
return aa;
}
return 0;
}
void InitFunction(SERIALWRITE a, SERIALWRITE readfunc)
{
MySerialWrite = a;
MySerialRead = readfunc;
//std::string temp = "01";
//a((u_char *)temp.c_str(), 2);
isIS3Init = true;
}
u_char *GetDataBufferPTR()
{
return BufferForRead;
}
bool isSensorInit()
{
return isIS3Init;
}
void CoverLittleAndBig(char *data, int lenth)
{
char *tempdata = new char[lenth];
memcpy(tempdata, data, lenth);
for (size_t i = 0; i < lenth / 2; i++)
{
data[2 * i] = tempdata[2 * i + 1];
data[2 * i + 1] = tempdata[2 * i];
/* code */
}
delete[] tempdata;
}
void CoverLittleandBigbyNumber(void *data, int lenth)
{
char *tempdata = new char[lenth];
memcpy(tempdata, data, lenth);
for (size_t i = 0; i < lenth ; i++) {
((char *)data)[i] = tempdata[lenth-1-i];
}
delete[] tempdata;
}

View File

@ -0,0 +1,145 @@
/**
* @brief is11<31><31><EFBFBD>صײ㺯<D7B2><E3BAAF>
*
*/
#ifndef __IS11COMON_H__
#define __IS11COMON_H__
#ifndef IS11COMMON_H
#define IS11COMMON_H
#include <stdint.h>
#include <stddef.h>
#include <string>
#ifdef __cplusplus
#endif
#define COMMAND_GET 0x03
#define COMMAND_SET 0x06
#define COMMAND_MULTSET 0x10
#define POLYNOMIAL 0xa001 //modbus crc
#define OVERTIME 1000000000
#define SENSORBUSY 1000000000
#include "comon.h"
const u_char GET_ADDRESS[]={0x01,0x03,0x00,0x01,0x00,0x01};
const u_char GET_BANDRATE[]={0x01,0x03,0x00,0x02,0x00,0x01};
const u_char GET_INTEGRAL_TIME[]={0x01,0x03,0x00,0x06,0x00,0x01};
const u_char GET_AVERAGE_NUMBER[]={0x01,0x03,0x00,0x07,0x00,0x01};
const u_char GET_WAVELENTH_AT_BAND[]={0x01, 0x03, 0x00,0x10, 0x00,0x02};
const u_char GET_VALUE_AT_BAND[]={0x01, 0x03, 0x00,0x30, 0x00,0x02};
const u_char GET_SETTING_OF_LAMP[]={0x01, 0x03, 0x00,0x04, 0x00,0x01};
// const u_char GET_WAVELENTH_COEFF[]={0x01, 0x03, 0x00,0x20, 0x00,0x08};
const u_char GET_ALL_DN[]={0x01, 0x03, 0x01,0x00, 0x10,0x00};
const u_char GET_SERIAL_NUMBER[]={0x01, 0x03, 0x00,0x40, 0x00,0x00};
const u_char GET_PRODUCT_NAME[]={0x01, 0x03, 0x00,0x50, 0x00,0x00};
const u_char SET_ADDRESS[]={0x01,0x06, 0x00,0x01};
const u_char SET_BandRATE[]={0x01,0x06, 0x00,0x02};
const u_char SET_INTEGRAL_TIME[]={0x01,0x06, 0x00,0x06};
const u_char SET_AVERAGE_NUMBER[]={0x01,0x06, 0x00,0x07};
const u_char SET_WORK_MODE[]={0x01,0x06, 0x00,0x01};
const u_char SET_WAVELENTH_COEFF[]={0x01,0x10,0x00,0x20,0x00,0x08,0x16};
/**
* @brief <20>жϴ<D0B6><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @return true
* @return false
*/
bool isSensorInit();
/**
* @brief <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @param writefunc д<><D0B4><EFBFBD><EFBFBD>
* @param readfunc <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void InitFunction(SERIALWRITE writefunc,SERIALWRITE readfunc);
/**
* @brief <20><>ȡ BufferForRead <20><>ָ<EFBFBD><D6B8> <20><><EFBFBD>ڶ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>
*
*/
u_char * GetDataBufferPTR();
/**
* @brief <20><><EFBFBD>ͻ<EFBFBD>ȡ<EFBFBD><EFBFBD><E8B1B8>Ϣ<EFBFBD><CFA2>ָ<EFBFBD><D6B8> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Getָ<74><D6B8>
*
* @param Command ָ<><D6B8> Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param lenth ָ<><EFBFBD><EEB3A4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sizeof<6F><66><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return size_t <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵij<DDB5><C4B3><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BufferForRead;
*/
size_t SendGetSensorInfo(u_char Command,size_t lenth);//<2F>˹<EFBFBD><CBB9>̲<EFBFBD><CCB2>ʺϻ<CABA>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
/**
* @brief
*
* @param shutter
* @return size_t
*/
size_t SendGetData(int shutter);
/**
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
*
* @param Command ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param CommandLenth ָ<><EFBFBD><EEB3A4>
* @param Value <20><><EFBFBD><EFBFBD>ֵ
* @param ValueLenth ֵ<><D6B5><EFBFBD><EFBFBD> Ĭ<><C4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
* @return size_t <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>
*/
size_t SendSettingCommand(u_char Command,size_t CommandLenth,u_char *Value,size_t ValueLenth=2);
//big
/**
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>Ϣ<EFBFBD>ķ<EFBFBD><C4B7>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>
*
* @param isbig <20><>ָ<EFBFBD>ü<EFBFBD><C3BC><EFBFBD><EFBFBD>ֽڱ<D6BD>ʾ<EFBFBD><CABE><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD> <20><>ʱֻ<CAB1><D6BB><EFBFBD>ֲɼ<D6B2><C9BC><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
* @return size_t <20><><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD>С
*/
size_t GetInfoBackFromSensor(uint8_t Command);
/**
* @brief <20><>ȡ<EFBFBD><C8A1><EFBFBD>ú󷵻<C3BA><F3B7B5BB><EFBFBD><EFBFBD><EFBFBD>
*
* @return size_t <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>;
*/
size_t GetSetBackFromSensor();
/**
* @brief
*
* @param data
* @param lenth
* @return size_t
*/
size_t SerialWrite(u_char* data,size_t lenth);
size_t SerailRead(u_char* data,size_t lenth=0);
/**
* @brief <20><><EFBFBD><EFBFBD>crc16
*
* @param data <20><><EFBFBD><EFBFBD>
* @param len <20><><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
* @param polynomial crc16<31><36><EFBFBD><EFBFBD>ʽ Ĭ<><C4AC><EFBFBD><EFBFBD>A001H
* @return uint16_t crc16<31><36>ֵ
*/
uint16_t crc16(const uint8_t *data, size_t len, uint16_t polynomial=POLYNOMIAL) ;
/**
*
* @param Command
* @param waittime <20><><EFBFBD><EFBFBD>
* @return
*/
size_t GetInfoBackFromSensorinTime(uint8_t Command,uint32_t waittime=5000);
void CoverLittleAndBig(char *data,int lenth);
void CoverLittleandBigbyNumber(void *data, int lenth);
#ifdef __cplusplus
#endif
#endif
#endif // __IS11COMON_H__

View File

@ -0,0 +1,84 @@
/**
******************************************************************************
* @file : IS11_INST.cpp
* @author : xin
* @brief : None
* @attention : None
* @date : 2024/8/14
******************************************************************************
*/
//
// Created by xin on 2024/8/14.
//
#include "SensorIS3.h"
#include "IS3_INST.h"
#include "iostream"
#include "cstring"
#include <string> // 如果 sensorinfo.SensorName 是 std::string 类型
#include <cstdio> // 对于 snprintf
SensorIS3 *thissensorIS3;
int IS3SensorInit()
{
std::cout<< "IS3SensorInit" << std::endl;
thissensorIS3 = new SensorIS3();
thissensorIS3->initSensor(1);
return 1;
}
void IS3Set_Serial_FUN(SERIALWRITE writefunc,SERIALWRITE readfunc)
{
InitFunction(writefunc,readfunc);
}
STRsensorinfo_C IS3Get_SensorInfo() {
STRSensorInfo sensorinfo= thissensorIS3->SensorInfo;
STRsensorinfo_C sensorinfo_c;
//把sensorname 拷贝到sensorinfo_c
snprintf(sensorinfo_c.SensorName, sizeof(sensorinfo_c.SensorName), "%s", sensorinfo.SensorName.c_str());
// strcpy_s(sensorinfo_c.SensorName,sensorinfo.SensorName.c_str());
sensorinfo_c.BandNum = sensorinfo.BandNum;
sensorinfo_c.maxValue = sensorinfo.maxValue;
//strcpy_s(sensorinfo_c.serialnumber,sensorinfo.serialnumber.c_str());
snprintf(sensorinfo_c.serialnumber, sizeof(sensorinfo_c.serialnumber), "%s", sensorinfo.serialnumber.c_str());
sensorinfo_c.a1 = sensorinfo.a1;
sensorinfo_c.a2 = sensorinfo.a2;
sensorinfo_c.a3 = sensorinfo.a3;
sensorinfo_c.a4 = sensorinfo.a4;
sensorinfo_c.issensorinit= sensorinfo.isSensorInit;
return sensorinfo_c;
}
int IS3OptSnenser(int percent) {
return thissensorIS3->OptSnenser(percent);
}
int IS3GetData(uint16_t *outdata, int shuttertime) {
thissensorIS3->GetOneDate(shuttertime);
memcpy(outdata,thissensorIS3->DATABUFF, sizeof(int16_t)*thissensorIS3->SensorInfo.BandNum);
float averageofdrift=(thissensorIS3->DATABUFF[thissensorIS3->SensorInfo.BandNum-1]+thissensorIS3->DATABUFF[thissensorIS3->SensorInfo.BandNum-0]+thissensorIS3->DATABUFF[thissensorIS3->SensorInfo.BandNum+1])/3;
// for(int i=0;i<thissensorIS3->SensorInfo.BandNum;i++)
// {
// outdata[i]-=averageofdrift;
// if (outdata[i]<0)
// outdata[i]=0;
// }
return thissensorIS3->SensorInfo.BandNum;
}
int IS3SetWeaveLenthCoeff(double *a,int lenth) {
// printf("IS3SetWeaveLenthCoeff\n");
// printf("lenth=%d\n",lenth);
// printf("a[0]=%f\n",a[0]);
thissensorIS3->SetWeaveLenthCoeff(a,lenth);
return 1;
}
void IS3SetShutterOpen(int isopen) {
thissensorIS3->SetShutter(isopen);
// printf("IS3SetShutterOpen\n");
// printf("isopen=%d\n",isopen);
}

View File

@ -0,0 +1,40 @@
/**
******************************************************************************
* @file : IS3_INST.h
* @author : xin
* @brief : None
* @attention : None
* @date : 2024/8/14
******************************************************************************
*/
//
// Created by xin on 2024/8/14.
//
#ifndef IS3LIB_IS3_INST_H
#define IS3LIB_IS3_INST_H
#include "comon.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _WIN32
#define WINDOWSEXPORT __declspec(dllexport) // Windows下导出函数
#else
#define WINDOWSEXPORT // Linux下导出函数
#endif
WINDOWSEXPORT int IS3SensorInit();
WINDOWSEXPORT void IS3Set_Serial_FUN(SERIALWRITE writefunc,SERIALWRITE readfunc);
WINDOWSEXPORT STRsensorinfo_C IS3Get_SensorInfo();
WINDOWSEXPORT int IS3OptSnenser(int percent);
WINDOWSEXPORT int IS3GetData(uint16_t *outdata,int shuttertime);
WINDOWSEXPORT int IS3SetWeaveLenthCoeff(double *a,int lenth);
WINDOWSEXPORT void IS3SetShutterOpen(int isopen);
#ifdef __cplusplus
}
#endif
#endif //IS3LIB_IS3_INST_H

View File

@ -0,0 +1,382 @@
#include"SensorIS3.h"
#include <Communication_Protocol.h>
#include "iostream"
#include "IRIS_Method.h"
#include <cstring>
static void split(const std::string& s, std::vector<std::string>& sv, char flag)
{
sv.clear();
std::istringstream iss(s);
std::string temp;
while (getline(iss, temp, flag)) {
sv.push_back(temp);
}
return;
}
bool SensorIS3::initSensor(int id)
{
DataRetrun=GetDataBufferPTR();
// IS1Sensor.SetPortName(id);
SensorInfo=GetSensorInfo();
// pinMode(22,OUTPUT);
// pinMode(23,OUTPUT);
return true;
}
STRSensorInfo SensorIS3::GetSensorInfo()
{
STRSensorInfo setem;
if (!isSensorInit())
{
return setem;
}
int retlenth= SendGetSensorInfo(GET_BASIC_INFO,sizeof(GET_BASIC_INFO));
char * result=new char[100];
memcpy(result,DataRetrun,retlenth);
result[retlenth]='\0';
std::cout<<result<<std::endl;
std::string str11(result);
std::vector<std::string> strvec;
split(str11,strvec,'-');
setem.SensorName=strvec[0];
if (strvec.size()>=2) {
setem.serialnumber=strvec[1];
}
delete[] result;
retlenth= SendGetSensorInfo(GET_BANDNUMBER,sizeof(GET_BASIC_INFO));
int bandnumber=0;
memcpy(&bandnumber,DataRetrun,retlenth);
CoverLittleandBigbyNumber(&bandnumber,4);
setem.BandNum=bandnumber;
setem.maxValue=65535;
setem.wavelenthlist=new float[setem.BandNum]();
retlenth= SendGetSensorInfo(GET_WEAVE_COEFF,sizeof(GET_WEAVE_COEFF));
double a[4];
char tempaa[100];
memcpy(tempaa,DataRetrun,100);
int lenthtemp=sizeof(double);
memcpy(a,DataRetrun,4*sizeof(double));
CoverLittleandBigbyNumber(a,sizeof(double));
CoverLittleandBigbyNumber(a+1,sizeof(double));
CoverLittleandBigbyNumber(a+2,sizeof(double));
CoverLittleandBigbyNumber(a+3,sizeof(double));
// a[0]=0;
// a[1]=0;
// a[2]=1;
// a[3]=350;
// CoverLittleAndBig((char *)a,4*sizeof(float));
int bandsss= setem.BandNum;
#ifdef ARDUINO
Serial.print("a0:");
Serial.print(a[0]);
Serial.print(" a1:");
Serial.print(a[1]);
Serial.print(" a2:");
Serial.print(a[2]);
Serial.print(" a3:");
Serial.println(a[3]);
#endif
std::cout<<"a0:"<<a[0]<<" a1:"<<a[1]<<" a2:"<<a[2]<<" a3:"<<a[3]<<std::endl;
setem.a1=a[0];
setem.a2=a[1];
setem.a3=a[2];
setem.a4=a[3];
for ( int i = 1; i <=bandsss ; i++)
{
setem.wavelenthlist[i-1] = a[0] * i*i*i + a[1] * i*i + a[2] * i + a[3];
setem.WavelenthStr=setem.WavelenthStr+std::to_string( setem.wavelenthlist[i-1])+",";
}
// delay(500);
// Serial.write(dataretrun,retlenth);
// memcpy(a,dataretrun+)
u_char temp[2]={0x00,0x01};
// retlenth=SendSettingCommand((u_char*)SET_AVERAGE_NUMBER,sizeof(SET_AVERAGE_NUMBER),temp,sizeof(temp));
// Serial.println("init ok");
return setem;
}
void SensorIS3::SetShutter(int id)
{
#ifdef ARDUINO
switch (id) {
case 0:
{
digitalWrite(22,LOW);
digitalWrite(23,LOW);
delay(200);
break;
}
case 1:{
digitalWrite(23,HIGH);
digitalWrite(22,LOW);
delay(200);
break;
}
case 2:{
digitalWrite(22,HIGH);
digitalWrite(23,LOW);
delay(200);
break;
}
}
#else
switch (id) {
case 0: {
u_char a=1;
SendSettingCommand(SET_SHUTTER_CLOSE,1, &a, 1);
break;
}
case 1: {
u_char a=1;
//SendSettingCommand(SET_SHUTTER_CLOSE,1, &a, 1);
SendSettingCommand(SET_SHUTTER_OPEN,1, &a, 1);
break;
}
}
#endif
}
void SensorIS3::SetWeaveLenthCoeff(double *a, int lenth) {
u_char *datetosend=new u_char[lenth*sizeof(double)];
printf("c++:a0:%f a1:%f a2:%f a3:%f\n",a[0],a[1],a[2],a[3]);
CoverLittleandBigbyNumber(a,sizeof(double));
CoverLittleandBigbyNumber(a+1,sizeof(double));
CoverLittleandBigbyNumber(a+2,sizeof(double));
CoverLittleandBigbyNumber(a+3,sizeof(double));
memcpy(datetosend,a,lenth*sizeof(double));
SendSettingCommand(SET_WEAVE_COEFF,1,datetosend,lenth*sizeof(double));
delete[] datetosend;
// GetSensorInfo();
}
void SensorIS3::GetOneDate(int msc)
{
if (msc!=shutternow)
{
u_char shutter[4];
memcpy(shutter,&msc,4);
//交换下shutter 前后
u_char shutterlitte[4];
shutterlitte[0]=shutter[3];
shutterlitte[1]=shutter[2];
shutterlitte[2]=shutter[1];
shutterlitte[3]=shutter[0];
int ret= SendSettingCommand(SET_INTEGRAL_TIME,1,shutterlitte,sizeof(shutterlitte));
}
shutternow=msc;
size_t retsize= SendGetData(shutternow);
memcpy(DATABUFF,DataRetrun,515*2);
//shortLittletoBiG(DATABUFF, SensorInfo.BandNum*2);
}
int SensorIS3::OptSnenser(int persent)
{
long minshuttertime=12;
long maxtime = 10000;
int maxvalue=SensorInfo.maxValue*1.0*persent / 100;
int maxvaluenow = 0;
float shutternow = 20;
GetOneDate(shutternow);
maxvaluenow= Getmaxvalue(DATABUFF, SensorInfo.BandNum);
int numberoftry = 0;
while (maxvaluenow<maxvalue*0.95 || maxvaluenow>maxvalue) {
if (maxvaluenow > maxvalue)
{
shutternow = shutternow *0.7;
}
else if (maxvaluenow==0)
{
shutternow =shutternow*10;
}
else
{
shutternow = maxvalue * 0.98 / (maxvaluenow * 1.0)*shutternow + 1;
}
if (shutternow > maxtime)
{
shutternow = maxtime;
break;
}
if (shutternow < minshuttertime)
{
shutternow = minshuttertime;
break;
}
GetOneDate(shutternow);
maxvaluenow= Getmaxvalue(DATABUFF, SensorInfo.BandNum);
#ifdef ARDUINO
Serial.print("now Shutter is :");
Serial.print(shutternow);
Serial.print(" maxvalue is :");
Serial.println(maxvaluenow);
#else
std::cout<<"now Shutter is :"<<shutternow<<" maxvalue is :"<<maxvaluenow<<std::endl;
#endif
numberoftry++;
if (numberoftry > 200)
{
return maxtime;
}
if (shutternow == maxtime)
{
return maxtime;
}
}
#ifdef ARDUINO
Serial.print("zi dong value:");
Serial.println(shutternow);
#endif
if (shutternow<0)
{
shutternow=maxtime;
/* code */
}
return shutternow;
}
void SensorIS3::shortLittletoBiG(unsigned short *data,int lenth)
{
CoverLittleAndBig((char *)data,lenth);
}
int SensorIS3::Getmaxvalue(unsigned short *data,int lenth)
{
int ret=-1;
for (int i = 0; i < lenth; ++i) {
if (data[i]>ret){
ret=data[i];
}
}
return ret;
}
void SensorIS3::TakeOneJob()
{
SetShutter(1);
int shutter=OptSnenser(90);
shutterup=shutter;
GetOneDate(shutter);
// Serial.println("Finish Up ------Green2313123");
if (UpData==nullptr)
{
UpData=new unsigned short[SensorInfo.BandNum*2];
/* code */
}
memcpy(UpData,DATABUFF,SensorInfo.BandNum*2);
SetShutter(0);
GetOneDate(shutter);
for (int i = 0; i < SensorInfo.BandNum; ++i) {
// UpData[i]=UpData[i]-DATABUFF[i];
}
shutterup=shutter;
bool dingbing=false;
#ifdef DINBIAO
String strout="1 shutteruo is "+String(shutterup)+" Finish Up ------Green change the fiber";
PrintFunc(strout );
digitalWrite(21, LOW);
delay(60000);
SensorInfo.SensorName=SensorInfo.SensorName+"cali";
Serial.println("begindown");
digitalWrite(21, HIGH);
#endif
SetShutter(2);
shutter=OptSnenser(90);
shutterdown=shutter;
GetOneDate(shutter);
if (DownData==nullptr)
{
DownData=new unsigned short[SensorInfo.BandNum*2];
/* code */
}
memcpy(DownData,DATABUFF,SensorInfo.BandNum*2);
SetShutter(0);
GetOneDate(shutter);
for (int i = 0; i < SensorInfo.BandNum; ++i) {
// DownData[i]=DownData[i]-DATABUFF[i];
}
shutterdown=shutter;
#ifdef DINBIAO
String strout1="2 shutterdown is "+String(shutterdown)+" Down Finish ------Blue";
PrintFunc(strout1 );
#endif
}
SensorIS3::SensorIS3()
{
shutternow=0;
// DataRetrun=GetDataBufferPTR();
}

View File

@ -0,0 +1,44 @@
#ifndef SENSORIS3_H
#define SENSORIS3_H
#include "comon.h"
#include "IS3Comon.h"
class SensorIS3 {
public:
SensorIS3();
STRSensorInfo SensorInfo;
bool initSensor(int id = 2);
STRSensorInfo GetSensorInfo();
void SetShutter(int id);// 0 dark 1 green 2 blue
void SetWeaveLenthCoeff(double *a,int lenth);
void GetOneDate(int msc);
int OptSnenser(int percent);
unsigned short DATABUFF[2048];
int shutterup,shutterdown;
unsigned short *DownData=nullptr;
unsigned short *UpData=nullptr;
void shortLittletoBiG( unsigned short *data,int lenth);
int Getmaxvalue(unsigned short *data,int lenth);
void TakeOneJob();
PRINTFUNC PrintFunc;
int shutternow;
//uint16_t result[2048];
u_char *DataRetrun;
};
#endif

44
myis11/src/comman/comon.h Normal file
View File

@ -0,0 +1,44 @@
#pragma once
#include <string>
#include <vector>
#include <sstream>
typedef unsigned char u_char;
/**
* @brief 串口写函数类型
*
*/
typedef size_t (*SERIALWRITE)(u_char* data,size_t lenth);
/**
* @brief 串口读函数原型
*
*/
typedef size_t (*SERIALREAD)(u_char* data,size_t lenth);
struct STRSensorInfo
{
std::string SensorName;
long maxValue;
long BandNum;
std::string WavelenthStr;
float *wavelenthlist;
//double *wavelenth;
bool isSensorInit;
std::string serialnumber;
float a1,a2,a3,a4;
};
struct STRsensorinfo_C
{
char SensorName[100];
long maxValue;
long BandNum;
char serialnumber[100];
float a1,a2,a3,a4;
u_char issensorinit;
};
typedef void (*PRINTFUNC)(std::string );

View File

@ -0,0 +1,243 @@
#include "IS11Comon.h"
#ifdef _WIN32
#include <windows.h>
void delay(int ms){
Sleep(ms);
}
#else
#include <unistd.h> // For usleep
void delay(int ms){
usleep(ms * 1000); // Convert milliseconds to microseconds
}
#include <unistd.h>
#include <cstring>
#endif
u_char BufferForRead[10000];
int TotalIndexNow = 0;
u_char BufferFortempWrite[1000];
// MySerialWrite=nullptr;
SERIALWRITE MySerialWrite = nullptr;
SERIALREAD MySerialRead = nullptr;
bool isIS3Init = false;
uint16_t crc16(const uint8_t *data, size_t len, uint16_t polynomial)
{
uint16_t i, j, tmp, CRC16;
CRC16 = 0xFFFF; // CRC寄存器初始值
for (i = 0; i < len; i++)
{
CRC16 ^= data[i];
for (j = 0; j < 8; j++)
{
tmp = (uint16_t)(CRC16 & 0x0001);
CRC16 >>= 1;
if (tmp == 1)
{
CRC16 ^= polynomial; // 异或多项式
}
}
}
return CRC16;
}
size_t SendSettingCommand(u_char *Command, size_t CommandLenth, u_char *Value, size_t ValueLenth)
{
memcpy(BufferFortempWrite, Command, CommandLenth);
memcpy(BufferFortempWrite + CommandLenth, Value, ValueLenth);
uint16_t crc = crc16(BufferFortempWrite, CommandLenth + ValueLenth);
memcpy(BufferFortempWrite + CommandLenth + ValueLenth, &crc, 2);
SerialWrite(BufferFortempWrite, CommandLenth + ValueLenth + 2);
// Serial.write(BufferFortempWrite, CommandLenth+ValueLenth + 2);
return GetSetBackFromSensor();
}
size_t SendGetData(int shutter)
{
int lenth = sizeof(GET_ALL_DN);
uint16_t crc = crc16(GET_ALL_DN, lenth);
memcpy(BufferFortempWrite, GET_ALL_DN, lenth);
memcpy(BufferFortempWrite + lenth, &crc, 2);
SerialWrite(BufferFortempWrite, lenth + 2);
// Serial.write(BufferFortempWrite, lenth + 2);
// Serial.println(shutter);
delay(shutter);
return GetInfoBackFromSensor(true);
}
size_t SendGetSensorInfo(u_char *Command, size_t lenth)
{
uint16_t crc = crc16(Command, lenth);
memcpy(BufferFortempWrite, Command, lenth);
memcpy(BufferFortempWrite + lenth, &crc, 2);
// Serial.println((int)MySerialWrite);
// Serial.write(BufferFortempWrite,lenth+2);
//delay(200);
SerialWrite(BufferFortempWrite, lenth + 2);
size_t retunnumber = GetInfoBackFromSensor();
return retunnumber;
}
size_t GetSetBackFromSensor()
{
TotalIndexNow = 0;
TotalIndexNow += (int)SerailRead(BufferForRead + TotalIndexNow, 1);
while (TotalIndexNow < 8)
{
// Serial.println(TotalIndexNow);
// Serial.write(BufferForRead,1);
TotalIndexNow += (int)SerailRead(BufferForRead + TotalIndexNow, 1);
}
return TotalIndexNow;
}
bool panduanHeader()
{
if (TotalIndexNow < 2)
{
return false;
/* code */
}
int temp = 0;
while (BufferForRead[temp] != 0x01 &&
!(BufferForRead[temp + 1] == 0x03 || BufferForRead[temp + 1] == 0x06 || BufferForRead[temp + 1] == 0x10))
{
if (temp >= TotalIndexNow - 2)
{
break;
/* code */
}
temp++;
/* code */
}
memcpy(BufferForRead, BufferForRead + temp, TotalIndexNow - temp);
TotalIndexNow = TotalIndexNow - temp;
temp = 0;
if (BufferForRead[temp] != 0x01 &&
!(BufferForRead[temp + 1] == 0x03 || BufferForRead[temp + 1] == 0x06 || BufferForRead[temp + 1] == 0x10))
{
return false;
}
return true;
}
size_t GetInfoBackFromSensor(bool isbig) // big 是指用几个字节表示数据长度 暂时只发现采集数据时用两个字节
{
if (isbig)
{
// 长度用两个字节表示
// Serial.println(shutter);
// Serial.println("i am here12312312312312312");
TotalIndexNow = 0;
BufferForRead[0] = 0x00;
TotalIndexNow +=(int) SerailRead(BufferForRead + TotalIndexNow, 2);
// while(BufferForRead)
while (!panduanHeader())
{
TotalIndexNow +=(int) SerailRead(BufferForRead + TotalIndexNow, 1);
}
while (TotalIndexNow < 4)
{
// Serial.write(BufferForRead,TotalIndexNow);
//delay(20);
// Serial.println("i am here12312312312312312");
TotalIndexNow += (int)SerailRead(BufferForRead + TotalIndexNow, 1);
}
int lenth = BufferForRead[2] * 256 + BufferForRead[3];
while (TotalIndexNow < lenth + 4)
{
// delay(20);
// Serial.write(BufferForRead,TotalIndexNow);
// Serial.println(lenth);
// Serial.println(TotalIndexNow);
// Serial.println("i am here12312312312312312");
TotalIndexNow +=(int) SerailRead(BufferForRead + TotalIndexNow, 1024);
}
return TotalIndexNow;
}
else
{
// 长度用一个字节表示
TotalIndexNow = 0;
TotalIndexNow += (int)SerailRead(BufferForRead + TotalIndexNow, 1);
while (TotalIndexNow < 3)
{
TotalIndexNow += (int)SerailRead(BufferForRead + TotalIndexNow, 1);
}
int lenth = BufferForRead[2];
while (TotalIndexNow < lenth + 5)
{
TotalIndexNow += (int)SerailRead(BufferForRead + TotalIndexNow, 1);
}
// Serial.write(BufferForRead,TotalIndexNow);
return TotalIndexNow;
}
}
size_t SerialWrite(u_char *data, size_t lenth)
{
if (MySerialWrite != nullptr)
{
// Serial.println("init ok");
return MySerialWrite(data, lenth);
}
return 0;
}
size_t SerailRead(u_char *data, size_t lenth)
{
if (MySerialRead != nullptr)
{
return MySerialRead(data, lenth);
}
return 0;
}
void InitFunction(SERIALWRITE a, SERIALWRITE readfunc)
{
MySerialWrite = a;
MySerialRead = readfunc;
//std::string temp = "01";
//a((u_char *)temp.c_str(), 2);
isIS3Init = true;
}
u_char *GetDataBufferPTR()
{
return BufferForRead;
}
bool isSensorInit()
{
return isIS3Init;
}
void CoverLittleAndBig(char *data, int lenth)
{
char *tempdata = new char[lenth];
memcpy(tempdata, data, lenth);
for (size_t i = 0; i < lenth / 2; i++)
{
data[2 * i] = tempdata[2 * i + 1];
data[2 * i + 1] = tempdata[2 * i];
/* code */
}
delete[] tempdata;
}

137
myis11/src/is11/IS11Comon.h Normal file
View File

@ -0,0 +1,137 @@
/**
* @brief is11相关底层函数
*
*/
#ifndef __IS11COMON_H__
#define __IS11COMON_H__
#ifndef IS11COMMON_H
#define IS11COMMON_H
#include <stdint.h>
#include <stddef.h>
#include <string>
#ifdef __cplusplus
#include "comon.h"
extern "C" {
#endif
#define COMMAND_GET 0x03
#define COMMAND_SET 0x06
#define COMMAND_MULTSET 0x10
#define POLYNOMIAL 0xa001 //modbus crc
const u_char GET_ADDRESS[]={0x01,0x03,0x00,0x01,0x00,0x01};
const u_char GET_BANDRATE[]={0x01,0x03,0x00,0x02,0x00,0x01};
const u_char GET_INTEGRAL_TIME[]={0x01,0x03,0x00,0x06,0x00,0x01};
const u_char GET_AVERAGE_NUMBER[]={0x01,0x03,0x00,0x07,0x00,0x01};
const u_char GET_WAVELENTH_AT_BAND[]={0x01, 0x03, 0x00,0x10, 0x00,0x02};
const u_char GET_VALUE_AT_BAND[]={0x01, 0x03, 0x00,0x30, 0x00,0x02};
const u_char GET_SETTING_OF_LAMP[]={0x01, 0x03, 0x00,0x04, 0x00,0x01};
const u_char GET_WAVELENTH_COEFF[]={0x01, 0x03, 0x00,0x20, 0x00,0x08};
const u_char GET_ALL_DN[]={0x01, 0x03, 0x01,0x00, 0x10,0x00};
const u_char GET_SERIAL_NUMBER[]={0x01, 0x03, 0x00,0x40, 0x00,0x00};
const u_char GET_PRODUCT_NAME[]={0x01, 0x03, 0x00,0x50, 0x00,0x00};
const u_char SET_ADDRESS[]={0x01,0x06, 0x00,0x01};
const u_char SET_BandRATE[]={0x01,0x06, 0x00,0x02};
const u_char SET_INTEGRAL_TIME[]={0x01,0x06, 0x00,0x06};
const u_char SET_AVERAGE_NUMBER[]={0x01,0x06, 0x00,0x07};
const u_char SET_WORK_MODE[]={0x01,0x06, 0x00,0x01};
const u_char SET_WAVELENTH_COEFF[]={0x01,0x10,0x00,0x20,0x00,0x08,0x16};
/**
* @brief 判断传感器是否初始化完成
*
* @return true
* @return false
*/
bool isSensorInit();
/**
* @brief 初始化传感器
*
* @param writefunc 写函数
* @param readfunc 读函数
*/
void InitFunction(SERIALWRITE writefunc,SERIALWRITE readfunc);
/**
* @brief 获取 BufferForRead 的指针 用于读取返回的数据
*
*/
u_char * GetDataBufferPTR();
/**
* @brief 发送获取设备信息的指令 适用于Get指令
*
* @param Command 指令 预定的数组
* @param lenth 指令长度 可以用sizeof来求算
* @return size_t 返回数据的长度 输出存放于 BufferForRead;
*/
size_t SendGetSensorInfo(u_char * Command,size_t lenth);//此过程不适合获取数据
/**
* @brief
*
* @param shutter
* @return size_t
*/
size_t SendGetData(int shutter);
/**
* @brief 发送设置指令
*
* @param Command 指令内容
* @param CommandLenth 指令长度
* @param Value 设置值
* @param ValueLenth 值长度 默认是两个字节
* @return size_t 返回值长度
*/
size_t SendSettingCommand(u_char * Command,size_t CommandLenth,u_char *Value,size_t ValueLenth=2);
//big
/**
* @brief 用来获取信息的返回的数据
*
* @param isbig 是指用几个字节表示数据长度 暂时只发现采集数据时用两个字节
* @return size_t 接收到的数据大小
*/
size_t GetInfoBackFromSensor(bool isbig=false);
/**
* @brief 获取设置后返回数据
*
* @return size_t 返回数据长度;
*/
size_t GetSetBackFromSensor();
/**
* @brief
*
* @param data
* @param lenth
* @return size_t
*/
size_t SerialWrite(u_char* data,size_t lenth);
size_t SerailRead(u_char* data,size_t lenth=0);
/**
* @brief 计算crc16
*
* @param data 数据
* @param len 数据长度
* @param polynomial crc16多项式 默认是A001H
* @return uint16_t crc16的值
*/
uint16_t crc16(const uint8_t *data, size_t len, uint16_t polynomial=POLYNOMIAL) ;
bool panduanHeader();
void CoverLittleAndBig(char *data,int lenth);
#ifdef __cplusplus
}
#endif
#endif
#endif // __IS11COMON_H__

View File

@ -0,0 +1,62 @@
/**
******************************************************************************
* @file : IS11_INST.cpp
* @author : xin
* @brief : None
* @attention : None
* @date : 2024/8/14
******************************************************************************
*/
//
// Created by xin on 2024/8/14.
//
#include "SensorIS11.h"
#include "IS11_INST.h"
#include "iostream"
#include "cstring"
#include <cstdio> // 对于 snprintf
SensorIS11 *thissensorIS11;
int IS11SensorInit()
{
std::cout<< "IS11SensorInit" << std::endl;
thissensorIS11 = new SensorIS11();
thissensorIS11->initSensor(1);
return 1;
}
void Set_Serial_FUN(SERIALWRITE writefunc,SERIALWRITE readfunc)
{
InitFunction(writefunc,readfunc);
}
STRsensorinfo_C Get_SensorInfo() {
STRSensorInfo sensorinfo= thissensorIS11->SensorInfo;
STRsensorinfo_C sensorinfo_c;
//把sensorname 拷贝到sensorinfo_c
//strcpy_s(sensorinfo_c.SensorName,sensorinfo.SensorName.c_str());
snprintf(sensorinfo_c.SensorName, sizeof(sensorinfo_c.SensorName), "%s", sensorinfo.SensorName.c_str());
sensorinfo_c.BandNum = sensorinfo.BandNum;
sensorinfo_c.maxValue = sensorinfo.maxValue;
//strcpy_s(sensorinfo_c.serialnumber,sensorinfo.serialnumber.c_str());
snprintf(sensorinfo_c.serialnumber, sizeof(sensorinfo_c.serialnumber), "%s", sensorinfo.serialnumber.c_str());
sensorinfo_c.a1 = sensorinfo.a1;
sensorinfo_c.a2 = sensorinfo.a2;
sensorinfo_c.a3 = sensorinfo.a3;
sensorinfo_c.a4 = sensorinfo.a4;
sensorinfo_c.issensorinit= sensorinfo.isSensorInit;
return sensorinfo_c;
}
int IS11OptSnenser(int percent) {
return thissensorIS11->OptSnenser(percent);
}
int IS11GetData(uint16_t *outdata, int shuttertime) {
thissensorIS11->GetOneDate(shuttertime);
memcpy(outdata,thissensorIS11->DATABUFF, sizeof(int16_t)*thissensorIS11->SensorInfo.BandNum);
return thissensorIS11->SensorInfo.BandNum;
}

View File

@ -0,0 +1,39 @@
/**
******************************************************************************
* @file : IS11_INST.h
* @author : xin
* @brief : None
* @attention : None
* @date : 2024/8/14
******************************************************************************
*/
//
// Created by xin on 2024/8/14.
//
#ifndef IS11LIB_IS11_INST_H
#define IS11LIB_IS11_INST_H
#include "comon.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _WIN32
#define WINDOWSEXPORT __declspec(dllexport) // Windows下导出函数
#else
#define WINDOWSEXPORT // Linux下导出函数
#endif
WINDOWSEXPORT int IS11SensorInit();
WINDOWSEXPORT void Set_Serial_FUN(SERIALWRITE writefunc,SERIALWRITE readfunc);
WINDOWSEXPORT STRsensorinfo_C Get_SensorInfo();
WINDOWSEXPORT int IS11OptSnenser(int percent);
WINDOWSEXPORT int IS11GetData(uint16_t *outdata,int shuttertime);
#ifdef __cplusplus
}
#endif
#endif //IS11LIB_IS11_INST_H

View File

@ -0,0 +1,301 @@
#include"SensorIS11.h"
#include "iostream"
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#include <cstring>
#endif
bool SensorIS11::initSensor(int id)
{
DataRetrun=GetDataBufferPTR();
// IS1Sensor.SetPortName(id);
SensorInfo=GetSensorInfo();
// pinMode(22,OUTPUT);
// pinMode(23,OUTPUT);
return true;
}
STRSensorInfo SensorIS11::GetSensorInfo()
{
STRSensorInfo setem;
if (!isSensorInit())
{
return setem;
}
int retlenth= SendGetSensorInfo((u_char *)GET_SERIAL_NUMBER,sizeof(GET_SERIAL_NUMBER));
char * result=new char[5];
memcpy(result,DataRetrun+3,4);
result[4]='\0';
std::cout<<result<<std::endl;
std::string str11(result);
setem.serialnumber=str11;
delete[] result;
//Serial.println(setem.serialnumber);
retlenth= SendGetSensorInfo((u_char *)GET_PRODUCT_NAME,sizeof(GET_PRODUCT_NAME));
result=new char[5];
memcpy(result,DataRetrun+3,4);
// delay(500);
result[4]='\0';
std::string str1(result);
setem.SensorName=str1;
delete result;
setem.BandNum=2048;
setem.maxValue=65535;
setem.wavelenthlist=new float[setem.BandNum]();
retlenth= SendGetSensorInfo((u_char *)GET_WAVELENTH_COEFF,sizeof(GET_WAVELENTH_COEFF));
float a[4];
memcpy(a,DataRetrun+3,16);
CoverLittleAndBig((char *)a,4*sizeof(float));
int bandsss= setem.BandNum;
#ifdef ARDUINO
Serial.print("a0:");
Serial.print(a[0]);
Serial.print(" a1:");
Serial.print(a[1]);
Serial.print(" a2:");
Serial.print(a[2]);
Serial.print(" a3:");
Serial.println(a[3]);
#endif
std::cout<<"a0:"<<a[0]<<" a1:"<<a[1]<<" a2:"<<a[2]<<" a3:"<<a[3]<<std::endl;
setem.a1=a[0];
setem.a2=a[1];
setem.a3=a[2];
setem.a4=a[3];
for ( int i = 1; i <=bandsss ; i++)
{
setem.wavelenthlist[i-1] = a[0] * i*i*i + a[1] * i*i + a[2] * i + a[3];
setem.WavelenthStr=setem.WavelenthStr+std::to_string( setem.wavelenthlist[i-1])+",";
}
// delay(500);
// Serial.write(dataretrun,retlenth);
// memcpy(a,dataretrun+)
u_char temp[2]={0x00,0x01};
retlenth=SendSettingCommand((u_char*)SET_AVERAGE_NUMBER,sizeof(SET_AVERAGE_NUMBER),temp,sizeof(temp));
// Serial.println("init ok");
return setem;
}
void SensorIS11::SetShutter(int id)
{
#ifdef ARDUINO
switch (id) {
case 0:
{
digitalWrite(22,LOW);
digitalWrite(23,LOW);
delay(200);
break;
}
case 1:{
digitalWrite(23,HIGH);
digitalWrite(22,LOW);
delay(200);
break;
}
case 2:{
digitalWrite(22,HIGH);
digitalWrite(23,LOW);
delay(200);
break;
}
}
#endif
}
void SensorIS11::GetOneDate(int msc)
{
if (msc!=shutternow)
{
u_char shutter[2];
shutter[0]=msc/256;
shutter[1]=msc%256;
SendSettingCommand((u_char *) SET_INTEGRAL_TIME,sizeof(SET_INTEGRAL_TIME),shutter,sizeof(shutter));
}
shutternow=msc;
size_t retsize= SendGetData(shutternow);
memcpy(DATABUFF,DataRetrun+4,4096);
shortLittletoBiG(DATABUFF, SensorInfo.BandNum*2);
}
int SensorIS11::OptSnenser(int persent)
{
long maxtime = 20000;
int maxvalue=SensorInfo.maxValue*1.0*persent / 100;
int maxvaluenow = 0;
float shutternow = 10;
GetOneDate(shutternow);
maxvaluenow= Getmaxvalue(DATABUFF, SensorInfo.BandNum);
int numberoftry = 0;
while (maxvaluenow<maxvalue*0.95 || maxvaluenow>maxvalue) {
if (maxvaluenow > maxvalue)
{
shutternow = shutternow *0.7;
}
else
{
shutternow = maxvalue * 0.98 / (maxvaluenow * 1.0)*shutternow + 1;
}
if (shutternow > maxtime)
{
shutternow = maxtime;
break;
}
GetOneDate(shutternow);
maxvaluenow= Getmaxvalue(DATABUFF, SensorInfo.BandNum);
#ifdef ARDUINO
Serial.print("now Shutter is :");
Serial.print(shutternow);
Serial.print(" maxvalue is :");
Serial.println(maxvaluenow);
#else
std::cout<<"now Shutter is :"<<shutternow<<" maxvalue is :"<<maxvaluenow<<std::endl;
#endif
numberoftry++;
if (numberoftry > 200)
{
return maxtime;
}
if (shutternow == maxtime)
{
return maxtime;
}
}
#ifdef ARDUINO
Serial.print("zi dong value:");
Serial.println(shutternow);
#endif
if (shutternow<0)
{
shutternow=maxtime;
/* code */
}
return shutternow;
}
void SensorIS11::shortLittletoBiG(unsigned short *data,int lenth)
{
CoverLittleAndBig((char *)data,lenth);
}
int SensorIS11::Getmaxvalue(unsigned short *data,int lenth)
{
int ret=-1;
for (int i = 0; i < lenth; ++i) {
if (data[i]>ret){
ret=data[i];
}
}
return ret;
}
void SensorIS11::TakeOneJob()
{
SetShutter(1);
int shutter=OptSnenser(90);
shutterup=shutter;
GetOneDate(shutter);
// Serial.println("Finish Up ------Green2313123");
if (UpData==nullptr)
{
UpData=new unsigned short[SensorInfo.BandNum*2];
/* code */
}
memcpy(UpData,DATABUFF,SensorInfo.BandNum*2);
SetShutter(0);
GetOneDate(shutter);
for (int i = 0; i < SensorInfo.BandNum; ++i) {
// UpData[i]=UpData[i]-DATABUFF[i];
}
shutterup=shutter;
bool dingbing=false;
#ifdef DINBIAO
String strout="1 shutteruo is "+String(shutterup)+" Finish Up ------Green change the fiber";
PrintFunc(strout );
digitalWrite(21, LOW);
delay(60000);
SensorInfo.SensorName=SensorInfo.SensorName+"cali";
Serial.println("begindown");
digitalWrite(21, HIGH);
#endif
SetShutter(2);
shutter=OptSnenser(90);
shutterdown=shutter;
GetOneDate(shutter);
if (DownData==nullptr)
{
DownData=new unsigned short[SensorInfo.BandNum*2];
/* code */
}
memcpy(DownData,DATABUFF,SensorInfo.BandNum*2);
SetShutter(0);
GetOneDate(shutter);
for (int i = 0; i < SensorInfo.BandNum; ++i) {
// DownData[i]=DownData[i]-DATABUFF[i];
}
shutterdown=shutter;
#ifdef DINBIAO
String strout1="2 shutterdown is "+String(shutterdown)+" Down Finish ------Blue";
PrintFunc(strout1 );
#endif
}
SensorIS11::SensorIS11()
{
shutternow=0;
// DataRetrun=GetDataBufferPTR();
}

View File

@ -0,0 +1,43 @@
#ifndef SENSORIS11_H
#define SENSORIS11_H
#include "comon.h"
#include "IS11Comon.h"
class SensorIS11 {
public:
SensorIS11();
STRSensorInfo SensorInfo;
bool initSensor(int id = 2);
STRSensorInfo GetSensorInfo();
void SetShutter(int id);// 0 dark 1 green 2 blue
void GetOneDate(int msc);
int OptSnenser(int percent);
unsigned short DATABUFF[2048];
int shutterup,shutterdown;
unsigned short *DownData=nullptr;
unsigned short *UpData=nullptr;
void shortLittletoBiG( unsigned short *data,int lenth);
int Getmaxvalue(unsigned short *data,int lenth);
void TakeOneJob();
PRINTFUNC PrintFunc;
int shutternow;
//uint16_t result[2048];
u_char *DataRetrun;
};
#endif

25
myis11/src/test/test.cpp Normal file
View File

@ -0,0 +1,25 @@
/**
******************************************************************************
* @file : test.cpp
* @author : xin
* @brief : None
* @attention : None
* @date : 2024/8/14
******************************************************************************
*/
//
// Created by xin on 2024/8/14.
//
#include "test.h"
#include "stdio.h"
//void test() {
// printf("hello world sdfsdf12131321321313132\n");
// printf("dsdf\n");
//}
//int isSensorInit() {
//
// return 1;
//}

29
myis11/src/test/test.h Normal file
View File

@ -0,0 +1,29 @@
/**
******************************************************************************
* @file : test.h
* @author : xin
* @brief : None
* @attention : None
* @date : 2024/8/14
******************************************************************************
*/
//
// Created by xin on 2024/8/14.
//
#ifndef MYIS11_TEST_H
#define MYIS11_TEST_H
#include <cstdlib>
#include <cinttypes>
//
//extern "C" __declspec(dllexport) std::int32_t abs1(std::int32_t n) {
// return 100;
//}
//extern "C" {
//
//}
//extern "C" __declspec(dllexport) void test();
#endif //MYIS11_TEST_H

1925
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "vite build", "build": "vite build",
"mybuild": "node -e \"require('child_process').exec('powershell -ExecutionPolicy Bypass -File ./src-tauri/pre-build.ps1')\"",
"preview": "vite preview", "preview": "vite preview",
"tauri": "tauri" "tauri": "tauri"
}, },
@ -20,19 +21,23 @@
"element-plus": "^2.4.4", "element-plus": "^2.4.4",
"json-editor-vue3": "^1.1.1", "json-editor-vue3": "^1.1.1",
"less": "^4.2.0", "less": "^4.2.0",
"maptalks": "^1.1.3",
"markdown-it": "^14.1.0",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"ol": "^10.6.1",
"serialport": "^12.0.0", "serialport": "^12.0.0",
"vue": "^3.3.4", "vue": "^3.3.4",
"vue-drag-resize": "^2.0.3", "vue-drag-resize": "^2.0.3",
"vue-json-viewer": "^3.0.4", "vue-json-viewer": "^3.0.4",
"vue-markdown-render": "^2.2.1",
"vue3-json-editor": "^1.1.5", "vue3-json-editor": "^1.1.5",
"vue3-konami-code": "^1.0.0" "vue3-konami-code": "^1.0.0"
}, },
"devDependencies": { "devDependencies": {
"@arco-design/web-vue": "^2.55.2", "@arco-design/web-vue": "^2.57.0",
"@tauri-apps/cli": "^1.5.11", "@tauri-apps/cli": "^1.5.11",
"@vitejs/plugin-vue": "^5.0.4", "@vitejs/plugin-vue": "^5.0.4",
"unplugin-vue-components": "^0.27.0", "unplugin-vue-components": "^0.27.0",
"vite": "^5.0.0" "vite": "^6.2.3"
} }
} }

View File

@ -0,0 +1,4 @@
[unstable]
features = ["warn-unused"]
warn-unused-features = false

91
src-tauri/Cargo.lock generated
View File

@ -491,7 +491,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.64", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -522,7 +522,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.64", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -570,7 +570,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"strsim 0.11.1", "strsim 0.11.1",
"syn 2.0.64", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -592,7 +592,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
dependencies = [ dependencies = [
"darling_core 0.20.9", "darling_core 0.20.9",
"quote", "quote",
"syn 2.0.64", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -860,7 +860,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.64", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -1497,9 +1497,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.153" version = "0.2.156"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" checksum = "a5f43f184355eefb8d17fc948dbecf6c13be3c141f20d834ae842193a448c72a"
[[package]] [[package]]
name = "libredox" name = "libredox"
@ -1686,9 +1686,12 @@ dependencies = [
name = "myfirst_tauri" name = "myfirst_tauri"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"chrono",
"csv", "csv",
"find_peaks", "find_peaks",
"lazy_static", "lazy_static",
"libc",
"nalgebra 0.33.2",
"ndarray", "ndarray",
"ndarray-ndimage", "ndarray-ndimage",
"ndarray-stats", "ndarray-stats",
@ -1728,7 +1731,7 @@ checksum = "3ea4908d4f23254adda3daa60ffef0f1ac7b8c3e9a864cf3cc154b251908a2ef"
dependencies = [ dependencies = [
"approx", "approx",
"matrixmultiply", "matrixmultiply",
"nalgebra-macros 0.2.1", "nalgebra-macros 0.2.2",
"num-complex", "num-complex",
"num-rational", "num-rational",
"num-traits", "num-traits",
@ -1736,6 +1739,22 @@ dependencies = [
"typenum", "typenum",
] ]
[[package]]
name = "nalgebra"
version = "0.33.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b"
dependencies = [
"approx",
"matrixmultiply",
"nalgebra-macros 0.2.2",
"num-complex",
"num-rational",
"num-traits",
"simba 0.9.0",
"typenum",
]
[[package]] [[package]]
name = "nalgebra-macros" name = "nalgebra-macros"
version = "0.1.0" version = "0.1.0"
@ -1749,13 +1768,13 @@ dependencies = [
[[package]] [[package]]
name = "nalgebra-macros" name = "nalgebra-macros"
version = "0.2.1" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91761aed67d03ad966ef783ae962ef9bbaca728d2dd7ceb7939ec110fffad998" checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 1.0.109", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -1868,6 +1887,16 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "num-bigint"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
dependencies = [
"num-integer",
"num-traits",
]
[[package]] [[package]]
name = "num-complex" name = "num-complex"
version = "0.4.6" version = "0.4.6"
@ -1898,6 +1927,7 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
dependencies = [ dependencies = [
"num-bigint",
"num-integer", "num-integer",
"num-traits", "num-traits",
] ]
@ -2182,7 +2212,7 @@ dependencies = [
"phf_shared 0.11.2", "phf_shared 0.11.2",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.64", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -2326,9 +2356,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.82" version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -2668,7 +2698,7 @@ checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.64", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -2691,7 +2721,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.64", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -2752,7 +2782,7 @@ dependencies = [
"darling 0.20.9", "darling 0.20.9",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.64", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -2861,6 +2891,19 @@ dependencies = [
"wide", "wide",
] ]
[[package]]
name = "simba"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa"
dependencies = [
"approx",
"num-complex",
"num-traits",
"paste",
"wide",
]
[[package]] [[package]]
name = "simd-adler32" name = "simd-adler32"
version = "0.3.7" version = "0.3.7"
@ -2998,9 +3041,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.64" version = "2.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ad3dee41f36859875573074334c200d1add8e4a87bb37113ebd31d926b7b11f" checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -3343,7 +3386,7 @@ checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.64", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -3444,7 +3487,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.64", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -3534,7 +3577,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.64", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -3732,7 +3775,7 @@ dependencies = [
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.64", "syn 2.0.100",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -3766,7 +3809,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.64", "syn 2.0.100",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]

View File

@ -26,6 +26,10 @@ ndarray-ndimage = "0.4.0"
find_peaks = "0.1.5" find_peaks = "0.1.5"
csv = "1.3.0" csv = "1.3.0"
tklog = "0.0.8" tklog = "0.0.8"
libc = "0.2.156"
chrono = "0.4.38"
nalgebra = "0.33.2"

View File

@ -1,3 +1,13 @@
fn main() { fn main() {
// 根据目标操作系统设置不同的链接搜索路径
if cfg!(target_os = "linux") {
println!("cargo:rustc-link-search=native=../myis11/project/is3/cmake-build-release-visual-studio");
println!("cargo:rustc-link-search=native=../myis11/project/is11/cmake-build-release-visual-studio");
// 注意:在 Linux 上,通常不需要显式地告诉 cargo 链接 .so 文件,
// 只要 #[link(name = "...", kind = "dylib")] 存在,并且库在搜索路径中,
// 链接器就会找到它们。但如果你想明确,也可以添加:
// println!("cargo:rustc-link-lib=dylib=iris_is3lib");
// println!("cargo:rustc-link-lib=dylib=is11lib");
}
tauri_build::build() tauri_build::build()
} }

Binary file not shown.

Binary file not shown.

View File

@ -1 +1 @@
{"pathofsave":"D:\\01Hydata\\123123123\\test2","Filename":"test","caijiavgNumber":"1","useSG":false,"usehighpass":true} {"pathofsave":null,"Filename":"testaa","caijiavgNumber":"1","useSG":false,"usehighpass":false,"Dispatcher":{"isenable":true,"begin":"09:28","end":"23:59"},"sensor_typeforset":"IS3"}

BIN
src-tauri/data46.iris Normal file

Binary file not shown.

View File

@ -0,0 +1,2 @@
copy .\\myis11\\project\\is11\\cmake-build-release-visual-studio-2022\\is11lib.dll ./src-tauri
copy .\\myis11\\project\\is3\\cmake-build-debug-visual-studio\\iris_is3lib.dll ./src-tauri

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 974 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 903 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

BIN
src-tauri/iris_is3lib.dll Normal file

Binary file not shown.

BIN
src-tauri/is11lib.dll Normal file

Binary file not shown.

BIN
src-tauri/msvcp140.dll Normal file

Binary file not shown.

2
src-tauri/pre-build.ps1 Normal file
View File

@ -0,0 +1,2 @@
copy ..\\myis11\\project\\is11\\cmake-build-release-visual-studio-2022\\is11lib.dll ./src-tauri
copy myis11\\project\\is3\\cmake-build-release-visual-studio\\iris_is3lib.dll ./src-tauri

View File

@ -18,7 +18,7 @@ pub fn sg_smooth(data: Vec<f64>, window: usize, order: usize) -> Vec<f64> {
smoothmethod::savgol(data, window, order) smoothmethod::savgol(data, window, order)
} }
#[tauri::command] #[tauri::command]
pub fn Gaussian_filter_high(data: Vec<f64>, sigma: f64) -> Vec<f64> { pub fn gaussian_filter_high(data: Vec<f64>, sigma: f64) -> Vec<f64> {
sharpmethod::high_pass_gaussian_filter(data, sigma) sharpmethod::high_pass_gaussian_filter(data, sigma)
} }
@ -26,3 +26,18 @@ pub fn Gaussian_filter_high(data: Vec<f64>, sigma: f64) -> Vec<f64> {
pub fn find_peek(data: Vec<f64>, minheigh: f64) -> Vec<(u32, f64)> { pub fn find_peek(data: Vec<f64>, minheigh: f64) -> Vec<(u32, f64)> {
spectraltools::find_peek(data, minheigh) spectraltools::find_peek(data, minheigh)
} }
#[tauri::command]
pub fn compute_weave_coeff(x: Vec<f64>, y: Vec<f64>) -> Vec<f64> {
spectraltools::compute_weave_coeff(x, y)
}
pub fn polynomial_smooth_u32(y: &[u32], degree: usize) -> Vec<u32> {
smoothmethod::polynomial_smooth_u32(y, degree)
}
pub fn polynomial_smooth_u16(y: Vec<u16>, degree: usize) -> Vec<u16> {
smoothmethod::polynomial_smooth_u16(&y, degree)
}

View File

@ -6,7 +6,7 @@ use ndarray_ndimage::{gaussian_filter, BorderMode};
pub fn high_pass_gaussian_filter(input: Vec<f64>, sigma: f64) -> Vec<f64> { pub fn high_pass_gaussian_filter(input: Vec<f64>, sigma: f64) -> Vec<f64> {
// 将输入 Vec<f64> 转换为 Array1<f64> // 将输入 Vec<f64> 转换为 Array1<f64>
let mut input_array = Array1::from_vec(input); let input_array = Array1::from_vec(input);
// for i in 0..input_array.len(){ // for i in 0..input_array.len(){
// //
// input_array[i]=input_array[i]*input_array[i]/( 65535f64); // input_array[i]=input_array[i]*input_array[i]/( 65535f64);
@ -16,7 +16,7 @@ pub fn high_pass_gaussian_filter(input: Vec<f64>, sigma: f64) -> Vec<f64> {
// 高斯低通滤波 // 高斯低通滤波
let mut low_pass = gaussian_filter(&input_array, sigma, 0, BorderMode::Reflect, 3); let low_pass = gaussian_filter(&input_array, sigma, 0, BorderMode::Reflect, 3);
// Modify the result: set values less than zero to zero // Modify the result: set values less than zero to zero
println!("{:?}",low_pass); println!("{:?}",low_pass);
// 高通滤波:原始信号 - 低通滤波结果 // 高通滤波:原始信号 - 低通滤波结果

View File

@ -1,5 +1,6 @@
extern crate savgol_rs; extern crate savgol_rs;
use nalgebra::{DMatrix, DVector};
use std::convert::TryFrom;
use savgol_rs::savgol_filter; use savgol_rs::savgol_filter;
pub fn savgol(data: Vec<f64>, window: usize, order: usize) -> Vec<f64> { pub fn savgol(data: Vec<f64>, window: usize, order: usize) -> Vec<f64> {
@ -8,7 +9,134 @@ pub fn savgol(data: Vec<f64>, window: usize, order: usize) -> Vec<f64> {
savgol_filter(&svinput).unwrap() savgol_filter(&svinput).unwrap()
} }
/// 多项式拟合函数 (f64版本)
///
/// 参数:
/// - x: x坐标序列
/// - y: y坐标序列
/// - degree: 多项式次数 (7或8)
///
/// 返回: 平滑后的y值序列
pub fn polynomial_fit_f64(x: &[f64], y: &[f64], degree: usize) -> Vec<f64> {
assert_eq!(x.len(), y.len(), "x和y的长度必须相同");
if x.len() < degree + 1 {
panic!("数据点数量必须大于多项式次数");
}
let n = x.len();
let y_vec = DVector::from_vec(y.to_vec());
// 构建范德蒙矩阵
let mut vandermonde = DMatrix::zeros(n, degree + 1);
for i in 0..n {
for j in 0..=degree {
vandermonde[(i, j)] = x[i].powi(j as i32);
}
}
// 解最小二乘问题 - 新版本nalgebra的调用方式
let svd = vandermonde.svd(true, true);
let coefficients = svd.solve(&y_vec, f64::EPSILON).unwrap();
// 计算拟合值
let fitted_y: Vec<f64> = x
.iter()
.map(|&xi| {
(0..=degree).fold(0.0, |acc, j| acc + coefficients[j] * xi.powi(j as i32))
})
.collect();
fitted_y
}
/// 多项式拟合函数 (u32版本)
///
/// 参数:
/// - x: x坐标序列
/// - y: y坐标序列
/// - degree: 多项式次数 (7或8)
///
/// 返回: 平滑后的y值序列
pub fn polynomial_fit_u32(x: &[u32], y: &[u32], degree: usize) -> Vec<u32> {
// 转换为f64处理
let x_f64: Vec<f64> = x.iter().map(|&xi| xi as f64).collect();
let y_f64: Vec<f64> = y.iter().map(|&yi| yi as f64).collect();
let fitted_f64 = polynomial_fit_f64(&x_f64, &y_f64, degree);
// 转换回u32处理可能的负值(截断为0)和溢出
fitted_f64
.into_iter()
.map(|y| {
if y < 0.0 {
0
} else {
u32::try_from(y.round() as i64).unwrap_or(u32::MAX)
}
})
.collect()
}
/// 简化版当x是等间距时的平滑函数 (u32版本)
pub fn polynomial_smooth_u32(y: &[u32], degree: usize) -> Vec<u32> {
let x: Vec<u32> = (0..y.len() as u32).collect();
polynomial_fit_u32(&x, y, degree)
}
/// 多项式拟合函数 (u16版本)
pub fn polynomial_fit_u16(x: &[u16], y: &[u16], degree: usize) -> Vec<u16> {
let x_f64: Vec<f64> = x.iter().map(|&xi| xi as f64).collect();
let y_f64: Vec<f64> = y.iter().map(|&yi| yi as f64).collect();
let fitted_f64 = polynomial_fit_f64(&x_f64, &y_f64, degree);
fitted_f64
.into_iter()
.map(|y| {
if y < 0.0 {
0
} else if y > u16::MAX as f64 {
u16::MAX
} else {
y.round() as u16
}
})
.collect()
}
/// 简化版当x是等间距时的平滑函数 (u16版本)
pub fn polynomial_smooth_u16(y: &[u16], degree: usize) -> Vec<u16> {
let x: Vec<u16> = (0..y.len() as u16).collect();
polynomial_fit_u16(&x, y, degree)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_polynomial_fit() {
// 测试数据: 一个简单的二次函数加一些噪声
let x = vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
let y = vec![1.0, 3.0, 6.0, 10.0, 15.0, 24.0, 35.0, 50.0, 65.0, 82.0];
// 2次多项式拟合应该能很好拟合
let fitted = polynomial_fit_f64(&x, &y, 2);
assert_eq!(fitted.len(), y.len());
// 检查拟合结果是否接近原始数据
for (original, fitted) in y.iter().zip(fitted.iter()) {
assert!((original - fitted).abs() < 5.0);
}
}
#[test]
fn test_polynomial_smooth() {
// 测试数据: 一个简单的上升序列加一些噪声
let y = vec![
10,12,11,13,12,14,13,15,14,16,
15,17,16,18,17,19,18,20,19,21,
];
// 7次多项式平滑
let smoothed_7 = polynomial_smooth_u32(&y, 7);
print!("smoothed_7: {:?}", smoothed_7);
assert_eq!(smoothed_7.len(), y.len());
// 8次多项式平滑
let smoothed_8 = polynomial_smooth_u32(&y, 8);
assert_eq!(smoothed_8.len(), y.len());
}
}
#[test] #[test]
fn test_savgol() { fn test_savgol() {
// 示例数据 // 示例数据

View File

@ -5,9 +5,9 @@ use std::error::Error;
use find_peaks::PeakFinder; use find_peaks::PeakFinder;
pub fn interpolate_spline<T: Copy + Into<f64>,>(x_T: Vec<T>, y_T: Vec<T>, step: f64) -> Result<Vec<(f64, f64)>, Box<dyn Error>> { pub fn interpolate_spline<T: Copy + Into<f64>,>(x_t: Vec<T>, y_t: Vec<T>, step: f64) -> Result<Vec<(f64, f64)>, Box<dyn Error>> {
let x: Vec<f64> = x_T.iter().map(|&x| x.into()).collect(); let x: Vec<f64> = x_t.iter().map(|&x| x.into()).collect();
let y: Vec<f64> = y_T.iter().map(|&y| y.into()).collect(); let y: Vec<f64> = y_t.iter().map(|&y| y.into()).collect();
if x.len() != y.len() { if x.len() != y.len() {
return Err("x and y must have the same length".into()); return Err("x and y must have the same length".into());
@ -39,9 +39,9 @@ pub fn interpolate_spline<T: Copy + Into<f64>,>(x_T: Vec<T>, y_T: Vec<T>, step:
Ok(result) Ok(result)
} }
pub fn interpolate_spline_at_points<T: Copy + Into<f64>>(x_T: Vec<T>, y_T: Vec<T>, x_target: Vec<f64>) -> Result<Vec<(f64)>, Box<dyn Error>> { pub fn interpolate_spline_at_points<T: Copy + Into<f64>>(x_t: Vec<T>, y_t: Vec<T>, x_target: Vec<f64>) -> Result<Vec<f64>, Box<dyn Error>> {
let x: Vec<f64> = x_T.iter().map(|&x| x.into()).collect(); let x: Vec<f64> = x_t.iter().map(|&x| x.into()).collect();
let y: Vec<f64> = y_T.iter().map(|&y| y.into()).collect(); let y: Vec<f64> = y_t.iter().map(|&y| y.into()).collect();
if x.len() != y.len() { if x.len() != y.len() {
return Err("x and y must have the same length".into()); return Err("x and y must have the same length".into());
@ -128,7 +128,51 @@ fn read_csv_to_vec(file_path: &str) -> Result<Vec<f64>, Box<dyn Error>> {
Ok(values) Ok(values)
} }
use nalgebra::{DMatrix, DVector};
pub fn compute_weave_coeff(x_data:Vec<f64>,y_data:Vec<f64>)->Vec<f64>{
assert_eq!(x_data.len(), y_data.len());
let n = x_data.len();
// 构建设计矩阵 X 和观测向量 y
let mut x_matrix = DMatrix::zeros(n, 4); // 三阶多项式有 4 个系数
let y_vector = DVector::from_vec(y_data.clone());
for (i, &x) in x_data.iter().enumerate() {
x_matrix[(i, 0)] = 1.0; // 常数项
x_matrix[(i, 1)] = x; // x
x_matrix[(i, 2)] = x.powi(2); // x²
x_matrix[(i, 3)] = x.powi(3); // x³
}
// 使用正规方程求解最小二乘问题: (XᵀX)β = Xᵀy
let xt = x_matrix.transpose();
let xtx = &xt * &x_matrix;
let xty = &xt * &y_vector;
// 求解方程 (XᵀX)β = Xᵀy
let beta = xtx
.lu()
.solve(&xty)
.expect("无法求解正规方程,可能是矩阵奇异");
// 输出拟合系数
println!("拟合的三阶多项式系数:");
println!("y = {:.4} + {:.4}x + {:.4}x² + {:.4}", beta[0], beta[1], beta[2], beta[3]);
// 示例:使用拟合的多项式进行预测
let x_test = 6.0;
let y_pred = beta[0] + beta[1]*x_test + beta[2]*x_test.powi(2) + beta[3]*x_test.powi(3);
println!("对于 x = {:.2}, 预测的 y = {:.4}", x_test, y_pred);
let mut retvec=Vec::new();
for i in 0..4{
retvec.push(beta[i]);
}
retvec
}
#[test] #[test]
fn test_find_peek(){ fn test_find_peek(){

37
src-tauri/src/comman1.rs Normal file
View File

@ -0,0 +1,37 @@
use super::serport::serport::*;
#[tauri::command]
pub fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
}
#[tauri::command]
pub fn getportnames() -> Vec<String> {
get_port_name()
}
// #[tauri::command]
// pub fn opencom(portname: serde_json::Value, baudrate: serde_json::Value) -> String {
// //tauri
// let portname = portname.as_str().unwrap();
// let baudrate = baudrate.as_u64().unwrap() as u32;
// set_port_info(&portname.to_string(), baudrate);
// println!("opencom portname:{} baudrate:{}", portname, baudrate);
// logtorust(format!(
// "opencom portname:{} baudrate:{}",
// portname, baudrate
// ));
// tryuseport()
// }
#[tauri::command]
pub fn clearportbuff() -> String {
clearserilport()
}
#[tauri::command]
pub fn closecome() -> String {
closeport()
}

View File

@ -0,0 +1,360 @@
use super::mydefine::*;
pub mod spectralserver;
pub mod spectralbase;
use std::fs;
use super::mylog::*;
use serde_json::json;
use spectralserver::calibrate_file;
use std::ffi::CStr;
use std::path::Path;
pub fn delete_file(filepath: String) -> String {
let file_path = Path::new(&filepath);
if file_path.exists() {
fs::remove_file(file_path).unwrap();
"OK".to_string()
} else {
"文件不存在".to_string()
}
}
pub fn sendtoport_andgetreturn(
data: serde_json::Value,
datatype: serde_json::Value,
) -> Result<RetStruct, String> {
let command = data.get("command").unwrap().to_string();
//println!("start_collect data:{}", data.to_string());
match command.as_str() {
"\"start_collect_flat\"" => {
return start_collect_flat(data, datatype);
},
"\"start_collect_dark\"" => {
return start_collect_dark(data, datatype);
},
"\"get_sensor_info\"" => {
spectralserver::is11_init();
logtorust("init sensor ok".to_string());
let sensor_info = spectralserver::is11_get_sensor_info();
let shuttertime = spectralserver::get_shuttertime();
let sensor_name_cstr = unsafe { CStr::from_ptr(sensor_info.SensorName.as_ptr()) };
let sensor_name = sensor_name_cstr.to_str().unwrap();
let serilnumber_cstr = unsafe { CStr::from_ptr(sensor_info.serialnumber.as_ptr()) };
let serilnumber = serilnumber_cstr.to_str().unwrap();
//定义一个json对象
let jsonforret = json!({
"bochangxishu":{
"a0":sensor_info.a1,
"a1":sensor_info.a2,
"a2":sensor_info.a3,
"a3":sensor_info.a4,
},
"serialnumber":serilnumber,
"bandnum":sensor_info.BandNum,
"bandsum":sensor_info.BandNum,
"name":sensor_name,
// "name":sensor_name,
"version":"1.0.0",
"return_data_type":0,
"work_mode":"advanced_mode",
"sensor_type":"IRIS-Sensor",
"fiber_type":"Single",
"shutter_time":shuttertime,
"has_shutter":true,
});
let califiename=format!("calibratefile/{}_{}_upgain.bin",sensor_name,serilnumber);
spectralserver::load_all_calibrate_file(califiename);
logtorust(format!("get_sensor_info:{}", jsonforret.to_string()));
return Ok(RetStruct {
datatype: 0,
content: jsonforret.to_string(),
data: IS11DataStruct::default(),
});
}
"\"start_opt\"" => {
spectralserver::opt_sensor(90);
let jsonforret = json!({
"command":"start_opt"
});
return Ok(RetStruct {
datatype: 0,
content: jsonforret.to_string(),
data: IS11DataStruct::default(),
});
}
"\"get_opt\"" => {
println!("get_opt");
let ret = get_opt_result();
return ret;
}
"\"start_collect\"" => {
return start_collect(data, datatype);
}
"\"get_caiji_state\"" => {
let (caiji_state, caiji_state_str,percent) = spectralserver::get_now_stat();
let jsonforret = json!({
"caiji_state":caiji_state,
"info":caiji_state_str,
"percent":percent,
"return_data_type":0,
});
//logtorust(format!("get_caiji_state:{}", jsonforret.to_string()));
return Ok(RetStruct {
datatype: 0,
content: jsonforret.to_string(),
data: IS11DataStruct::default(),
});
}
"\"get_data\"" => {
return get_data(data, datatype);
},
"\"get_data_flat\"" => {
return get_data_flat(data, datatype);
},
"\"get_data_dark\"" => {
return get_data_dark(data, datatype);
},
"\"set_shutter_time\"" => {
return set_shutter_time(data, datatype);
},
_ => {
return Err("command not found ".to_string() + "command is:" + &command);
}
}
}
pub fn get_opt_result() -> Result<RetStruct, String> {
let shuttertime = spectralserver::get_shuttertime();
let jsonret = json!({
"opt":shuttertime,
});
return Ok(RetStruct {
datatype: 0,
content: jsonret.to_string(),
data: IS11DataStruct::default(),
});
}
pub fn set_shutter_time(data: serde_json::Value,
datatype: serde_json::Value) -> Result<RetStruct, String> {
let shuttertime: u32;
if data.get("shutter_time").is_none() {
shuttertime = spectralserver::get_shuttertime() as u32;
} else {
shuttertime = data.get("shutter_time").unwrap().as_u64().unwrap() as u32;
spectralserver::set_shutter_time(shuttertime);
}
let jsonret = json!({
"shuttertime":"ok",
});
return Ok(RetStruct {
datatype: 0,
content: jsonret.to_string(),
data: IS11DataStruct::default(),
});
}
pub fn start_collect(
data: serde_json::Value,
datatype: serde_json::Value,
) -> Result<RetStruct, String> {
let shuttertime: u32;
if data.get("shutter_time").is_none() {
shuttertime =spectralserver::get_shuttertime() as u32;
} else {
shuttertime = data.get("shutter_time").unwrap().as_u64().unwrap() as u32;
}
//判断是否有这个参数
let removedark: bool;
if data.get("remove_dark").is_none() {
removedark = false;
} else {
if data.get("remove_dark").unwrap().is_boolean() {
removedark = data.get("remove_dark").unwrap().as_bool().unwrap();
} else if data.get("remove_dark").unwrap().is_string() {
let remove_dark_str = data.get("remove_dark").unwrap().as_str().unwrap();
if remove_dark_str == "yes" {
removedark = true;
} else {
removedark = false;
}
} else {
removedark = false;
}
}
let computeflat = spectralserver::get_is_computeref();
logtorust(format!("start_collect,shutter time is:{}", shuttertime));
if !data.get("collect_times").is_none() {
if data.get("collect_times").unwrap().is_u64() {
let collect_times = data.get("collect_times").unwrap().as_u64().unwrap() as u32;
spectralserver::set_average_number(collect_times,collect_times,collect_times );
}
}
spectralserver::collect(shuttertime, removedark, computeflat);
let jsonret = json!({
"command":"start_collect"
});
return Ok(RetStruct {
datatype: 0,
content: jsonret.to_string(),
data: IS11DataStruct::default(),
});
}
pub fn start_collect_dark(
data: serde_json::Value,
datatype: serde_json::Value,
) -> Result<RetStruct, String> {
let shuttertime: u32;
if data.get("shutter_time").is_none() {
shuttertime = spectralserver::get_shuttertime() as u32;
} else {
shuttertime = data.get("shutter_time").unwrap().as_u64().unwrap() as u32;
}
//判断是否有这个参数
if !data.get("collect_times").is_none() {
if data.get("collect_times").unwrap().is_u64() {
let collect_times = data.get("collect_times").unwrap().as_u64().unwrap() as u32;
spectralserver::set_average_number(collect_times,collect_times,collect_times );
}
}
spectralserver::collcect_dark(shuttertime);
let jsonret = json!({
"command":"start_collect_dark"
});
return Ok(RetStruct {
datatype: 0,
content: jsonret.to_string(),
data: IS11DataStruct::default(),
});
}
pub fn start_collect_flat(
data: serde_json::Value,
datatype: serde_json::Value,
) -> Result<RetStruct, String> {
let shuttertime: u32;
if data.get("shutter_time").is_none() {
shuttertime = spectralserver::get_shuttertime() as u32;
} else {
shuttertime = data.get("shutter_time").unwrap().as_u64().unwrap() as u32;
}
//判断是否有这个参数
if !data.get("collect_times").is_none() {
if data.get("collect_times").unwrap().is_u64() {
let collect_times = data.get("collect_times").unwrap().as_u64().unwrap() as u32;
spectralserver::set_average_number(collect_times,collect_times,collect_times );
}
}
spectralserver::collcect_flat(shuttertime);
let jsonret = json!({
"command":"start_collect_flat"
});
return Ok(RetStruct {
datatype: 0,
content: jsonret.to_string(),
data: IS11DataStruct::default(),
});
}
pub fn get_data(data: serde_json::Value, datatype: serde_json::Value) -> Result<RetStruct, String> {
let mut is11_data = spectralserver::get_data();
println!("get_data datatype:{}", data["return_data_type"]);
let retrun_data_type = data["return_data_type"].as_u64().unwrap();
if retrun_data_type ==0x12 || retrun_data_type ==0x13 {
is11_data=calibrate_file(&is11_data)
}
let jsonret = json!({
"command":"get_data"
});
return Ok(RetStruct {
datatype: 2,
content: jsonret.to_string(),
data: is11_data,
});
}
pub fn get_data_flat(data: serde_json::Value, datatype: serde_json::Value) -> Result<RetStruct, String> {
let is11_data = spectralserver::get_data_flat();
let jsonret = json!({
"command":"get_data_flat"
});
return Ok(RetStruct {
datatype: 2,
content: jsonret.to_string(),
data: is11_data,
});
}
pub fn get_data_dark(data: serde_json::Value, datatype: serde_json::Value) -> Result<RetStruct, String> {
let is11_data = spectralserver::get_data_dark();
let jsonret = json!({
"command":"get_data_dark"
});
return Ok(RetStruct {
datatype: 2,
content: jsonret.to_string(),
data: is11_data,
});
}
pub fn set_weave_coeff(
specnumber: i32,
a0: f64,
a1: f64,
a2: f64,
a3: f64,
) -> String {
println!("set_weave_coeff:specnumber:{},a0:{},a1:{},a2:{},a3:{}", specnumber, a0, a1, a2, a3);
spectralserver::set_weave_coeff(specnumber, a0, a1, a2, a3);
"OK".to_string()
}

View File

@ -0,0 +1,80 @@
use libc::{c_uchar, size_t};
use std::slice;
use crate::serport::serport::*;
use super::STRSensorInfo;
type SerialWrite = Option<unsafe extern "C" fn(data: *mut c_uchar, length: size_t) -> size_t>;
#[cfg_attr(target_os = "windows", link(name = "..\\myis11\\project\\is11\\cmake-build-release-visual-studio-2022/is11lib", kind = "dylib"))]
#[cfg_attr(target_os = "linux", link(name = "is11lib", kind = "dylib"))]
// #[link(name = "../myis11/project/is11/cmake-build-release-visual-studio-2022/is11lib",kind = "dylib")]
extern "C" {
pub fn Set_Serial_FUN(writefunc:SerialWrite,readfunc:SerialWrite);
pub fn abs1(input: i32) -> i32;
pub fn test();
pub fn IS11SensorInit() -> i32;
pub fn Get_SensorInfo() -> STRSensorInfo;
pub fn IS11OptSnenser(percent:i32) -> i32;
pub fn IS11GetData(outdata: *mut u16, shuttertime: i32) -> i32;
}
pub unsafe extern "C" fn serialsenddata(data: *mut c_uchar, length: size_t) -> size_t {
// 处理数据
let data_slice = slice::from_raw_parts(data, length as usize).to_vec();
// data_slice转换为Vec<u8>
// 打印数据
// for byte in data_slice.clone() {
// print!("{:02X} ", byte);
// }
// println!();
sendtoprot(data_slice);
length
}
use core::ptr;
pub unsafe extern "C" fn serialreaddate(data: *mut c_uchar, length: size_t) -> size_t {
let dataout=readforport();
let length1: usize = dataout.len();
// 将结果复制给c_uchar
// for byte in dataout.clone() {
// print!("{:02X} ", byte);
// }
// println!();
ptr::copy_nonoverlapping(dataout.as_ptr(), data, length1);
// println!("{:?}",data);
length1
}
pub fn is11_init() -> i32 {
unsafe {
Set_Serial_FUN(Some(serialsenddata), Some(serialreaddate));
IS11SensorInit()
}
}
pub fn is11_get_sensor_info() -> STRSensorInfo {
unsafe { Get_SensorInfo() }
}
pub fn _is11_opt_snenser(percent: i32) -> i32 {
unsafe { IS11OptSnenser(percent) }
}
pub fn is11_get_data(shuttertime: i32) -> Vec<u16> {
let mut outdata: Vec<u16> = vec![0; 2048];
unsafe {
let len = IS11GetData(outdata.as_mut_ptr(), shuttertime);
outdata.truncate(len as usize);
}
outdata
}

View File

@ -0,0 +1,94 @@
use libc::{c_uchar, size_t};
use std::slice;
use crate::serport::serport::*;
use super::STRSensorInfo;
//void IS3SetShutterOpen(int isopen);
type SerialWrite = Option<unsafe extern "C" fn(data: *mut c_uchar, length: size_t) -> size_t>;
#[cfg_attr(target_os = "windows", link(name = "..\\myis11\\project\\is3\\cmake-build-debug-visual-studio/iris_is3lib", kind = "dylib"))]
#[cfg_attr(target_os = "linux", link(name = "iris_is3lib", kind = "dylib"))]
// #[link(
// name = "..\\myis11\\project\\is3\\cmake-build-debug-visual-studio/iris_is3lib",
// kind = "dylib"
// )]
extern "C" {
pub fn IS3Set_Serial_FUN(writefunc:SerialWrite,readfunc:SerialWrite);
pub fn IS3SensorInit() -> i32;
pub fn IS3Get_SensorInfo() -> STRSensorInfo;
pub fn IS3OptSnenser(percent:i32) -> i32;
pub fn IS3GetData(outdata: *mut u16, shuttertime: i32) -> i32;
pub fn IS3SetWeaveLenthCoeff(a:*mut f64,length:i32) -> i32;
pub fn IS3SetShutterOpen(isopen: i32) ;
}
pub unsafe extern "C" fn serialsenddata(data: *mut c_uchar, length: size_t) -> size_t {
// 处理数据
let data_slice = slice::from_raw_parts(data, length as usize).to_vec();
// data_slice转换为Vec<u8>
// 打印数据
// for byte in data_slice.clone() {
// print!("{:02X} ", byte);
// }
// println!();
sendtoprot(data_slice);
length
}
use core::ptr;
pub unsafe extern "C" fn serialreaddate(data: *mut c_uchar, length: size_t) -> size_t {
let dataout=readforport();
let length1: usize = dataout.len();
// 将结果复制给c_uchar
// for byte in dataout.clone() {
// print!("{:02X} ", byte);
// }
// println!();
ptr::copy_nonoverlapping(dataout.as_ptr(), data, length1);
// println!("{:?}",data);
length1
}
pub fn is3_init() -> i32 {
unsafe {
IS3Set_Serial_FUN(Some(serialsenddata), Some(serialreaddate));
IS3SensorInit()
}
}
pub fn is3_get_sensor_info() -> STRSensorInfo {
unsafe { IS3Get_SensorInfo() }
}
pub fn is3_opt_snenser(percent: i32) -> i32 {
unsafe { IS3OptSnenser(percent) }
}
pub fn is3_get_data(shuttertime: i32) -> Vec<u16> {
let mut outdata: Vec<u16> = vec![0; 2048];
unsafe {
let len = IS3GetData(outdata.as_mut_ptr(), shuttertime);
outdata.truncate(len as usize);
}
outdata
}
pub fn is3_set_shutter_open(isopen: i32) {
unsafe { IS3SetShutterOpen(isopen) }
}
pub fn is3_set_weave_length_coeff(a: Vec<f64>) -> i32 {
let mut a = a.clone();
let a_ptr = a.as_mut_ptr();
let length = a.len() as i32;
println!("a_ptr: {:?}", a_ptr);
println!("length: {:?}", length);
unsafe { IS3SetWeaveLenthCoeff(a_ptr, length) }
}

View File

@ -0,0 +1,255 @@
use libc::{c_uchar,c_char,c_long,c_float, size_t};
type SerialWrite = Option<unsafe extern "C" fn(data: *mut c_uchar, length: size_t) -> size_t>;
use lazy_static::lazy_static;
use std::{
sync::{Arc, Mutex},
};
mod IS3_sensor;
mod IS11_sensor;
// 定义emun 不同光谱仪
#[derive(Copy, Clone)]
pub enum Senortype {
IS11,
IS1,
IS2,
OSIF,
IS3
}
//全局变量 传感器类型 用lazy_static宏定义 原子变量
lazy_static! {
static ref SENSORTYPE: Arc<Mutex<Senortype>> = Arc::new(Mutex::new(Senortype::IS3));
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct STRSensorInfo {
pub SensorName: [c_char; 100],
pub maxValue: c_long,
pub BandNum: c_long,
pub serialnumber: [c_char; 100],
pub a1: c_float,
pub a2: c_float,
pub a3: c_float,
pub a4: c_float,
pub issensorinit: c_uchar,
}
impl Default for STRSensorInfo {
fn default() -> Self {
STRSensorInfo {
SensorName: [0; 100],
maxValue: 0,
BandNum: 0,
serialnumber: [0; 100],
a1: 0.0,
a2: 0.0,
a3: 0.0,
a4: 0.0,
issensorinit: 0,
}
}
}
lazy_static! {
static ref SENSOR_INFO: Arc<Mutex<STRSensorInfo>> = Arc::new(Mutex::new(STRSensorInfo::default()));
}
pub fn sensor_set_sensor_type(senortype:String)
{
let mut data = SENSORTYPE.lock().unwrap();
match senortype.as_str() {
"IS11" => *data = Senortype::IS11,
"IS1" => *data = Senortype::IS1,
"IS2" => *data = Senortype::IS2,
"OSIF" => *data = Senortype::OSIF,
"IS3" => *data = Senortype::IS3,
_ => *data = Senortype::IS11,
}
}
pub fn abs1(input: i32) -> i32
{
return 0;
}
pub fn test()
{
}
pub fn sensor_init() -> i32
{
let senortype = SENSORTYPE.lock().unwrap();
match *senortype {
Senortype::IS11 => {
unsafe {
IS11_sensor::Set_Serial_FUN(Some(IS11_sensor::serialsenddata), Some(IS11_sensor::serialreaddate));
return IS11_sensor::IS11SensorInit();
}
},
Senortype::IS3 => {
unsafe {
IS3_sensor::IS3Set_Serial_FUN(Some(IS3_sensor::serialsenddata), Some(IS3_sensor::serialreaddate));
return IS3_sensor::IS3SensorInit();
}
},
_ => {
return 0;
},
}
}
pub fn sensor_get_sensor_info() -> STRSensorInfo{
let senortype = SENSORTYPE.lock().unwrap();
let mut Sensorinfo= SENSOR_INFO.lock().unwrap();
match *senortype {
Senortype::IS11 => {
unsafe {
let info = IS11_sensor::Get_SensorInfo();
*Sensorinfo = info.clone();
return info;
}
},
Senortype::IS3 => {
unsafe {
let info = IS3_sensor::IS3Get_SensorInfo();
*Sensorinfo = info.clone();
return info;
}
},
_ => {
return STRSensorInfo::default();
},
}
}
pub fn sensor_opt_sensor(percent:i32) -> i32{
let senortype = SENSORTYPE.lock().unwrap();
match *senortype {
Senortype::IS11 => {
unsafe {
return IS11_sensor::IS11OptSnenser(percent);
}
},
Senortype::IS3 => {
unsafe {
return IS3_sensor::IS3OptSnenser(percent);
}
},
_ => {
return 0;
},
}
}
pub fn sensor_get_data_base(outdata: *mut u16, shuttertime: i32) -> i32
{
let senortype = SENSORTYPE.lock().unwrap();
match *senortype {
Senortype::IS11 => {
unsafe {
return IS11_sensor::IS11GetData(outdata, shuttertime);
}
},
Senortype::IS3 => {
unsafe {
return IS3_sensor::IS3GetData(outdata, shuttertime);
}
},
_ => {
return 0;
},
}
}
pub fn sensor_get_data(shuttertime: i32) -> Vec<u16> {
let sensor_info= SENSOR_INFO.lock().unwrap();
let bandSum = sensor_info.BandNum as usize;
let mut outdata: Vec<u16> = vec![0; bandSum];
unsafe {
let len = sensor_get_data_base(outdata.as_mut_ptr(), shuttertime);
outdata.truncate(len as usize);
}
// polynomial_smooth_u16( outdata ,7)
outdata
}
pub fn set_sensor_weave_length_coeff(a: Vec<f64>) -> i32 {
let senortype = SENSORTYPE.lock().unwrap();
match *senortype {
Senortype::IS11 => {
0
},
Senortype::IS3 => {
IS3_sensor::is3_set_weave_length_coeff(a);
0
},
_ => {
return 0;
},
}
}
pub fn sensor_set_shutter_open(isopen:i32) {
let senortype = SENSORTYPE.lock().unwrap();
match *senortype {
Senortype::IS11 => {
unsafe {
}
},
Senortype::IS3 => {
unsafe {
IS3_sensor::IS3SetShutterOpen(isopen);
}
},
_ => {
},
}
}

View File

@ -0,0 +1,467 @@
use super::spectralbase;
use super::spectralbase::*;
use super::super::mydefine::*;
use lazy_static::lazy_static;
use chrono::{self, Datelike, Timelike};
use std::thread;
use std::fs::File;
use std::mem;
use std::path::Path;
use std::io::Read;
#[derive(PartialEq)]
enum WorkStat {
IDLE,
WOKING,
STOP,
OPTING,
}
use std::vec;
use std::{
sync::{Arc, Mutex},
};
struct is11_dev_data {
sensor_info: super::spectralbase::STRSensorInfo,
shuttertime: i32,
stat: WorkStat,
percent: i32,
workname: String,
hasdark: bool,
hasflat: bool,
removedark: bool,
computeflat: bool,
average_number_data: u32,
average_number_dark: u32,
average_number_flat: u32,
has_CalidataUP: bool,
}
lazy_static! {
static ref DEV_STAT: Arc<Mutex<is11_dev_data>> = Arc::new(Mutex::new(is11_dev_data {
sensor_info: super::spectralbase::STRSensorInfo::default(),
shuttertime: 0,
stat: WorkStat::IDLE,
percent: 0,
workname: "noting".to_string(),
hasdark: false,
hasflat: false,
removedark: false,
computeflat: true,
average_number_data: 1,
average_number_dark: 10,
average_number_flat: 10,
has_CalidataUP: false,
}));
}
// lazy_static! {
// static ref DATA: Arc<Mutex<Vec<u16>>> = Arc::new(Mutex::new(Vec::new()));
// }
lazy_static! {
static ref DATA_IS11: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
static ref DARK_DATA: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
static ref FLAT_DATA: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
static ref CALIDATAUP: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
static ref CALIOFFSETUP: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
}
pub fn is11_get_sensor_info() -> STRSensorInfo {
return super::spectralbase::sensor_get_sensor_info();
}
pub fn is11_init(){
super::spectralbase::sensor_init();
let mut dev_stat=DEV_STAT.lock().unwrap();
let sensorinfo= is11_get_sensor_info();
dev_stat.sensor_info=sensorinfo;
}
pub fn get_shuttertime() -> i32 {
let dev_stat=DEV_STAT.lock().unwrap();
return dev_stat.shuttertime;
}
pub fn opt_sensor(percent: i32) -> i32 {
let mut dev_stat=DEV_STAT.lock().unwrap();
if dev_stat.stat != WorkStat::IDLE {
return -1;
}
dev_stat.stat=WorkStat::OPTING;
dev_stat.percent=0;
dev_stat.workname="opting".to_string();
drop(dev_stat); //释放锁
thread::spawn(move || {
let shuttertime= super::spectralbase::sensor_opt_sensor(90); //多线程设置曝光时间
let mut dev_statnow=DEV_STAT.lock().unwrap();
dev_statnow.stat=WorkStat::IDLE;
dev_statnow.shuttertime=shuttertime;
dev_statnow.workname="finish".to_string();
dev_statnow.percent=100;
dev_statnow.hasdark=false;
dev_statnow.hasflat=false;
}
);
return 0;
}
pub fn get_now_stat()->(String,String,i32){
let dev_stat=DEV_STAT.lock().unwrap();
match dev_stat.stat {
WorkStat::IDLE => {
return ("finish".to_string(),dev_stat.workname.clone(),100);
},
WorkStat::WOKING => {
return ("working".to_string(),dev_stat.workname.clone(),dev_stat.percent);
},
WorkStat::STOP => {
return ("finish".to_string(),dev_stat.workname.clone(),dev_stat.percent);
},
WorkStat::OPTING => {
return ("opting".to_string(),dev_stat.workname.clone(),dev_stat.percent);
},
}
}
pub fn collect(shuttertime:u32,removedark:bool,computeflat:bool){
let mut dev_stat=DEV_STAT.lock().unwrap();
if dev_stat.stat != WorkStat::IDLE {
return ;
}
let averagenumber=dev_stat.average_number_data;
dev_stat.stat=WorkStat::WOKING;
dev_stat.percent=0;
dev_stat.workname="采集中".to_string();
let bandsunm=dev_stat.sensor_info.BandNum as usize;
drop(dev_stat); //释放锁
thread::spawn(move || {
let mut datasum:Vec<u32>=vec![0;bandsunm];
for _i in 0..averagenumber {
let data=super::spectralbase::sensor_get_data(shuttertime as i32);
for i in 0..bandsunm {
datasum[i]=datasum[i]+data[i] as u32;
}
let mut dev_stat=DEV_STAT.lock().unwrap();
let info=format!("采集中,{}%",_i as f32/averagenumber as f32*100 as f32*0.9);
dev_stat.workname=info;
dev_stat.percent=((_i+1) as f32/averagenumber as f32*100 as f32*0.9) as i32;
drop(dev_stat); //释放锁
}
let data=datasum.iter().map(|x| *x as f32/averagenumber as f32).collect::<Vec<f32>>();
let mut dev_stat=DEV_STAT.lock().unwrap();
let _lenth=data.len();
println!("data len={}",_lenth);
let mut tempis11data=IS11DataStruct::default();
for i in 0.._lenth {
tempis11data.data[i]=data[i] as f32;
}
// 获取当前时间
let now = chrono::Local::now();
tempis11data.year=(now.year()-2000) as u8;
tempis11data.month=now.month() as u8;
tempis11data.day=now.day() as u8;
tempis11data.hour=now.hour() as u8;
tempis11data.minute=now.minute() as u8;
tempis11data.second=now.second() as u8;
tempis11data.shutter_time=shuttertime;
tempis11data.index=0;
tempis11data.datatype=0;
let mut data1=DATA_IS11.lock().unwrap();
let darkdata=DARK_DATA.lock().unwrap();
*data1=tempis11data;
if removedark && dev_stat.hasdark {
for i in 0.._lenth {
data1.data[i]=data1.data[i]-darkdata.data[i];
}
}
if computeflat && dev_stat.hasflat {
let flatdata=FLAT_DATA.lock().unwrap();
for i in 0.._lenth {
let temp=flatdata.data[i]-darkdata.data[i];
if temp<=0.0 {
data1.data[i]=10000.0;
}else{
data1.data[i]=data1.data[i]/temp*10000.0;
}
if data1.data[i]<0.0 {
data1.data[i]=0.0;
}
if data1.data[i]>15000.0 {
data1.data[i]=15000.0;
}
// data1.data[i]=data1.data[i]/(flatdata.data[i]-darkdata.data[i])*10000.0;
}
}
dev_stat.stat=WorkStat::IDLE;
dev_stat.percent=100;
dev_stat.workname="finish".to_string();
});
}
pub fn collcect_dark(shuttertime:u32)
{
let mut dev_stat=DEV_STAT.lock().unwrap();
if dev_stat.stat != WorkStat::IDLE {
return ;
}
let averagenumber=dev_stat.average_number_dark;
dev_stat.stat=WorkStat::WOKING;
dev_stat.percent=0;
dev_stat.workname="采集Dark中".to_string();
let bandsunm=dev_stat.sensor_info.BandNum as usize;
drop(dev_stat); //释放锁
thread::spawn(move || {
let mut datasum:Vec<u32>=vec![0;bandsunm];
sensor_set_shutter_open(0);
for _i in 0..averagenumber {
let data=super::spectralbase::sensor_get_data(shuttertime as i32);
for i in 0..bandsunm {
datasum[i]=datasum[i]+data[i] as u32;
}
let mut dev_stat=DEV_STAT.lock().unwrap();
let info=format!("采集Dark中,{}%",_i as f32/averagenumber as f32*100 as f32*0.9);
dev_stat.workname=info;
dev_stat.percent=((_i+1) as f32/averagenumber as f32*100 as f32*0.9) as i32;
drop(dev_stat); //释放锁
}
sensor_set_shutter_open(1);
let data=datasum.iter().map(|x| *x as f32/averagenumber as f32).collect::<Vec<f32>>();
let mut dev_stat=DEV_STAT.lock().unwrap();
let _lenth=data.len();
println!("data len={}",_lenth);
let mut tempis11data=IS11DataStruct::default();
for i in 0.._lenth {
tempis11data.data[i]=data[i] as f32;
}
//获取当前时间
let now = chrono::Local::now();
tempis11data.year=(now.year()-2000) as u8;
tempis11data.month=now.month() as u8;
tempis11data.day=now.day() as u8;
tempis11data.hour=now.hour() as u8;
tempis11data.minute=now.minute() as u8;
tempis11data.second=now.second() as u8;
tempis11data.shutter_time=shuttertime;
tempis11data.index=0;
tempis11data.datatype=0;
let mut data1=DARK_DATA.lock().unwrap();
*data1=tempis11data;
dev_stat.stat=WorkStat::IDLE;
dev_stat.percent=100;
dev_stat.workname="finish".to_string();
dev_stat.hasdark=true;
});
}
pub fn collcect_flat(shuttertime:u32)
{
let mut dev_stat=DEV_STAT.lock().unwrap();
if dev_stat.stat != WorkStat::IDLE {
return ;
}
let averagenumber=dev_stat.average_number_flat;
dev_stat.stat=WorkStat::WOKING;
dev_stat.percent=0;
dev_stat.workname="采集中".to_string();
let bandsunm=dev_stat.sensor_info.BandNum as usize;
drop(dev_stat); //释放锁
thread::spawn(move || {
let mut datasum:Vec<u32>=vec![0;bandsunm];
for _i in 0..averagenumber {
let data=super::spectralbase::sensor_get_data(shuttertime as i32);
for i in 0..bandsunm {
datasum[i]=datasum[i]+data[i] as u32;
}
let mut dev_stat=DEV_STAT.lock().unwrap();
let info=format!("采集白板中,{}%",_i as f32/averagenumber as f32*100 as f32*0.9);
dev_stat.workname=info;
dev_stat.percent=((_i+1) as f32/averagenumber as f32*100 as f32*0.9) as i32;
drop(dev_stat); //释放锁
}
let data=datasum.iter().map(|x| *x as f32/averagenumber as f32).collect::<Vec<f32>>();
let mut dev_stat=DEV_STAT.lock().unwrap();
let _lenth=data.len();
println!("data len={}",_lenth);
let mut tempis11data=IS11DataStruct::default();
for i in 0.._lenth {
tempis11data.data[i]=data[i] as f32;
}
//获取当前时间
let now = chrono::Local::now();
tempis11data.year=(now.year()-2000) as u8;
tempis11data.month=now.month() as u8;
tempis11data.day=now.day() as u8;
tempis11data.hour=now.hour() as u8;
tempis11data.minute=now.minute() as u8;
tempis11data.second=now.second() as u8;
tempis11data.shutter_time=shuttertime;
tempis11data.index=0;
tempis11data.datatype=0;
let mut data1=FLAT_DATA.lock().unwrap();
*data1=tempis11data;
dev_stat.stat=WorkStat::IDLE;
dev_stat.percent=100;
dev_stat.workname="finish".to_string();
dev_stat.hasflat=true;
});
}
pub fn get_data()->IS11DataStruct{
let data1=DATA_IS11.lock().unwrap();
return data1.clone();
}
pub fn get_data_flat()->IS11DataStruct{
let data1=FLAT_DATA.lock().unwrap();
return data1.clone();
}
pub fn get_data_dark()->IS11DataStruct{
let data1=DARK_DATA.lock().unwrap();
return data1.clone();
}
pub fn get_is_computeref()->bool{
let dev_stat=DEV_STAT.lock().unwrap();
return dev_stat.computeflat;
}
pub fn set_shutter_time(shuttertime:u32){
let mut dev_stat=DEV_STAT.lock().unwrap();
dev_stat.shuttertime=shuttertime as i32;
dev_stat.hasdark=false;
dev_stat.hasflat=false;
}
pub fn set_average_number(arverage_number_data:u32,arverage_number_dark:u32,arverage_number_flat:u32){
let mut dev_stat=DEV_STAT.lock().unwrap();
dev_stat.average_number_data=arverage_number_data;
dev_stat.average_number_dark=arverage_number_dark;
dev_stat.average_number_flat=arverage_number_flat;
}
pub fn calibrate_file(orgdata: &IS11DataStruct) -> IS11DataStruct {
let dev_stat=DEV_STAT.lock().unwrap();
if !dev_stat.has_CalidataUP {
return orgdata.clone();
}
drop(dev_stat);
;
let calidata=CALIDATAUP.lock().unwrap();
let offsetdata=CALIOFFSETUP.lock().unwrap();
let mut data = IS11DataStruct::default();
let collect_gaindb = orgdata.temprature[0];
let collect_shutter = orgdata.shutter_time;
let cali_gaindb = calidata.temprature[0];
let cali_shutter = calidata.shutter_time;
//db 转系数
let collect_gain = 10.0_f32.powf(collect_gaindb / 20.0);
let cali_gain = 10.0_f32.powf(cali_gaindb / 20.0);
//计算增益
let Scale_gain = cali_gain / collect_gain;
let Scale_shutter = cali_shutter as f32/ collect_shutter as f32;
let SCale = Scale_gain * Scale_shutter as f32;
let len = orgdata.data.len();
for i in 0..len {
data.data[i] = orgdata.data[i] * SCale * calidata.data[i]+offsetdata.data[i];
}
return data;
}
pub fn load_all_calibrate_file(filepath: String) -> String {
let file_path = Path::new(&filepath);
if file_path.exists() {
let mut up_gain_data=CALIDATAUP.lock().unwrap();
*up_gain_data=load_calibrate_file(file_path.to_str().unwrap().to_string()).unwrap();
let mut dev_stat=DEV_STAT.lock().unwrap();
dev_stat.has_CalidataUP=true;
return "ok".to_string();
} else {
println!("文件不存在: {:?}", file_path);
return "文件不存在".to_string();
}
}
fn load_calibrate_file(filepath: String) -> Result<IS11DataStruct, String> {
let mut data = IS11DataStruct::default();
let mut buffer = vec![0u8; mem::size_of::<IS11DataStruct>()];
let mut file = File::open(filepath).unwrap();
file.read_exact(&mut buffer).unwrap();
unsafe {
let ptr = &mut data as *mut IS11DataStruct as *mut u8;
std::ptr::copy_nonoverlapping(buffer.as_ptr(), ptr, mem::size_of::<IS11DataStruct>());
}
return Ok(data);
}
pub fn set_weave_coeff(specnumber: i32, a0: f64, a1: f64, a2: f64, a3: f64) -> String {
let vecdata=vec![a0,a1,a2,a3];
spectralbase::set_sensor_weave_length_coeff(vecdata);
"ok".to_string()
}

View File

@ -0,0 +1,265 @@
use std::fmt::format;
use chrono::Datelike;
use chrono::Timelike;
use serde_json::json;
use crate::myformatiris::structures::*;
use crate::myformatiris::read::*;
use crate::myformatiris::write::*;
pub fn savecalibratefileIRIS(Gain:serde_json::Value,direction: bool, filepath: String, dndata: serde_json::Value, lampdata: serde_json::Value, devinfo: serde_json::Value) -> String {
//输出 输入参数
//println!("Gain: {:?}", Gain);
// println!("direction: {:?}", direction);
// println!("Filepath: {:?}", devinfo);
// println!("DNData: {:?}", dndata);
// println!("Lampdata: {:?}", lampdata);
// println!("Devinfo: {:?}", devinfo);
let mut oneirisdata:OneIRISData = OneIRISData::new();
let mut spectraldatagain: SpectralData= SpectralData::new();
spectraldatagain.name= devinfo["name"].as_str().unwrap_or("Unknown").to_string()+&"_".to_string()+&devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string()+&"_gain".to_string();
spectraldatagain.sensor_id= devinfo["name"].as_str().unwrap_or("Unknown").to_string()+&devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string();
spectraldatagain.bands= devinfo["bands"].as_u64().unwrap_or(0) as u16;
spectraldatagain.pixel_size=8;
spectraldatagain.data_type=DATA_TYPE_FLOAT64;
spectraldatagain.fiber_id=direction as u8;
spectraldatagain.exposure=Gain["shutter_time"].as_u64().unwrap_or(0) as f64;
spectraldatagain.gain=Gain["sensor_gain"].as_f64().unwrap_or(1.0) as f32;
let datenow = chrono::Local::now();
let nowtiem= TimeStruct {
time_zone:50,
year:datenow.year() as u16,
month:datenow.month() as u8,
day:datenow.day() as u8,
hour:datenow.hour() as u8,
minute:datenow.minute() as u8,
second:datenow.second() as u8,
millisecond:datenow.timestamp_subsec_millis() as u16,
};
spectraldatagain.collection_time=nowtiem.clone();
spectraldatagain.ground_type=Target_Spectral_Type_CaliFile_Gain;
spectraldatagain.valid_flag=1;
let spectraldatavec:Vec<f64>=Gain["Data"].as_array().unwrap_or(&vec![]).iter()
.map(|x| x.as_f64().unwrap_or(0.0))
.collect::<Vec<f64>>();
spectraldatagain.Set_Spectral_Data(spectraldatavec, DATA_TYPE_FLOAT64);
println!("spectraldata.name: {:?}", spectraldatagain.name);
oneirisdata.spectral_data_section.push(spectraldatagain);
let mut spectraldata_dn: SpectralData= SpectralData::new();
spectraldata_dn.name= devinfo["name"].as_str().unwrap_or("Unknown").to_string()+&"_".to_string()+&devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string()+&"_dn".to_string();
spectraldata_dn.sensor_id= devinfo["name"].as_str().unwrap_or("Unknown").to_string()+&devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string();
spectraldata_dn.bands= devinfo["bands"].as_u64().unwrap_or(0) as u16;
spectraldata_dn.pixel_size=8;
spectraldata_dn.fiber_id=direction as u8;
spectraldata_dn.exposure=dndata["shutter_time"].as_u64().unwrap_or(0) as f64;
spectraldata_dn.gain=dndata["gain"].as_f64().unwrap_or(1.0) as f32;
spectraldata_dn.data_type=DATA_TYPE_FLOAT64;
spectraldata_dn.collection_time=nowtiem.clone();
spectraldata_dn.ground_type=Target_Spectral_Type_DN;
spectraldata_dn.valid_flag=1;
let spectraldatavec_dn:Vec<f64>=dndata["data"].as_array().unwrap_or(&vec![]).iter()
.map(|x| x.as_f64().unwrap_or(0.0))
.collect::<Vec<f64>>();
spectraldata_dn.Set_Spectral_Data(spectraldatavec_dn, DATA_TYPE_FLOAT64);
println!("spectraldata_dn.name: {:?}", spectraldata_dn.name);
oneirisdata.spectral_data_section.push(spectraldata_dn);
let mut spectraldata_lamp: SpectralData= SpectralData::new();
let lampvalue= lampdata["value_lable"].as_str().unwrap_or("Unknown");
let datalabel= lampdata["data_value"].as_str().unwrap_or("Unknown");
spectraldata_lamp.name= devinfo["name"].as_str().unwrap_or("Unknown").to_string()+&"_".to_string()+&devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string()+&"_lamplable_".to_string()+&lampvalue.to_string()+&"_datalabel_".to_string()+&datalabel.to_string();
spectraldata_lamp.sensor_id= devinfo["name"].as_str().unwrap_or("Unknown").to_string()+&devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string();
let lampvalue_f64_vec= lampdata["data"].as_array().unwrap_or(&vec![]).iter()
.map(|x| x.as_f64().unwrap_or(0.0))
.collect::<Vec<f64>>();
spectraldata_lamp.Set_Spectral_Data(lampvalue_f64_vec, DATA_TYPE_FLOAT64);
spectraldata_lamp.ground_type=Target_LAMP_VALUE_SCALED;
oneirisdata.spectral_data_section.push(spectraldata_lamp);
let spectraldata_devinfo= json!(
{
"info_type": "devinfo", // 0 for device info
"sensor_id": devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string(),
"wave_coeff": {
"a1": devinfo["bochangxishu"]["a1"].as_f64().unwrap_or(0.0),
"a2": devinfo["bochangxishu"]["a2"].as_f64().unwrap_or(0.0),
"a3": devinfo["bochangxishu"]["a3"].as_f64().unwrap_or(0.0),
"a4": devinfo["bochangxishu"]["a4"].as_f64().unwrap_or(0.0)
}
}
);
let environment_info= json!(
{
"info_type": "environment", // 1 for environment info
"date": format!("{}-{:02}-{:02} {:02}:{:02}:{:02}",
datenow.year(),
datenow.month(),
datenow.day(),
datenow.hour(),
datenow.minute(),
datenow.second()
),
}
);
/*
let spectraldata_devinfo= json!(
{
"info_type": "infolist", // 0 for device info
"info_number":3,
"info_list": [
{
"info_type": "devinfo", // 0 for device info
"sensor_id": "is30002",
"bandnum": 2048,
"wave_coeff": {
"a1": 0.0,
"a2": 0.0,
"a3": 400,
"a4": 1.0
}
},
{
"info_type": "environment", // 1 for gain info
"date": "2000-01-00 00:00:00",
//下面可选
"humidity":90.0,
"temperature":35.0 ,
"gps":{
"latitude":115.01,
"longitude": 39.01,
"altitude": 100.0
},
},
{
"info_type": "devinfo", // 0 for device info
"sensor_id": "is20001",
"bandnum": 512,
"wave_coeff": {
"a1": 0,
"a2": 0.0,
"a3":390,
"a4": 4
}
}
]
}
);
*/
// spectraldata_devinfo.sensor_id=devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string();
// spectraldata_devinfo.wave_coeff[0]=devinfo["bochangxishu"]["a1"].as_f64().unwrap_or(0.0);
// spectraldata_devinfo.wave_coeff[1]=devinfo["bochangxishu"]["a2"].as_f64().unwrap_or(0.0);
// spectraldata_devinfo.wave_coeff[2]=devinfo["bochangxishu"]["a3"].as_f64().unwrap_or(0.0);
// spectraldata_devinfo.wave_coeff[3]=devinfo["bochangxishu"]["a4"].as_f64().unwrap_or(0.0);
oneirisdata.spectral_info_section.push(spectraldata_devinfo);
oneirisdata.spectral_info_section.push(environment_info);
// 修复后的代码
let filesave_date = format!("{}_{:04}{:02}{:02}",
filepath, // 如果 filepath 是 String这里会自动借用
datenow.year(),
datenow.month(),
datenow.day()
);
let filesavepath=filesave_date.clone()+".iris";
wirte_iris_data(&oneirisdata, &filesavepath);
"ok".to_string()
}
pub fn save_reflectance_to_iris(reflectance_data: serde_json::Value, devinfo: serde_json::Value, filepath: String) -> String {
let mut oneirisdata: OneIRISData = OneIRISData::new();
let mut spectraldata_reflectance: SpectralData = SpectralData::new();
let fileName = reflectance_data["fileName"].as_str().unwrap_or("Unknown").to_string();
//将filename中的.替换为_ 并保存到新的变量里
let fileName1 = fileName.replace(".", "_");
spectraldata_reflectance.name = fileName1+&devinfo["name"].as_str().unwrap_or("Unknown").to_string() ;
spectraldata_reflectance.sensor_id = devinfo["sensor_id"].as_str().unwrap_or("Unknown").to_string() ;
// + &devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string();
let reflectance_values: Vec<f64> = reflectance_data["data"]
.as_array()
.unwrap_or(&vec![])
.iter()
.map(|x| x.as_f64().unwrap_or(0.0))
.collect::<Vec<f64>>();
spectraldata_reflectance.bands = reflectance_values.len() as u16;
spectraldata_reflectance.pixel_size = 8;
spectraldata_reflectance.data_type = DATA_TYPE_FLOAT64;
spectraldata_reflectance.fiber_id = 0;
spectraldata_reflectance.exposure = 0.0;
spectraldata_reflectance.gain = 0.0;
let datenow = chrono::Local::now();
let nowtime = TimeStruct {
time_zone: 50,
year: datenow.year() as u16,
month: datenow.month() as u8,
day: datenow.day() as u8,
hour: datenow.hour() as u8,
minute: datenow.minute() as u8,
second: datenow.second() as u8,
millisecond: datenow.timestamp_subsec_millis() as u16,
};
spectraldata_reflectance.collection_time = nowtime.clone();
spectraldata_reflectance.ground_type = Target_Spectral_Type_FlatRef;
spectraldata_reflectance.valid_flag = 1;
spectraldata_reflectance.Set_Spectral_Data(reflectance_values, DATA_TYPE_FLOAT64);
oneirisdata.spectral_data_section.push(spectraldata_reflectance);
let spectraldata_devinfo = json!({
"info_type": "devinfo",
"sensor_id": devinfo["sensor_id"].as_str().unwrap_or("Unknown").to_string(),
"wave_coeff": {
"a1": devinfo["bochangxishu"]["a0"].as_f64().unwrap_or(0.0),
"a2": devinfo["bochangxishu"]["a1"].as_f64().unwrap_or(0.0),
"a3": devinfo["bochangxishu"]["a2"].as_f64().unwrap_or(0.0),
"a4": devinfo["bochangxishu"]["a3"].as_f64().unwrap_or(0.0)
}
});
println!("spectraldata_devinfo: {:?}", spectraldata_devinfo);
let environment_info = json!({
"info_type": "environment",
"date": format!("{}-{:02}-{:02} {:02}:{:02}:{:02}",
datenow.year(),
datenow.month(),
datenow.day(),
datenow.hour(),
datenow.minute(),
datenow.second()
)
});
oneirisdata.spectral_info_section.push(spectraldata_devinfo);
oneirisdata.spectral_info_section.push(environment_info);
match wirte_iris_data(&oneirisdata, &filepath) {
Ok(_) => "ok".to_string(),
Err(e) => format!("保存失败: {}", e)
}
}

View File

@ -0,0 +1,384 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use core::str;
use std::fs;
use std::fs::File;
use std::io::{Write};
// use std::sync::WaitTimeoutResult;
use std::path::Path;
use std::mem;
use super::mylog::*;
use super::serport::serport::*;
use super::mydefine::*;
pub fn savecalibratefile_iris(gain: Vec<f32>, shutter: u32, direction: bool, filepath: String) -> String {
let mut data = IS11DataStruct::default();
let lenthofgain = gain.len() ;
for i in 0..lenthofgain {
data.data[i] = gain[i];
}
data.shutter_time = shutter as u32;
data.direction = if direction { 1 } else { 0 };
data.datatype = 0x04;
let mut buffer = vec![0u8; mem::size_of::<IS11DataStruct>()];
// 序列化为二进制数据
unsafe {
let ptr = &data as *const IS11DataStruct as *const u8;
std::ptr::copy_nonoverlapping(ptr, buffer.as_mut_ptr(), mem::size_of::<IS11DataStruct>());
}
// 序列化为二进制数据
let file_path = Path::new(&filepath);
// 获取文件路径的父目录
if let Some(parent) = file_path.parent() {
// 确保父目录存在
if !parent.exists() {
fs::create_dir_all(parent).unwrap();
println!("父目录已创建: {:?}", parent);
} else {
println!("父目录已存在: {:?}", parent);
}
} else {
println!("文件路径没有父目录");
}
let mut file = File::create(filepath).unwrap();
file.write_all(&buffer).unwrap();
"OK".to_string()
}
pub fn sendcalibratetodev_iris(gain: Vec<f32>, shutter: u32, direction: bool) -> String {
let mut data = IS11DataStruct::default();
if gain.len() != data.data.len() {
logtorust(format!["Gain data length error"]);
return "Gain data length error".to_string();
}
data.data = gain.as_slice().try_into().unwrap();
data.shutter_time = shutter as u32;
data.direction = if direction { 1 } else { 0 };
data.datatype = 0x04;
let mut buffer = vec![0u8; mem::size_of::<IS11DataStruct>()];
// 序列化为二进制数据
unsafe {
let ptr = &data as *const IS11DataStruct as *const u8;
std::ptr::copy_nonoverlapping(ptr, buffer.as_mut_ptr(), mem::size_of::<IS11DataStruct>());
}
sendtoportbinary_iris(buffer, 0x03);
"OK".to_string()
}
pub fn sendtoportbinary_iris(data: Vec<u8>, command: u8) -> String {
let lenth = data.len() as u16;
let high: u8 = (lenth >> 8) as u8;
let low: u8 = (lenth & 0xFF) as u8;
let mut header = vec![];
header.push(0x55);
header.push(0xAA);
let mut crcbody = vec![];
// crcbody.push(high);
// crcbody.push(low);
crcbody.extend(data);
let crc = iris_calc_crc(&crcbody);
let crchigh: u8 = (crc >> 8) as u8;
let crclow: u8 = (crc & 0xFF) as u8;
let mut senddata = vec![];
senddata.extend(header);
senddata.push(command);
senddata.push(high);
senddata.push(low);
senddata.extend(crcbody);
senddata.push(crchigh);
senddata.push(crclow);
// println!("sendtoport data:{}",senddata.len());
println!(
"sendtoport data content:{:X?}",
senddata
.iter()
.map(|&byte| format!("{:02X}", byte))
.collect::<Vec<String>>()
.join(" ")
);
sendtoprot(senddata);
"send ok".to_string()
}
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
pub fn greet_iris(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
}
pub fn getportnames_iris() -> Vec<String> {
get_port_name()
}
pub fn opencom_iris(portname: serde_json::Value, baudrate: serde_json::Value) -> String {
//tauri
let portname = portname.as_str().unwrap();
let baudrate = baudrate.as_u64().unwrap() as u32;
set_port_info(&portname.to_string(), baudrate);
println!("opencom portname:{} baudrate:{}", portname, baudrate);
logtorust(format!(
"opencom portname:{} baudrate:{}",
portname, baudrate
));
tryuseport()
}
pub fn closecome_iris() -> String {
closeport()
}
pub fn sendtoport_iris(data: serde_json::Value, datatype: serde_json::Value) -> String {
// println!("sendtoport data:{}",data.to_string());
//判断是否存在data
// if !data.is_object() {
// return String::from("Invalid data");
// }
println!("sendtoport data:{}", data.to_string());
logtorust(format!("sendtoport data:{}", data.to_string()));
let data = data.to_string().as_bytes().to_vec();
let lenth = data.len() as u16;
let high: u8 = (lenth >> 8) as u8;
let low: u8 = (lenth & 0xFF) as u8;
let mut header = vec![];
header.push(0x55);
header.push(0xAA);
let mut command: u8 = 0;
let datatype = datatype.as_str().unwrap();
println!("datatype:{}", datatype);
if datatype == "hex" {
command = 0x03;
}
if datatype == "string" {
command = 0x01;
}
if datatype == "json" {
command = 0x00;
}
let mut crcbody = vec![];
// crcbody.push(high);
// crcbody.push(low);
crcbody.extend(data);
let crc = iris_calc_crc(&crcbody);
let crchigh: u8 = (crc >> 8) as u8;
let crclow: u8 = (crc & 0xFF) as u8;
let mut senddata = vec![];
senddata.extend(header);
senddata.push(command);
senddata.push(high);
senddata.push(low);
senddata.extend(crcbody);
senddata.push(crchigh);
senddata.push(crclow);
// println!("sendtoport data:{}",senddata.len());
// println!(
// "sendtoport data content:{:X?}",
// senddata
// .iter()
// .map(|&byte| format!("{:02X}", byte))
// .collect::<Vec<String>>()
// .join(" ")
// );
logtorust(format!(
"sendtoport data content:{:X?}",
senddata
.iter()
.map(|&byte| format!("{:02X}", byte))
.collect::<Vec<String>>()
.join(" ")
));
sendtoprot(senddata);
"send ok".to_string()
}
pub fn readformport_iris(commanid: serde_json::Value, wait_time_json: serde_json::Value) -> String {
let mut waittime = 50;
if wait_time_json.is_u64() {
waittime = wait_time_json.as_u64().unwrap() as u32;
}
let commanid = commanid.as_u64().unwrap() as u8;
let ret = readdatafromport(waittime as u64, commanid);
let str = String::from_utf8_lossy(&ret);
println!("read data: {}", str);
return str.to_string();
}
pub fn sendtoport_andgetreturn_iris(
data: serde_json::Value,
datatype: serde_json::Value,
) -> Result<RetStruct, String> {
// println!("sendtoport data:{}",data.to_string());
//判断是否存在data
// if !data.is_object() {
// return String::from("Invalid data");
// }
//println!("sendtoport data:{}", data.to_string());
let command = data.get("command").unwrap().to_string();
let mut isneedlog = true;
let mut isgetdata = false;
if command == "\"get_caiji_state\"" {
isneedlog = false;
}
if command == "\"get_data\"" {
isgetdata = true;
}
if isneedlog {
logtorust(format!("sendtoport data:{}", data.to_string()));
}
let data = data.to_string().as_bytes().to_vec();
let lenth = data.len() as u16;
let high: u8 = (lenth >> 8) as u8;
let low: u8 = (lenth & 0xFF) as u8;
let mut header = vec![];
header.push(0x55);
header.push(0xAA);
let mut command: u8 = 0;
let datatype = datatype.as_str().unwrap();
println!("datatype:{}", datatype);
if datatype == "hex" {
command = 0x03;
}
if datatype == "string" {
command = 0x01;
}
if datatype == "json" {
command = 0x00;
}
let mut crcbody = vec![];
// crcbody.push(high);
// crcbody.push(low);
crcbody.extend(data);
let crc = iris_calc_crc(&crcbody);
let crchigh: u8 = (crc >> 8) as u8;
let crclow: u8 = (crc & 0xFF) as u8;
let mut senddata = vec![];
senddata.extend(header);
senddata.push(command);
senddata.push(high);
senddata.push(low);
senddata.extend(crcbody);
senddata.push(crchigh);
senddata.push(crclow);
println!("sendtoport data:{}", senddata.len());
// println!(
// "sendtoport data content:{:X?}",
// senddata
// .iter()
// .map(|&byte| format!("{:02X}", byte))
// .collect::<Vec<String>>()
// .join(" ")
// );
if isneedlog {
logtorust(format!(
"sendtoport data content:{:X?}",
senddata
.iter()
.map(|&byte| format!("{:02X}", byte))
.collect::<Vec<String>>()
.join(" ")
));
}
sendtoprot(senddata);
let mut ret = readdatafromport(50, 0xff);
let datatype = ret[0];
if isneedlog {
if !isgetdata{
logtorust(format!(
"read content: {:X?}",
ret.iter()
.map(|&byte| format!("{:02X}", byte))
.collect::<Vec<String>>()
.join(" ")
));
}
}
if isgetdata{
logtorust("Get data Back SUCCESS".to_string());
logtorust("_____________________________one_data_over_____________________________\n".to_string());
}
ret.remove(0);
ret.remove(0);
ret.remove(0);
if datatype == 0x02 {
let mut is11data = IS11DataStruct::default();
unsafe {
let is11data_ptr = &mut is11data as *mut IS11DataStruct;
let ret_ptr = &mut ret[0] as *mut u8;
std::ptr::copy_nonoverlapping(
ret_ptr,
is11data_ptr as *mut u8,
std::mem::size_of::<IS11DataStruct>(),
);
return Ok(RetStruct {
datatype: datatype,
content: "null".to_string(),
data: is11data,
});
}
}
let str = String::from_utf8_lossy(&ret);
// println!("read data: {}", str);
if datatype==0x00 &&isneedlog {
logtorust(format![
"read string: {}",
str.to_string()
]);
}
return Ok(RetStruct {
datatype: datatype,
content: str.to_string(),
data: IS11DataStruct::default(),
});
// return str.to_string();
}
pub fn clearportbuff_iris() -> String {
clearserilport()
}
pub fn setport_iris(data: serde_json::Value) -> String {
//判断是否存在portname和baudrate
if !data.is_object() {
return String::from("Invalid data");
}
if !data["portname"].is_string() || !data["baudrate"].is_u64() {
return String::from("Invalid data");
}
let portname = data["portname"].as_str().unwrap();
let baudrate = data["baudrate"].as_u64().unwrap() as u32;
set_port_info(&portname.to_string(), baudrate);
//println!("{}",readdatafromport(1000));
String::from("Port set ok")
}

View File

@ -0,0 +1,108 @@
use libc::{c_uchar,c_char,c_long,c_float, size_t};
use std::ffi::CStr;
use std::slice;
use super::super::serport::serport::*;
#[repr(C)]
pub struct STRSensorInfo {
pub SensorName: [c_char; 100],
pub maxValue: c_long,
pub BandNum: c_long,
pub serialnumber: [c_char; 100],
pub a1: c_float,
pub a2: c_float,
pub a3: c_float,
pub a4: c_float,
pub issensorinit: c_uchar,
}
impl Default for STRSensorInfo {
fn default() -> Self {
STRSensorInfo {
SensorName: [0; 100],
maxValue: 0,
BandNum: 0,
serialnumber: [0; 100],
a1: 0.0,
a2: 0.0,
a3: 0.0,
a4: 0.0,
issensorinit: 0,
}
}
}
type SerialWrite = Option<unsafe extern "C" fn(data: *mut c_uchar, length: size_t) -> size_t>;
#[cfg_attr(target_os = "windows", link(name = "..\\myis11\\project\\is11\\cmake-build-release-visual-studio-2022/is11lib", kind = "dylib"))]
#[cfg_attr(target_os = "linux", link(name = "is11lib", kind = "dylib"))]
//#[link(name = "../myis11/project/is11/cmake-build-release-visual-studio-2022/is11lib",kind = "dylib")]
extern "C" {
fn Set_Serial_FUN(writefunc:SerialWrite,readfunc:SerialWrite);
fn abs1(input: i32) -> i32;
fn test();
fn IS11SensorInit() -> i32;
fn Get_SensorInfo() -> STRSensorInfo;
fn IS11OptSnenser(percent:i32) -> i32;
fn IS11GetData(outdata: *mut u16, shuttertime: i32) -> i32;
}
unsafe extern "C" fn serialsenddata(data: *mut c_uchar, length: size_t) -> size_t {
// 处理数据
let data_slice = slice::from_raw_parts(data, length as usize).to_vec();
// data_slice转换为Vec<u8>
// 打印数据
// for byte in data_slice.clone() {
// print!("{:02X} ", byte);
// }
// println!();
sendtoprot(data_slice);
length
}
use core::ptr;
unsafe extern "C" fn serialreaddate(data: *mut c_uchar, length: size_t) -> size_t {
let dataout=readforport();
let length1: usize = dataout.len();
// 将结果复制给c_uchar
// for byte in dataout.clone() {
// print!("{:02X} ", byte);
// }
// println!();
ptr::copy_nonoverlapping(dataout.as_ptr(), data, length1);
// println!("{:?}",data);
length1
}
pub fn is11_init() -> i32 {
unsafe {
Set_Serial_FUN(Some(serialsenddata), Some(serialreaddate));
IS11SensorInit()
}
}
pub fn is11_get_sensor_info() -> STRSensorInfo {
unsafe { Get_SensorInfo() }
}
pub fn _is11_opt_snenser(percent: i32) -> i32 {
unsafe { IS11OptSnenser(percent) }
}
pub fn is11_get_data(shuttertime: i32) -> Vec<u16> {
let mut outdata: Vec<u16> = vec![0; 2048];
unsafe {
let len = IS11GetData(outdata.as_mut_ptr(), shuttertime);
outdata.truncate(len as usize);
}
outdata
}

View File

@ -0,0 +1,367 @@
use super::is11base;
use super::super::mydefine::*;
use lazy_static::lazy_static;
use chrono::{self, format, Datelike, Timelike};
use std::thread;
#[derive(PartialEq)]
enum WorkStat {
IDLE,
WOKING,
STOP,
OPTING,
}
use std::{
sync::{Arc, Mutex},
};
struct is11_dev_data {
sensor_info: is11base::STRSensorInfo,
shuttertime: i32,
stat: WorkStat,
percent: i32,
workname: String,
hasdark: bool,
hasflat: bool,
removedark: bool,
computeflat: bool,
average_number_data: u32,
average_number_dark: u32,
average_number_flat: u32,
}
lazy_static! {
static ref DEV_STAT: Arc<Mutex<is11_dev_data>> = Arc::new(Mutex::new(is11_dev_data {
sensor_info: is11base::STRSensorInfo::default(),
shuttertime: 0,
stat: WorkStat::IDLE,
percent: 0,
workname: "noting".to_string(),
hasdark: false,
hasflat: false,
removedark: false,
computeflat: true,
average_number_data: 1,
average_number_dark: 1,
average_number_flat: 1,
}));
}
// lazy_static! {
// static ref DATA: Arc<Mutex<Vec<u16>>> = Arc::new(Mutex::new(Vec::new()));
// }
lazy_static! {
static ref DATA_IS11: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
static ref DARK_DATA: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
static ref FLAT_DATA: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
}
pub fn get_shuttertime() -> i32 {
let dev_stat=DEV_STAT.lock().unwrap();
return dev_stat.shuttertime;
}
pub fn opt_sensor(percent: i32) -> i32 {
let mut dev_stat=DEV_STAT.lock().unwrap();
if dev_stat.stat != WorkStat::IDLE {
return -1;
}
dev_stat.stat=WorkStat::OPTING;
dev_stat.percent=0;
dev_stat.workname="opting".to_string();
drop(dev_stat); //释放锁
thread::spawn(move || {
let shuttertime= is11base::_is11_opt_snenser(90); //多线程设置曝光时间
let mut dev_statnow=DEV_STAT.lock().unwrap();
dev_statnow.stat=WorkStat::IDLE;
dev_statnow.shuttertime=shuttertime;
dev_statnow.workname="finish".to_string();
dev_statnow.percent=100;
dev_statnow.hasdark=false;
dev_statnow.hasflat=false;
}
);
return 0;
}
pub fn get_now_stat()->(String,String,i32){
let mut dev_stat=DEV_STAT.lock().unwrap();
match dev_stat.stat {
WorkStat::IDLE => {
return ("finish".to_string(),dev_stat.workname.clone(),100);
},
WorkStat::WOKING => {
return ("working".to_string(),dev_stat.workname.clone(),dev_stat.percent);
},
WorkStat::STOP => {
return ("finish".to_string(),dev_stat.workname.clone(),dev_stat.percent);
},
WorkStat::OPTING => {
return ("opting".to_string(),dev_stat.workname.clone(),dev_stat.percent);
},
}
}
pub fn collect(shuttertime:u32,removedark:bool,computeflat:bool){
let mut dev_stat=DEV_STAT.lock().unwrap();
if dev_stat.stat != WorkStat::IDLE {
return ;
}
let averagenumber=dev_stat.average_number_data;
dev_stat.stat=WorkStat::WOKING;
dev_stat.percent=0;
dev_stat.workname="采集中".to_string();
drop(dev_stat); //释放锁
thread::spawn(move || {
let mut datasum:Vec<u32>=vec![0;2048];
for _i in 0..averagenumber {
let data=is11base::is11_get_data(shuttertime as i32);
for i in 0..2048 {
datasum[i]=datasum[i]+data[i] as u32;
}
let mut dev_stat=DEV_STAT.lock().unwrap();
let info=format!("采集中,{}%",_i as f32/averagenumber as f32*100 as f32*0.9);
dev_stat.workname=info;
dev_stat.percent=((_i+1) as f32/averagenumber as f32*100 as f32*0.9) as i32;
drop(dev_stat); //释放锁
}
let data=datasum.iter().map(|x| *x as f32/averagenumber as f32).collect::<Vec<f32>>();
let mut dev_stat=DEV_STAT.lock().unwrap();
let _lenth=data.len();
println!("data len={}",_lenth);
let mut tempis11data=IS11DataStruct::default();
for i in 0.._lenth {
tempis11data.data[i]=data[i] as f32;
}
// 获取当前时间
let now = chrono::Local::now();
tempis11data.year=(now.year()-2000) as u8;
tempis11data.month=now.month() as u8;
tempis11data.day=now.day() as u8;
tempis11data.hour=now.hour() as u8;
tempis11data.minute=now.minute() as u8;
tempis11data.second=now.second() as u8;
tempis11data.shutter_time=shuttertime;
tempis11data.index=0;
tempis11data.datatype=0;
let mut data1=DATA_IS11.lock().unwrap();
let darkdata=DARK_DATA.lock().unwrap();
*data1=tempis11data;
if removedark && dev_stat.hasdark {
for i in 0.._lenth {
data1.data[i]=data1.data[i]-darkdata.data[i];
}
}
if computeflat && dev_stat.hasflat {
let flatdata=FLAT_DATA.lock().unwrap();
for i in 0.._lenth {
let temp=flatdata.data[i]-darkdata.data[i];
if temp<=0.0 {
data1.data[i]=10000.0;
}else{
data1.data[i]=data1.data[i]/temp*10000.0;
}
if data1.data[i]<0.0 {
data1.data[i]=0.0;
}
if data1.data[i]>15000.0 {
data1.data[i]=15000.0;
}
// data1.data[i]=data1.data[i]/(flatdata.data[i]-darkdata.data[i])*10000.0;
}
}
dev_stat.stat=WorkStat::IDLE;
dev_stat.percent=100;
dev_stat.workname="finish".to_string();
});
}
pub fn collcect_dark(shuttertime:u32)
{
let mut dev_stat=DEV_STAT.lock().unwrap();
if dev_stat.stat != WorkStat::IDLE {
return ;
}
let averagenumber=dev_stat.average_number_dark;
dev_stat.stat=WorkStat::WOKING;
dev_stat.percent=0;
dev_stat.workname="采集Dark中".to_string();
drop(dev_stat); //释放锁
thread::spawn(move || {
let mut datasum:Vec<u32>=vec![0;2048];
for _i in 0..averagenumber {
let data=is11base::is11_get_data(shuttertime as i32);
for i in 0..2048 {
datasum[i]=datasum[i]+data[i] as u32;
}
let mut dev_stat=DEV_STAT.lock().unwrap();
let info=format!("采集Dark中,{}%",_i as f32/averagenumber as f32*100 as f32*0.9);
dev_stat.workname=info;
dev_stat.percent=((_i+1) as f32/averagenumber as f32*100 as f32*0.9) as i32;
drop(dev_stat); //释放锁
}
let data=datasum.iter().map(|x| *x as f32/averagenumber as f32).collect::<Vec<f32>>();
let mut dev_stat=DEV_STAT.lock().unwrap();
let _lenth=data.len();
println!("data len={}",_lenth);
let mut tempis11data=IS11DataStruct::default();
for i in 0.._lenth {
tempis11data.data[i]=data[i] as f32;
}
//获取当前时间
let now = chrono::Local::now();
tempis11data.year=(now.year()-2000) as u8;
tempis11data.month=now.month() as u8;
tempis11data.day=now.day() as u8;
tempis11data.hour=now.hour() as u8;
tempis11data.minute=now.minute() as u8;
tempis11data.second=now.second() as u8;
tempis11data.shutter_time=shuttertime;
tempis11data.index=0;
tempis11data.datatype=0;
let mut data1=DARK_DATA.lock().unwrap();
*data1=tempis11data;
dev_stat.stat=WorkStat::IDLE;
dev_stat.percent=100;
dev_stat.workname="finish".to_string();
dev_stat.hasdark=true;
});
}
pub fn collcect_flat(shuttertime:u32)
{
let mut dev_stat=DEV_STAT.lock().unwrap();
if dev_stat.stat != WorkStat::IDLE {
return ;
}
let averagenumber=dev_stat.average_number_flat;
dev_stat.stat=WorkStat::WOKING;
dev_stat.percent=0;
dev_stat.workname="采集中".to_string();
drop(dev_stat); //释放锁
thread::spawn(move || {
let mut datasum:Vec<u32>=vec![0;2048];
for _i in 0..averagenumber {
let data=is11base::is11_get_data(shuttertime as i32);
for i in 0..2048 {
datasum[i]=datasum[i]+data[i] as u32;
}
let mut dev_stat=DEV_STAT.lock().unwrap();
let info=format!("采集白板中,{}%",_i as f32/averagenumber as f32*100 as f32*0.9);
dev_stat.workname=info;
dev_stat.percent=((_i+1) as f32/averagenumber as f32*100 as f32*0.9) as i32;
drop(dev_stat); //释放锁
}
let data=datasum.iter().map(|x| *x as f32/averagenumber as f32).collect::<Vec<f32>>();
let mut dev_stat=DEV_STAT.lock().unwrap();
let _lenth=data.len();
println!("data len={}",_lenth);
let mut tempis11data=IS11DataStruct::default();
for i in 0.._lenth {
tempis11data.data[i]=data[i] as f32;
}
//获取当前时间
let now = chrono::Local::now();
tempis11data.year=(now.year()-2000) as u8;
tempis11data.month=now.month() as u8;
tempis11data.day=now.day() as u8;
tempis11data.hour=now.hour() as u8;
tempis11data.minute=now.minute() as u8;
tempis11data.second=now.second() as u8;
tempis11data.shutter_time=shuttertime;
tempis11data.index=0;
tempis11data.datatype=0;
let mut data1=FLAT_DATA.lock().unwrap();
*data1=tempis11data;
dev_stat.stat=WorkStat::IDLE;
dev_stat.percent=100;
dev_stat.workname="finish".to_string();
dev_stat.hasflat=true;
});
}
pub fn get_data()->IS11DataStruct{
let data1=DATA_IS11.lock().unwrap();
return data1.clone();
}
pub fn get_data_flat()->IS11DataStruct{
let data1=FLAT_DATA.lock().unwrap();
return data1.clone();
}
pub fn get_data_dark()->IS11DataStruct{
let data1=DARK_DATA.lock().unwrap();
return data1.clone();
}
pub fn get_is_computeref()->bool{
let dev_stat=DEV_STAT.lock().unwrap();
return dev_stat.computeflat;
}
pub fn set_shutter_time(shuttertime:u32){
let mut dev_stat=DEV_STAT.lock().unwrap();
dev_stat.shuttertime=shuttertime as i32;
dev_stat.hasdark=false;
dev_stat.hasflat=false;
}
pub fn set_average_number(arverage_number_data:u32,arverage_number_dark:u32,arverage_number_flat:u32){
let mut dev_stat=DEV_STAT.lock().unwrap();
dev_stat.average_number_data=arverage_number_data;
dev_stat.average_number_dark=arverage_number_dark;
dev_stat.average_number_flat=arverage_number_flat;
}

View File

@ -0,0 +1,322 @@
use super::mydefine::*;
pub mod is11base;
pub mod is11server;
use super::mylog::*;
use is11server::get_shuttertime;
use serde_json::json;
use std::ffi::CStr;
pub fn sendtoport_andgetreturn(
data: serde_json::Value,
datatype: serde_json::Value,
) -> Result<RetStruct, String> {
let command = data.get("command").unwrap().to_string();
println!("start_collect data:{}", data.to_string());
match command.as_str() {
"\"start_collect_flat\"" => {
return start_collect_flat(data, datatype);
},
"\"start_collect_dark\"" => {
return start_collect_dark(data, datatype);
},
"\"get_sensor_info\"" => {
is11base::is11_init();
logtorust("init is11 ok".to_string());
let sensor_info = is11base::is11_get_sensor_info();
let sensor_name_cstr = unsafe { CStr::from_ptr(sensor_info.SensorName.as_ptr()) };
let sensor_name = sensor_name_cstr.to_str().unwrap();
let serilnumber_cstr = unsafe { CStr::from_ptr(sensor_info.serialnumber.as_ptr()) };
let serilnumber = serilnumber_cstr.to_str().unwrap();
//定义一个json对象
let jsonforret = json!({
"bochangxishu":{
"a0":sensor_info.a1,
"a1":sensor_info.a2,
"a2":sensor_info.a3,
"a3":sensor_info.a4,
},
"serialnumber":serilnumber,
"name":"IS11",
// "name":sensor_name,
"version":"1.0.0",
"return_data_type":0,
"work_mode":"advanced_mode",
"sensor":"JZ-IS11",
});
logtorust(format!("get_sensor_info:{}", jsonforret.to_string()));
return Ok(RetStruct {
datatype: 0,
content: jsonforret.to_string(),
data: IS11DataStruct::default(),
});
}
"\"start_opt\"" => {
is11server::opt_sensor(90);
let jsonforret = json!({
"command":"start_opt"
});
return Ok(RetStruct {
datatype: 0,
content: jsonforret.to_string(),
data: IS11DataStruct::default(),
});
}
"\"get_opt\"" => {
println!("get_opt");
let ret = get_opt_result();
return ret;
}
"\"start_collect\"" => {
return start_collect(data, datatype);
}
"\"get_caiji_state\"" => {
let (caiji_state, caiji_state_str,percent) = is11server::get_now_stat();
let jsonforret = json!({
"caiji_state":caiji_state,
"info":caiji_state_str,
"percent":percent,
"return_data_type":0,
});
logtorust(format!("get_caiji_state:{}", jsonforret.to_string()));
return Ok(RetStruct {
datatype: 0,
content: jsonforret.to_string(),
data: IS11DataStruct::default(),
});
}
"\"get_data\"" => {
return get_data(data, datatype);
},
"\"get_data_flat\"" => {
return get_data_flat(data, datatype);
},
"\"get_data_dark\"" => {
return get_data_dark(data, datatype);
},
"\"set_shutter_time\"" => {
return set_shutter_time(data, datatype);
},
_ => {
return Err("command not found ".to_string() + "command is:" + &command);
}
}
}
pub fn get_opt_result() -> Result<RetStruct, String> {
let shuttertime = is11server::get_shuttertime();
let jsonret = json!({
"opt":shuttertime,
});
return Ok(RetStruct {
datatype: 0,
content: jsonret.to_string(),
data: IS11DataStruct::default(),
});
}
pub fn set_shutter_time(data: serde_json::Value,
datatype: serde_json::Value) -> Result<RetStruct, String> {
let shuttertime: u32;
if data.get("shutter_time").is_none() {
shuttertime = get_shuttertime() as u32;
} else {
shuttertime = data.get("shutter_time").unwrap().as_u64().unwrap() as u32;
is11server::set_shutter_time(shuttertime);
}
let jsonret = json!({
"shuttertime":"ok",
});
return Ok(RetStruct {
datatype: 0,
content: jsonret.to_string(),
data: IS11DataStruct::default(),
});
}
pub fn start_collect(
data: serde_json::Value,
datatype: serde_json::Value,
) -> Result<RetStruct, String> {
let shuttertime: u32;
if data.get("shutter_time").is_none() {
shuttertime = get_shuttertime() as u32;
} else {
shuttertime = data.get("shutter_time").unwrap().as_u64().unwrap() as u32;
}
//判断是否有这个参数
let removedark: bool;
if data.get("remove_dark").is_none() {
removedark = false;
} else {
if data.get("remove_dark").unwrap().is_boolean() {
removedark = data.get("remove_dark").unwrap().as_bool().unwrap();
} else if data.get("remove_dark").unwrap().is_string() {
let remove_dark_str = data.get("remove_dark").unwrap().as_str().unwrap();
if remove_dark_str == "yes" {
removedark = true;
} else {
removedark = false;
}
} else {
removedark = false;
}
}
let computeflat = is11server::get_is_computeref();
logtorust(format!("start_collect,shutter time is:{}", shuttertime));
if !data.get("collect_times").is_none() {
if data.get("collect_times").unwrap().is_u64() {
let collect_times = data.get("collect_times").unwrap().as_u64().unwrap() as u32;
is11server::set_average_number(collect_times,collect_times,collect_times );
}
}
is11server::collect(shuttertime, removedark, computeflat);
let jsonret = json!({
"command":"start_collect"
});
return Ok(RetStruct {
datatype: 0,
content: jsonret.to_string(),
data: IS11DataStruct::default(),
});
}
pub fn start_collect_dark(
data: serde_json::Value,
datatype: serde_json::Value,
) -> Result<RetStruct, String> {
let shuttertime: u32;
if data.get("shutter_time").is_none() {
shuttertime = get_shuttertime() as u32;
} else {
shuttertime = data.get("shutter_time").unwrap().as_u64().unwrap() as u32;
}
//判断是否有这个参数
if !data.get("collect_times").is_none() {
if data.get("collect_times").unwrap().is_u64() {
let collect_times = data.get("collect_times").unwrap().as_u64().unwrap() as u32;
is11server::set_average_number(collect_times,collect_times,collect_times );
}
}
is11server::collcect_dark(shuttertime);
let jsonret = json!({
"command":"start_collect_dark"
});
return Ok(RetStruct {
datatype: 0,
content: jsonret.to_string(),
data: IS11DataStruct::default(),
});
}
pub fn start_collect_flat(
data: serde_json::Value,
datatype: serde_json::Value,
) -> Result<RetStruct, String> {
let shuttertime: u32;
if data.get("shutter_time").is_none() {
shuttertime = get_shuttertime() as u32;
} else {
shuttertime = data.get("shutter_time").unwrap().as_u64().unwrap() as u32;
}
//判断是否有这个参数
if !data.get("collect_times").is_none() {
if data.get("collect_times").unwrap().is_u64() {
let collect_times = data.get("collect_times").unwrap().as_u64().unwrap() as u32;
is11server::set_average_number(collect_times,collect_times,collect_times );
}
}
is11server::collcect_flat(shuttertime);
let jsonret = json!({
"command":"start_collect_flat"
});
return Ok(RetStruct {
datatype: 0,
content: jsonret.to_string(),
data: IS11DataStruct::default(),
});
}
pub fn get_data(data: serde_json::Value, datatype: serde_json::Value) -> Result<RetStruct, String> {
let is11_data = is11server::get_data();
let jsonret = json!({
"command":"get_data"
});
return Ok(RetStruct {
datatype: 2,
content: jsonret.to_string(),
data: is11_data,
});
}
pub fn get_data_flat(data: serde_json::Value, datatype: serde_json::Value) -> Result<RetStruct, String> {
let is11_data = is11server::get_data_flat();
let jsonret = json!({
"command":"get_data_flat"
});
return Ok(RetStruct {
datatype: 2,
content: jsonret.to_string(),
data: is11_data,
});
}
pub fn get_data_dark(data: serde_json::Value, datatype: serde_json::Value) -> Result<RetStruct, String> {
let is11_data = is11server::get_data_dark();
let jsonret = json!({
"command":"get_data_dark"
});
return Ok(RetStruct {
datatype: 2,
content: jsonret.to_string(),
data: is11_data,
});
}

View File

@ -1,405 +1,36 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!! // Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use core::str; mod irisdatamanager;
use serialport::new;
use std::ffi::c_float;
use std::fmt::format;
use std::fs;
use std::fs::File;
use std::io::{self, Read, Write};
// use std::sync::WaitTimeoutResult;
use std::path::Path;
mod algorithm; mod algorithm;
mod mylog; mod mylog;
mod serport; mod serport;
mod iris_spectral;
mod irishypersptral;
mod mydefine;
mod comman1;
mod myformatiris;
use comman1::*;
use algorithm::interpolate_spline; use algorithm::interpolate_spline;
use algorithm::sg_smooth; use algorithm::sg_smooth;
use std::mem; use mydefine::*;
use iris_spectral::spectralbase::Senortype;
use myformatiris::getoneirisfile;
enum DevName {
IRIS_IS11,
IRIS_SENSOR(Senortype),
use mylog::*; }
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
use serport::serport::*;
#[derive(Serialize, Deserialize)] use lazy_static::lazy_static;
struct RetStruct { use tauri::api::dir;
datatype: u8, use std::sync::Mutex;
content: String, //设置一个可修改的全局变量
data: IS11DataStruct, lazy_static! {
} static ref DEVNAME: Mutex<DevName> = Mutex::new(DevName::IRIS_SENSOR(Senortype::IS3));
#[serde_as]
#[derive(Serialize, Deserialize)]
#[repr(C)]
struct IS11DataStruct {
datatype: u8, // Using r# to allow the use of the keyword 'type'
direction: u8,
tuigan_stat: u8,
shutter_time: u32,
index: u64,
temprature: [f32; 8],
#[serde_as(as = "[_; 2048]")]
data: [f32; 2048],
}
impl Default for IS11DataStruct {
fn default() -> Self {
IS11DataStruct {
datatype: 0,
direction: 10,
tuigan_stat: 0,
shutter_time: 0,
index: 0,
temprature: [0.0; 8],
data: [0.0; 2048],
}
}
} }
#[tauri::command] #[tauri::command]
fn savecalibratefile(Gain: Vec<f32>, shutter: u32, direction: bool, filepath: String) -> String { fn setport(data: serde_json::Value) -> String {
let mut data = IS11DataStruct::default();
data.data = Gain.as_slice().try_into().unwrap();
data.shutter_time = shutter as u32;
data.direction = if direction { 1 } else { 0 };
data.datatype = 0x04;
let mut buffer = vec![0u8; mem::size_of::<IS11DataStruct>()];
// 序列化为二进制数据
unsafe {
let ptr = &data as *const IS11DataStruct as *const u8;
std::ptr::copy_nonoverlapping(ptr, buffer.as_mut_ptr(), mem::size_of::<IS11DataStruct>());
}
// 序列化为二进制数据
let file_path = Path::new(&filepath);
// 获取文件路径的父目录
if let Some(parent) = file_path.parent() {
// 确保父目录存在
if !parent.exists() {
fs::create_dir_all(parent).unwrap();
println!("父目录已创建: {:?}", parent);
} else {
println!("父目录已存在: {:?}", parent);
}
} else {
println!("文件路径没有父目录");
}
let mut file = File::create(filepath).unwrap();
file.write_all(&buffer).unwrap();
"OK".to_string()
}
#[tauri::command]
fn sendcalibratetodev(Gain: Vec<f32>, shutter: u32, direction: bool) -> String {
let mut data = IS11DataStruct::default();
data.data = Gain.as_slice().try_into().unwrap();
data.shutter_time = shutter as u32;
data.direction = if direction { 1 } else { 0 };
data.datatype = 0x04;
let mut buffer = vec![0u8; mem::size_of::<IS11DataStruct>()];
// 序列化为二进制数据
unsafe {
let ptr = &data as *const IS11DataStruct as *const u8;
std::ptr::copy_nonoverlapping(ptr, buffer.as_mut_ptr(), mem::size_of::<IS11DataStruct>());
}
sendtoportbinary(buffer, 0x03);
"OK".to_string()
}
fn sendtoportbinary(data: Vec<u8>, command: u8) -> String {
let lenth = data.len() as u16;
let high: u8 = (lenth >> 8) as u8;
let low: u8 = (lenth & 0xFF) as u8;
let mut header = vec![];
header.push(0x55);
header.push(0xAA);
let mut crcbody = vec![];
// crcbody.push(high);
// crcbody.push(low);
crcbody.extend(data);
let crc = iris_calc_crc(&crcbody);
let crchigh: u8 = (crc >> 8) as u8;
let crclow: u8 = (crc & 0xFF) as u8;
let mut senddata = vec![];
senddata.extend(header);
senddata.push(command);
senddata.push(high);
senddata.push(low);
senddata.extend(crcbody);
senddata.push(crchigh);
senddata.push(crclow);
// println!("sendtoport data:{}",senddata.len());
println!(
"sendtoport data content:{:X?}",
senddata
.iter()
.map(|&byte| format!("{:02X}", byte))
.collect::<Vec<String>>()
.join(" ")
);
sendtoprot(senddata);
"send ok".to_string()
}
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
}
#[tauri::command]
fn getportnames() -> Vec<String> {
get_port_name()
}
#[tauri::command]
fn opencom(portname: serde_json::Value, baudrate: serde_json::Value) -> String {
//tauri
let portname = portname.as_str().unwrap();
let baudrate = baudrate.as_u64().unwrap() as u32;
set_port_info(&portname.to_string(), baudrate);
println!("opencom portname:{} baudrate:{}", portname, baudrate);
logtorust(format!(
"opencom portname:{} baudrate:{}",
portname, baudrate
));
tryuseport()
}
#[tauri::command]
fn closecome() -> String {
closeport()
}
#[tauri::command]
fn sendtoport(data: serde_json::Value, datatype: serde_json::Value) -> String {
// println!("sendtoport data:{}",data.to_string());
//判断是否存在data
// if !data.is_object() {
// return String::from("Invalid data");
// }
println!("sendtoport data:{}", data.to_string());
logtorust(format!("sendtoport data:{}", data.to_string()));
let data = data.to_string().as_bytes().to_vec();
let lenth = data.len() as u16;
let high: u8 = (lenth >> 8) as u8;
let low: u8 = (lenth & 0xFF) as u8;
let mut header = vec![];
header.push(0x55);
header.push(0xAA);
let mut command: u8 = 0;
let datatype = datatype.as_str().unwrap();
println!("datatype:{}", datatype);
if datatype == "hex" {
command = 0x03;
}
if datatype == "string" {
command = 0x01;
}
if datatype == "json" {
command = 0x00;
}
let mut crcbody = vec![];
// crcbody.push(high);
// crcbody.push(low);
crcbody.extend(data);
let crc = iris_calc_crc(&crcbody);
let crchigh: u8 = (crc >> 8) as u8;
let crclow: u8 = (crc & 0xFF) as u8;
let mut senddata = vec![];
senddata.extend(header);
senddata.push(command);
senddata.push(high);
senddata.push(low);
senddata.extend(crcbody);
senddata.push(crchigh);
senddata.push(crclow);
// println!("sendtoport data:{}",senddata.len());
// println!(
// "sendtoport data content:{:X?}",
// senddata
// .iter()
// .map(|&byte| format!("{:02X}", byte))
// .collect::<Vec<String>>()
// .join(" ")
// );
logtorust(format!(
"sendtoport data content:{:X?}",
senddata
.iter()
.map(|&byte| format!("{:02X}", byte))
.collect::<Vec<String>>()
.join(" ")
));
sendtoprot(senddata);
"send ok".to_string()
}
#[tauri::command]
fn readformport(commanid: serde_json::Value, wait_time_json: serde_json::Value) -> String {
let mut waittime = 50;
if wait_time_json.is_u64() {
waittime = wait_time_json.as_u64().unwrap() as u32;
}
let commanid = commanid.as_u64().unwrap() as u8;
let ret = readdatafromport(waittime as u64, commanid);
let str = String::from_utf8_lossy(&ret);
println!("read data: {}", str);
return str.to_string();
}
#[tauri::command]
fn sendtoportAndgetreturn(
data: serde_json::Value,
datatype: serde_json::Value,
) -> Result<RetStruct, String> {
// println!("sendtoport data:{}",data.to_string());
//判断是否存在data
// if !data.is_object() {
// return String::from("Invalid data");
// }
//println!("sendtoport data:{}", data.to_string());
let command = data.get("command").unwrap().to_string();
let mut isneedlog = true;
let mut isgetdata = false;
if command == "\"get_caiji_state\"" {
isneedlog = false;
}
if command == "\"get_data\"" {
isgetdata = true;
}
if isneedlog {
logtorust(format!("sendtoport data:{}", data.to_string()));
}
let data = data.to_string().as_bytes().to_vec();
let lenth = data.len() as u16;
let high: u8 = (lenth >> 8) as u8;
let low: u8 = (lenth & 0xFF) as u8;
let mut header = vec![];
header.push(0x55);
header.push(0xAA);
let mut command: u8 = 0;
let datatype = datatype.as_str().unwrap();
println!("datatype:{}", datatype);
if datatype == "hex" {
command = 0x03;
}
if datatype == "string" {
command = 0x01;
}
if datatype == "json" {
command = 0x00;
}
let mut crcbody = vec![];
// crcbody.push(high);
// crcbody.push(low);
crcbody.extend(data);
let crc = iris_calc_crc(&crcbody);
let crchigh: u8 = (crc >> 8) as u8;
let crclow: u8 = (crc & 0xFF) as u8;
let mut senddata = vec![];
senddata.extend(header);
senddata.push(command);
senddata.push(high);
senddata.push(low);
senddata.extend(crcbody);
senddata.push(crchigh);
senddata.push(crclow);
println!("sendtoport data:{}", senddata.len());
// println!(
// "sendtoport data content:{:X?}",
// senddata
// .iter()
// .map(|&byte| format!("{:02X}", byte))
// .collect::<Vec<String>>()
// .join(" ")
// );
if isneedlog {
logtorust(format!(
"sendtoport data content:{:X?}",
senddata
.iter()
.map(|&byte| format!("{:02X}", byte))
.collect::<Vec<String>>()
.join(" ")
));
}
sendtoprot(senddata);
let mut ret = readdatafromport(50, 0xff);
let datatype = ret[0];
if isneedlog {
if !isgetdata{
logtorust(format!(
"read content: {:X?}",
ret.iter()
.map(|&byte| format!("{:02X}", byte))
.collect::<Vec<String>>()
.join(" ")
));
}
}
if isgetdata{
logtorust("Get data Back SUCCESS".to_string());
logtorust("_____________________________one_data_over_____________________________\n".to_string());
}
ret.remove(0);
ret.remove(0);
ret.remove(0);
if datatype == 0x02 {
let mut is11data = IS11DataStruct::default();
unsafe {
let mut is11data_ptr = &mut is11data as *mut IS11DataStruct;
let mut ret_ptr = &mut ret[0] as *mut u8;
std::ptr::copy_nonoverlapping(
ret_ptr,
is11data_ptr as *mut u8,
std::mem::size_of::<IS11DataStruct>(),
);
return Ok(RetStruct {
datatype: datatype,
content: "null".to_string(),
data: is11data,
});
}
}
let str = String::from_utf8_lossy(&ret);
// println!("read data: {}", str);
if datatype==0x00 &&isneedlog {
logtorust(format![
"read string: {}",
str.to_string()
]);
}
return Ok(RetStruct {
datatype: datatype,
content: str.to_string(),
data: IS11DataStruct::default(),
});
// return str.to_string();
}
#[tauri::command]
fn clearportbuff() -> String {
clearserilport()
}
#[tauri::command]
fn setport(data: serde_json::Value) -> String {
//判断是否存在portname和baudrate //判断是否存在portname和baudrate
if !data.is_object() { if !data.is_object() {
return String::from("Invalid data"); return String::from("Invalid data");
@ -409,10 +40,188 @@ fn setport(data: serde_json::Value) -> String {
} }
let portname = data["portname"].as_str().unwrap(); let portname = data["portname"].as_str().unwrap();
let baudrate = data["baudrate"].as_u64().unwrap() as u32; let baudrate = data["baudrate"].as_u64().unwrap() as u32;
set_port_info(&portname.to_string(), baudrate); serport::serport::set_port_info(&portname.to_string(), baudrate);
//println!("{}",readdatafromport(1000)); //println!("{}",readdatafromport(1000));
String::from("Port set ok") String::from("Port set ok")
} }
/* let data = {
gain: Gain,
direction: direction,
filepath: Filepath,
DNData: DNData,
LampData: Lampdata,
Devinfo: Devinfo
} */
#[tauri::command]
fn savecalibratefileIRIS(Gain:serde_json::Value,direction: bool, filepath: String, dndata: serde_json::Value, lampdata: serde_json::Value, devinfo: serde_json::Value) -> String {
//输出 输入参数
// println!("Gain: {:?}", Gain);
// println!("direction: {:?}", direction);
// println!("Filepath: {:?}", devinfo);
// println!("DNData: {:?}", dndata);
// println!("Lampdata: {:?}", lampdata);
// println!("Devinfo: {:?}", devinfo);
irisdatamanager::savecalibratefileIRIS(Gain, direction, filepath, dndata, lampdata, devinfo)
}
#[tauri::command]
fn savecalibratefile(gain: Vec<f32>, shutter: u32, direction: bool, filepath: String) -> String {
let devname=DEVNAME.lock().unwrap();
match *devname {
DevName::IRIS_IS11=>{
return irishypersptral::savecalibratefile_iris(gain, shutter, direction, filepath);
},
DevName::IRIS_SENSOR(sensor_type)=>{
return irishypersptral::savecalibratefile_iris(gain, shutter, direction, filepath);
//return jianzhiis11::s(gain, shutter, direction, filepath);
}
}
//irishypersptral::savecalibratefile_iris(gain, shutter, direction, filepath)
}
#[tauri::command]
fn sendcalibratetodev(gain: Vec<f32>, shutter: u32, direction: u32) -> String {
let devname=DEVNAME.lock().unwrap();
println!("sendcalibratetodev");
match *devname {
DevName::IRIS_IS11=>{
return irishypersptral::sendcalibratetodev_iris(gain, shutter, direction !=0);
},
DevName::IRIS_SENSOR(sensor_type)=>{
return irishypersptral::sendcalibratetodev_iris(gain, shutter, direction !=0);
//return jianzhiis11::s(gain, shutter, direction, filepath);
}
}
//irishypersptral::sendcalibratetodev_iris(gain, shutter, direction)
}
#[tauri::command]
fn setdevtype(devtype: String)->String {
let mut devname1 = DEVNAME.lock().unwrap();
match devtype.as_str() {
"IRIS-IS11" => *devname1 = DevName::IRIS_IS11,
"IS3" => *devname1 = DevName::IRIS_SENSOR(Senortype::IS3),
"IS11" => *devname1 = DevName::IRIS_SENSOR(Senortype::IS11),
_ => *devname1 = DevName::IRIS_SENSOR(Senortype::IS3),
}
mylog::logtorust("set dev to ".to_string()+&devtype);
return "ok".to_string();
}
#[tauri::command]
fn __sendto_portbinary(data: Vec<u8>, command: u8) -> String {
irishypersptral::sendtoportbinary_iris(data, command)
}
#[tauri::command]
fn sendtoport(data: serde_json::Value, datatype: serde_json::Value) -> String {
irishypersptral::sendtoport_iris(data, datatype)
}
#[tauri::command]
fn readformport(commanid: serde_json::Value, wait_time_json: serde_json::Value) -> String {
irishypersptral::readformport_iris(commanid, wait_time_json)
}
#[tauri::command]
fn set_weave_coeff(specnumber: i32, a0: f64, a1: f64, a2: f64, a3: f64) -> String {
let devname=DEVNAME.lock().unwrap();
match *devname{
DevName::IRIS_SENSOR(sensor_type) =>{
iris_spectral::set_weave_coeff(specnumber, a0, a1, a2, a3);
} ,
_ => {},
}
"OK".to_string()
}
#[tauri::command]
fn opencom(portname: serde_json::Value, baudrate: serde_json::Value) -> String {
//tauri
let portname = portname.as_str().unwrap();
let devname=DEVNAME.lock().unwrap();
let mut baudrate :u32=0;
match *devname {
DevName::IRIS_IS11=>{
baudrate =115200 as u32;
},
DevName::IRIS_SENSOR(sensor_type)=>{
baudrate =921600 as u32;
}
}
// let baudrate = baudrate.as_u64().unwrap() as u32;
serport::serport::set_port_info(&portname.to_string(), baudrate);
println!("opencom portname:{} baudrate:{}", portname, baudrate);
mylog::logtorust(format!(
"opencom portname:{} baudrate:{}",
portname, baudrate
));
serport::serport::tryuseport()
}
#[tauri::command]
fn sendtoport_andgetreturn(
data: serde_json::Value,
datatype: serde_json::Value,
) -> Result<RetStruct, String> {
//irishypersptral::sendtoport_andgetreturn_iris(data, datatype)
//irishypersptral::sendtoport_andgetreturn_iris(data, datatype)
let devname=DEVNAME.lock().unwrap();
match *devname {
DevName::IRIS_IS11=>{
return irishypersptral::sendtoport_andgetreturn_iris(data, datatype);
},
DevName::IRIS_SENSOR(sensor_type)=>{
return iris_spectral::sendtoport_andgetreturn(data, datatype);
}
}
//jianzhiis11::sendtoport_andgetreturn(data, datatype)
}
#[tauri::command]
fn delete_file_by_path(filepath: String) -> String {
let devname=DEVNAME.lock().unwrap();
match *devname {
DevName::IRIS_IS11=>{
"delete_file_by_path_iris(filepath)".to_string()
},
DevName::IRIS_SENSOR(sensor_type)=>{
return iris_spectral::delete_file(filepath)
}
}
}
#[tauri::command]
fn save_reflectance_to_iris(reflectance_data: serde_json::Value, devinfo: serde_json::Value, filepath: String) -> String {
irisdatamanager::save_reflectance_to_iris(reflectance_data, devinfo, filepath)
}
////////////////////////////////////////////////////////////////////////////////////////
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
use tauri::{LogicalSize, Manager, Size}; use tauri::{LogicalSize, Manager, Size};
@ -428,21 +237,38 @@ fn main() {
greet, greet,
getportnames, getportnames,
opencom, opencom,
setport,
closecome, closecome,
sendtoportAndgetreturn, sendtoport_andgetreturn,
readformport, readformport,
sendtoport, sendtoport,
interpolate_spline, interpolate_spline,
sg_smooth, sg_smooth,
savecalibratefile, savecalibratefile,
savecalibratefileIRIS,
sendcalibratetodev, sendcalibratetodev,
algorithm::Gaussian_filter_high, setdevtype,
set_weave_coeff,
delete_file_by_path,
algorithm::gaussian_filter_high,
algorithm::interpolate_spline_at_points, algorithm::interpolate_spline_at_points,
algorithm::find_peek algorithm::find_peek,
algorithm::compute_weave_coeff,
getoneirisfile,
save_reflectance_to_iris
]) ])
.setup(|app| { .setup(|app| {
let config = app.config();
// 打印配置信息,例如窗口标题
let producnaem = config.package.product_name.clone().unwrap();
let version=config.package.version.clone().unwrap();
println!("producnaem:{:?}", producnaem);
let main_window = app.get_window("main").unwrap(); let main_window = app.get_window("main").unwrap();
main_window.set_title(&(producnaem+"_v"+&version));
// 获取屏幕大小 // 获取屏幕大小
if let Some(monitor) = main_window.primary_monitor().unwrap() { if let Some(monitor) = main_window.primary_monitor().unwrap() {

View File

@ -0,0 +1,86 @@
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
#[derive(Serialize, Deserialize)]
pub struct RetStruct {
/// 0x00 json 0x01 string 0x02 data binary
pub datatype: u8,
pub content: String,
pub data: IS11DataStruct,
}
#[serde_as]
#[derive(Serialize, Deserialize)]
#[repr(C)]
pub struct IS11DataStruct {
pub datatype: u8, // Using r# to allow the use of the keyword 'type'
pub direction: u8,
pub tuigan_stat: u8,
pub year:u8,
pub month:u8,
pub day:u8,
pub hour:u8,
pub minute:u8,
pub second:u8,
pub nca:u8,
pub ncb:u8,
pub ncc:u8,
pub shutter_time: u32,
pub index: u64,
pub temprature: [f32; 8],
#[serde_as(as = "[_; 2048]")]
pub data: [f32; 2048],
}
impl Default for IS11DataStruct {
fn default() -> Self {
IS11DataStruct {
datatype: 0,
direction: 10,
tuigan_stat: 0,
year:24,
month:1,
day:1,
hour:0,
minute:0,
second:0,
nca:0,
ncb:0,
ncc:0,
shutter_time: 0,
index: 0,
temprature: [0.0; 8],
data: [0.0; 2048],
}
}
}
impl IS11DataStruct {
pub fn clone(&self) -> IS11DataStruct {
IS11DataStruct {
datatype: self.datatype,
direction: self.direction,
tuigan_stat: self.tuigan_stat,
year: self.year,
month: self.month,
day: self.day,
hour: self.hour,
minute: self.minute,
second: self.second,
nca:self.nca,
ncb:self.ncb,
ncc:self.ncc,
shutter_time: self.shutter_time,
index: self.index,
temprature: self.temprature,
data: self.data,
}
}
}

View File

@ -0,0 +1,16 @@
pub mod structures;
pub mod read;
pub mod write;
pub use structures::{TimeStruct, SpectralData, ImageInfo, OneIRISData};
pub use structures::*;
pub use read::{read_time, read_spectral_data, read_image_info, read_iris_file};
pub use write::*;
#[tauri::command]
pub fn getoneirisfile(path:String)->OneIRISData{
let returndata=read_iris_file(&path).unwrap();
return returndata;
}

View File

@ -0,0 +1,343 @@
use std::io::{Read, Result, BufReader};
use std::fs::File;
use std::convert::TryInto;
use super::structures::{TimeStruct, SpectralData, ImageInfo, OneIRISData};
// use serde::de::value;
use serde_json::Value;
pub fn read_time<R: Read>(reader: &mut R) -> Result<TimeStruct> {
let mut buffer = [0u8; 10]; // Corrected buffer size to 10 bytes
reader.read_exact(&mut buffer)?;
Ok(TimeStruct {
time_zone: buffer[0] as i8,
year: u16::from_le_bytes([buffer[1], buffer[2]]),
month: buffer[3],
day: buffer[4],
hour: buffer[5],
minute: buffer[6],
second: buffer[7],
millisecond: u16::from_le_bytes([buffer[8], buffer[9]]), // Indices 8 and 9 are correct for 10-byte buffer
})
}
pub fn read_image_info<R: Read>(reader: &mut R) -> Result<ImageInfo> {
let mut info = ImageInfo::new();
// Read data length
let mut len_buf = [0u8; 8];
reader.read_exact(&mut len_buf)?;
info.data_length = u64::from_le_bytes(len_buf);
// Read name (fixed size 100 bytes)
let mut name_buf = [0u8; 100];
reader.read_exact(&mut name_buf)?;
info.name = String::from_utf8_lossy(&name_buf).trim_end_matches('\0').to_string();
info.name = remove_after_null_split_once(info.name);
// Read collection time
info.collection_time = read_time(reader)?;
// Read info type
let mut type_buf = [0u8; 1];
reader.read_exact(&mut type_buf)?;
info.info_type = type_buf[0];
let imagedatlenth= info.data_length as u64- 100-10-1; // Adjusted to account for the size of TimeStruct and info_type
// Read image data
info.image_data.resize(imagedatlenth as usize, 0);
reader.read_exact(&mut info.image_data)?;
Ok(info)
}
pub fn read_iris_file(path: &str) -> Result<OneIRISData> {
let file = File::open(path)?;
let mut reader = BufReader::new(file);
// Read and verify magic number
// let mut magic = [0u8; 4];
// reader.read_exact(&mut magic)?;
// if magic != [0x49, 0x52, 0x49, 0x53] { // "IRIS" in ASCII
// return Err(std::io::Error::new(
// std::io::ErrorKind::InvalidData,
// "Not a valid IRIS file"
// ));
// }
let mut iris_data = OneIRISData::new();
// // Read file version
// let mut version = [0u8; 2];
// reader.read_exact(&mut version)?;
// Read sections until EOF
loop {
let mut section_header = [0u8; 12]; // type (4) + length (8)
if reader.read_exact(&mut section_header).is_err() {
break; // EOF reached
}
let section_type = u32::from_le_bytes(section_header[0..4].try_into().unwrap());
let section_length = u64::from_le_bytes(section_header[4..12].try_into().unwrap());
match section_type {
0x00FF00FF => { // Spectral data section
let count = read_section_count(&mut reader)?;
let mut data = Vec::with_capacity(count);
for _ in 0..count {
data.push(read_spectral_data(&mut reader)?);
}
iris_data.spectral_data_section = data;
},
0xFF00FF00 => { // Spectral info section
let count = read_section_count(&mut reader)?;
let mut data = Vec::with_capacity(count);
for _ in 0..count {
let mut tempbuffer = [0u8; 3]; // Adjust size as needed
reader.read_exact(&mut tempbuffer)?;
let lenth = u16::from_le_bytes([tempbuffer[0],tempbuffer[1]]) as usize;
let datatype= u8::from_le_bytes([tempbuffer[2]]);
let mut tempvector = vec![0u8; lenth];
reader.read_exact(&mut tempvector)?;
// Convert to String
let json_string = String::from_utf8(tempvector).unwrap_or_default();
let json_string = json_string.trim_end_matches('\0').to_string();
//print!("JSON String: {}", json_string);
let json:Value = match serde_json::from_str(&json_string){
Ok(json) => json,
Err(e) => {
eprintln!("Error parsing JSON: {}", e);
continue; // Skip this entry if parsing fails
}
}; // Handle parsing error gracefully
//判断json["info_type"]是否存在
if !json.get("info_type").is_some() {
eprintln!("JSON does not contain 'info_type': {}", json_string);
continue; // Skip this entry if "info_type" is missing
}
/* {
"info_type": "infolist", // 0 for device info
"info_number":3,
"info_list": [
{
"info_type": "devinfo", // 0 for device info
"sensor_id": "is30002",
"bandnum": 2048,
"wave_coeff": {
"a1": 0.0,
"a2": 0.0,
"a3": 400,
"a4": 1.0
}
},
{
"info_type": "environment", // 1 for gain info
"date": "2000-01-00 00:00:00",
//下面可选
"humidity":90.0,
"temperature":35.0 ,
"gps":{
"latitude":115.01,
"longitude": 39.01,
"altitude": 100.0
},
},
{
"info_type": "devinfo", // 0 for device info
"sensor_id": "is20001",
"bandnum": 512,
"wave_coeff": {
"a1": 0,
"a2": 0.0,
"a3":390,
"a4": 4
}
}
]
} */
//如果info_type是infolist 则需要逐个解析
if json.get("info_type").and_then(Value::as_str) == Some("infolist") {
let info_number = json.get("info_number").and_then(Value::as_u64).unwrap_or(0) as usize;
for i in 0 ..info_number{
//将对应的info加入到data中
if let Some(info) = json.get("info_list").and_then(|list| list.get(i)) {
data.push(info.clone());
}
}
continue; // Skip the rest of the loop for this entry
}
data.push(json);
//println!("Parsed JSON: {:?}", json);
// let mut data_entry = SpectralInfo::new();
// data_entry.sensor_id = json.get("SensorId").and_then(Value::as_str).unwrap_or_default().to_string();
// data_entry.wave_coeff[0]=json["WaveCoeff"]["a1"].as_f64().unwrap_or(0.0);
// data_entry.wave_coeff[1]=json["WaveCoeff"]["a2"].as_f64().unwrap_or(0.0);
// data_entry.wave_coeff[2]=json["WaveCoeff"]["a3"].as_f64().unwrap_or(0.0);
// data_entry.wave_coeff[3]=json["WaveCoeff"]["a4"].as_f64().unwrap_or(0.0);
// data.push(data_entry);
// Parse JSON string
}
iris_data.spectral_info_section = data;
},
0xF0F0F0F0 => { // Other info section
if section_length == 0 {
iris_data.other_info_section = Vec::new(); // Handle empty section
continue; // Skip empty section
}
let count = read_section_count(&mut reader)?;
let mut data = Vec::with_capacity(count);
for _ in 0..count {
let mut tempbuffer = [0u8; 3]; // Adjust size as needed
reader.read_exact(&mut tempbuffer)?;
let lenth = u16::from_le_bytes([tempbuffer[0], tempbuffer[1]]) as usize;
let info_type = u8::from_le_bytes([tempbuffer[2]]);
let mut tempvector = vec![0u8; lenth];
reader.read_exact(&mut tempvector)?;
// Convert to String
let json_string = String::from_utf8(tempvector).unwrap_or_default();
let json_string = json_string.trim_end_matches('\0').to_string();
//print!("JSON String: {}", json_string);
let json: Value = match serde_json::from_str(&json_string) {
Ok(json) => json,
Err(e) => {
eprintln!("Error parsing JSON: {}", e);
continue; // Skip this entry if parsing fails
}
}; // Handle parsing error gracefully
data.push(json);
}
iris_data.other_info_section = data;
},
0x0F0F0F0F => { // Image info section
if section_length== 0 {
iris_data.image_info_section= Vec::new(); // Handle empty section
continue; // Skip empty section
}
let count = read_section_count(&mut reader)?;
let mut data = Vec::with_capacity(count);
for _ in 0..count {
data.push(read_image_info(&mut reader)?);
}
iris_data.image_info_section = data;
},
_ => {
// Skip unknown sections
let mut buf = vec![0u8; section_length as usize];
reader.read_exact(&mut buf)?;
}
}
}
Ok(iris_data)
}
fn read_section_count<R: Read>(reader: &mut R) -> Result<usize> {
let mut count_buf = [0u8; 2];
reader.read_exact(&mut count_buf)?;
Ok(u16::from_le_bytes(count_buf) as usize)
}
// pub fn read_other_info<R: Read>(reader: &mut R) -> Result<OtherInfo> {
// let mut info = OtherInfo::new();
// // Read info type
// let mut type_buf = [0u8; 1];
// reader.read_exact(&mut type_buf)?;
// info.info_type = type_buf[0];
// // Read data length
// let mut len_buf = [0u8; 8];
// reader.read_exact(&mut len_buf)?;
// let data_len = u64::from_le_bytes(len_buf) as usize;
// // Read data
// info.data.resize(data_len, 0);
// reader.read_exact(&mut info.data)?;
// Ok(info)
// }
fn remove_after_null_split_once(s: String) -> String {
if let Some((before_null, _after_null)) = s.split_once('\0') {
// 返回 \0 之前的部分
before_null.to_string()
} else {
// 如果没有找到 \0就返回原始 String
s
}
}
pub fn read_spectral_data<R: Read>(reader: &mut R) -> Result<SpectralData> {
let mut data = SpectralData::new();
// Read fixed-size fields
let mut name_buf = [0u8; 100];
reader.read_exact(&mut name_buf)?;
name_buf[99] = 0; // Ensure null termination
let temp= String::from_utf8_lossy(&name_buf);
data.name = temp.trim_end_matches('\0').to_string();
data.name = remove_after_null_split_once(data.name);
let mut sensor_buf = [0u8; 50];
reader.read_exact(&mut sensor_buf)?;
data.sensor_id = String::from_utf8_lossy(&sensor_buf).trim_end_matches('\0').to_string();
data.sensor_id = remove_after_null_split_once(data.sensor_id);
let mut uint8_buf = [0u8; 1];
reader.read_exact(&mut uint8_buf)?;
data.fiber_id = uint8_buf[0];
data.collection_time = read_time(reader)?;
let mut float_buf = [0u8; 8];
reader.read_exact(&mut float_buf)?;
data.exposure = f64::from_le_bytes(float_buf);
let mut float_buf = [0u8; 4];
reader.read_exact(&mut float_buf)?;
data.gain = f32::from_le_bytes(float_buf);
let mut byte_buf = [0u8; 1];
reader.read_exact(&mut byte_buf)?;
data.data_type = byte_buf[0];
reader.read_exact(&mut byte_buf)?;
data.pixel_size = byte_buf[0];
reader.read_exact(&mut byte_buf)?;
data.ground_type = byte_buf[0];
let mut short_buf = [0u8; 2];
reader.read_exact(&mut short_buf)?;
data.bands = u16::from_le_bytes(short_buf);
reader.read_exact(&mut byte_buf)?;
data.valid_flag = byte_buf[0];
let data_len=data.pixel_size as usize * data.bands as usize;
// Read the length of the spectral_data vector
// let mut len_buf = [0u8; 8];
// reader.read_exact(&mut len_buf)?;
// let data_len = u64::from_le_bytes(len_buf) as usize;
// Read the spectral_data vector
data.spectral_data.resize(data_len, 0);
reader.read_exact(&mut data.spectral_data)?;
Ok(data)
}

View File

@ -0,0 +1,411 @@
pub const DATA_TYPE_UINT8: u8 = 0x10;
pub const DATA_TYPE_INT16: u8 = 0x11;
pub const DATA_TYPE_UINT16: u8 = 0x12;
pub const DATA_TYPE_INT32: u8 = 0x13;
pub const DATA_TYPE_UINT32: u8 = 0x14;
pub const DATA_TYPE_FLOAT32: u8 = 0x20;
pub const DATA_TYPE_FLOAT64: u8 = 0x21;
/* 0 dn 1 rad 2 ref 3 irad 4 califile 5 flat_ref 6 dark_dn 7 flat_dn */
pub const Target_Spectral_Type_DN:u8 = 0x00;
pub const Target_Spectral_Type_Rad:u8 = 0x01;
pub const Target_Spectral_Type_Ref:u8 = 0x02;
pub const Target_Spectral_Type_IRad:u8 = 0x03;
pub const Target_Spectral_Type_CaliFile_Gain:u8 = 0x04;
pub const Target_Spectral_Type_FlatRef:u8 = 0x05;
pub const Target_Spectral_Type_DarkDN:u8 = 0x06;
pub const Target_Spectral_Type_FlatDN:u8 = 0x07;
pub const Target_LAMP_VALUE_SCALED:u8 = 0x08;
use serde::Serialize;
use serde_json::json;
#[derive(serde::Serialize,Debug, Clone, PartialEq)]
pub struct TimeStruct {
pub time_zone: i8,
pub year: u16,
pub month: u8,
pub day: u8,
pub hour: u8,
pub minute: u8,
pub second: u8,
pub millisecond: u16,
}
impl TimeStruct {
pub fn new() -> Self {
TimeStruct {
time_zone: 0,
year: 0,
month: 1,
day: 1,
hour: 0,
minute: 0,
second: 0,
millisecond: 0,
}
}
}
#[derive(serde::Serialize,Debug, Clone, PartialEq)]
pub struct SpectralData {
pub name: String,
pub sensor_id: String,
pub fiber_id: u8,
pub collection_time: TimeStruct,
pub exposure: f64,
pub gain: f32,
pub data_type: u8,
pub pixel_size: u8,
pub ground_type: u8,
pub bands: u16,
pub valid_flag: u8,
pub spectral_data: Vec<u8>,
}
impl SpectralData {
pub fn new() -> Self {
SpectralData {
name: String::new(),
sensor_id: String::new(),
fiber_id:0,
collection_time: TimeStruct::new(),
exposure: 0.0,
gain: 0.0,
data_type: 0,
pixel_size: 0,
ground_type: 0,
bands: 0,
valid_flag: 0,
spectral_data: Vec::new(),
}
}
pub fn Get_Spectral_Data(&self)-> Vec<f64> {
let mut retrun_data: Vec<f64> = Vec::new();
let datatype = self.data_type;
let bands = self.bands as usize;
match datatype {
DATA_TYPE_UINT8 => {
// uint8
for i in 0..bands {
retrun_data.push(self.spectral_data[i] as f64);
}
}
DATA_TYPE_INT16 => {
// int16
self.spectral_data.chunks(2).for_each(|chunk| {
if chunk.len() == 2 {
let value = i16::from_le_bytes([chunk[0], chunk[1]]);
retrun_data.push(value as f64);
}
});
}
DATA_TYPE_UINT16 => {
// uint16
self.spectral_data.chunks(2).for_each(|chunk| {
if chunk.len() == 2 {
let value = u16::from_le_bytes([chunk[0], chunk[1]]);
retrun_data.push(value as f64);
}
});
}
DATA_TYPE_INT32 => {
// int32
self.spectral_data.chunks(4).for_each(|chunk| {
if chunk.len() == 4 {
let value = i32::from_le_bytes([
chunk[0],
chunk[1],
chunk[2],
chunk[3],
]);
retrun_data.push(value as f64);
}
});
}
DATA_TYPE_UINT32 => {
// uint32
for i in (0..self.spectral_data.len()).step_by(4) {
let value = u32::from_le_bytes([
self.spectral_data[i],
self.spectral_data[i + 1],
self.spectral_data[i + 2],
self.spectral_data[i + 3],
]);
retrun_data.push(value as f64);
}
}
DATA_TYPE_FLOAT32 => {
// float32
for i in (0..self.spectral_data.len()).step_by(4) {
let value = f32::from_le_bytes([
self.spectral_data[i],
self.spectral_data[i + 1],
self.spectral_data[i + 2],
self.spectral_data[i + 3],
]);
retrun_data.push(value as f64);
}
}
DATA_TYPE_FLOAT64 => {
// float64
for i in (0..self.spectral_data.len()).step_by(8) {
let value = f64::from_le_bytes([
self.spectral_data[i],
self.spectral_data[i + 1],
self.spectral_data[i + 2],
self.spectral_data[i + 3],
self.spectral_data[i + 4],
self.spectral_data[i + 5],
self.spectral_data[i + 6],
self.spectral_data[i + 7],
]);
retrun_data.push(value);
}
}
_ => {
// Unsupported data type
panic!("Unsupported data type: {}", datatype);
}
}
retrun_data
}
pub fn Set_Spectral_Data(&mut self, data: Vec<f64>,datatype: u8) {
self.data_type = datatype;
self.bands = data.len() as u16;
self.spectral_data.clear();
// let datatype = self.data_type;
let bands = self.bands as usize;
match datatype {
DATA_TYPE_UINT8 => {
// uint8
self.pixel_size = 1;
self.spectral_data.clear();
for i in 0..bands {
if i < data.len() {
self.spectral_data.push(data[i] as u8);
} else {
self.spectral_data.push(0);
}
}
}
DATA_TYPE_INT16 => {
// int16
self.pixel_size = 2;
self.spectral_data.clear();
for i in 0..bands {
if i < data.len() {
let value = data[i] as i16;
self.spectral_data.extend_from_slice(&value.to_le_bytes());
} else {
self.spectral_data.extend_from_slice(&[0, 0]);
}
}
}
DATA_TYPE_UINT16 => {
// uint16
self.pixel_size = 2;
self.spectral_data.clear();
for i in 0..bands {
if i < data.len() {
let value = data[i] as u16;
self.spectral_data.extend_from_slice(&value.to_le_bytes());
} else {
self.spectral_data.extend_from_slice(&[0, 0]);
}
}
}
DATA_TYPE_INT32 => {
// int32
self.pixel_size = 4;
self.spectral_data.clear();
for i in 0..bands {
if i < data.len() {
let value = data[i] as i32;
self.spectral_data.extend_from_slice(&value.to_le_bytes());
} else {
self.spectral_data.extend_from_slice(&[0, 0, 0, 0]);
}
}
}
DATA_TYPE_UINT32 => {
// uint32
self.pixel_size = 4;
self.spectral_data.clear();
for i in 0..bands {
if i < data.len() {
let value = data[i] as u32;
self.spectral_data.extend_from_slice(&value.to_le_bytes());
} else {
self.spectral_data.extend_from_slice(&[0, 0, 0, 0]);
}
}
}
DATA_TYPE_FLOAT32 => {
// float32
self.pixel_size = 4;
self.spectral_data.clear();
for i in 0..bands {
if i < data.len() {
let value = data[i] as f32;
self.spectral_data.extend_from_slice(&value.to_le_bytes());
} else {
self.spectral_data.extend_from_slice(&[0, 0, 0, 0]);
}
}
}
DATA_TYPE_FLOAT64 => {
// float64
self.pixel_size = 8;
self.spectral_data.clear();
for i in 0..bands {
if i < data.len() {
let value = data[i];
self.spectral_data.extend_from_slice(&value.to_le_bytes());
} else {
self.spectral_data.extend_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0]);
}
}
}
_ => {
// Unsupported data type
panic!("Unsupported data type: {}", datatype);
}
}
}
}
// #[derive(Debug, Clone, PartialEq)]
// pub struct OtherInfo {
// pub info_type: u8,
// pub data: Vec<u8>, // Assuming the data is variable length
// }
// impl OtherInfo {
// pub fn new() -> Self {
// OtherInfo {
// info_type: 0,
// data: Vec::new(),
// }
// }
// }
#[derive(serde::Serialize, Debug, Clone, PartialEq)]
pub struct OneIRISData {
pub spectral_data_section: Vec<SpectralData>,
pub spectral_info_section: Vec<serde_json::Value>, // Using serde_json::Value for flexibility
pub other_info_section: Vec<serde_json::Value>,
pub image_info_section: Vec<ImageInfo>,
}
impl OneIRISData {
pub fn new() -> Self {
OneIRISData {
spectral_data_section: Vec::new(),
spectral_info_section: Vec::new(),
other_info_section: Vec::new(),
image_info_section: Vec::new(),
}
}
}
// #[derive(Debug, Clone, PartialEq)]
// pub struct SpectralInfo {
// pub sensor_id: String,
// pub wave_coeff: [f64; 4],
// }
// impl SpectralInfo {
// pub fn new() -> Self {
// SpectralInfo {
// sensor_id: String::new(),
// wave_coeff: [0.0; 4],
// }
// }
// }
#[derive(serde::Serialize,Debug, Clone, PartialEq)]
pub struct ImageInfo {
pub data_length: u64,
pub name: String,
pub collection_time: TimeStruct,
pub info_type: u8,
pub image_data: Vec<u8>, // Assuming the data is variable length
}
impl ImageInfo {
pub fn new() -> Self {
ImageInfo {
data_length: 0,
name: String::new(),
collection_time: TimeStruct::new(),
info_type: 0,
image_data: Vec::new(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_time_struct() {
let time = TimeStruct::new();
assert_eq!(time.time_zone, 0);
assert_eq!(time.year, 0);
assert_eq!(time.month, 1);
}
#[test]
fn test_spectral_data() {
let data = SpectralData::new();
assert_eq!(data.name, "");
assert_eq!(data.bands, 0);
assert!(data.spectral_data.is_empty());
}
// #[test]
// fn test_spectral_info() {
// let info = SpectralInfo::new();
// assert_eq!(info.sensor_id, "");
// assert_eq!(info.wave_coeff, [0.0; 4]);
// }
// #[test]
// fn test_other_info() {
// let info = OtherInfo::new();
// assert_eq!(info.info_type, 0);
// assert!(info.data.is_empty());
// }
#[test]
fn test_image_info() {
let info = ImageInfo::new();
assert_eq!(info.data_length, 0);
assert_eq!(info.name, "");
assert!(info.image_data.is_empty());
}
}

View File

@ -0,0 +1,222 @@
use std::fs::File;
use std::io::{self, Write, Result};
use std::vec;
use serde_json::json;
// use crate::write;
use super::structures::{TimeStruct, SpectralData, ImageInfo,OneIRISData};
// Internal writer functions remain the same
fn write_time<W: Write>(time: &TimeStruct, writer: &mut W) -> Result<()> {
writer.write_all(&[time.time_zone as u8])?;
writer.write_all(&time.year.to_le_bytes())?;
writer.write_all(&[time.month])?;
writer.write_all(&[time.day])?;
writer.write_all(&[time.hour])?;
writer.write_all(&[time.minute])?;
writer.write_all(&[time.second])?;
writer.write_all(&time.millisecond.to_le_bytes())?;
Ok(())
}
pub fn write_image_info<W: Write>(info: &ImageInfo, writer: &mut W) -> Result<()> {
// Write data length
writer.write_all(&info.data_length.to_le_bytes())?;
// Write name (fixed size 100 bytes)
let mut name_buf = [0u8; 100];
let name_bytes = info.name.as_bytes();
name_buf[..info.name.len().min(99)].copy_from_slice(name_bytes[0..name_bytes.len().min(99)].as_ref());
writer.write_all(&name_buf)?;
// Write collection time
write_time(&info.collection_time, writer)?;
// Write info type
writer.write_all(&[info.info_type])?;
// Write image data
writer.write_all(&info.image_data)?;
Ok(())
}
pub fn write_spectral_data<W: Write>(data: &SpectralData, writer: &mut W) -> Result<()> {
// Write fixed-size fields
let mut name_buf = [0u8; 100];
let namebyte= data.name.as_bytes();
name_buf[..data.name.len().min(99)].copy_from_slice(namebyte[0..namebyte.len().min(99)].as_ref());
writer.write_all(&name_buf)?;
let mut sensor_buf = [0u8; 50];
let sensor_id_bytes = data.sensor_id.as_bytes();
sensor_buf[..data.sensor_id.len().min(49)].copy_from_slice(sensor_id_bytes[0..sensor_id_bytes.len().min(49)].as_ref());
writer.write_all(&sensor_buf)?;
writer.write_all(&[data.fiber_id])?;
write_time(&data.collection_time, writer)?;
writer.write_all(&data.exposure.to_le_bytes())?;
writer.write_all(&data.gain.to_le_bytes())?;
writer.write_all(&[data.data_type])?;
writer.write_all(&[data.pixel_size])?;
writer.write_all(&[data.ground_type])?;
writer.write_all(&data.bands.to_le_bytes())?;
writer.write_all(&[data.valid_flag])?;
// // Write the length of the spectral_data vector
// writer.write_all(&(data.spectral_data.len() as u64).to_le_bytes())?;
// Write the spectral_data vector
writer.write_all(&data.spectral_data)?;
Ok(())
}
pub fn caculate_spectral_data_length(data: &Vec<SpectralData>) -> u64 {
let mut lenth:u64 = 0;
//加上u16的长度
lenth += 2; // bands
//加上u8的长度
// let numberofspectral=data.len();
for datatemp in data {
lenth += 100; // name
lenth += 50; // sensor_id
lenth += 1 ; // fiber_id
lenth += 10; // time_zone
lenth += 8; // exposure
lenth += 4; // gain
lenth += 1; // data_type
lenth += 1; // pixel_size
lenth += 1; // ground_type
lenth += 2; // bands
lenth += 1; // valid_flag
lenth += datatemp.spectral_data.len() as u64;
}
lenth
}
pub fn caculate_image_info_length(data: &Vec<ImageInfo>) -> u64 {
let mut lenth: u64 = 0;
if data.is_empty() {
return lenth;
}
lenth +=2;
for info in data {
lenth += 8; // data_length
lenth += 100; // name
lenth += 10; // time_zone
lenth += 1; // info_type
lenth += info.image_data.len() as u64; // image_data length
}
lenth
}
pub fn cacluate_other_info_length(data: &Vec<serde_json::Value>) -> (Vec<u8>, u64) {
let mut lenth: u64 = 0;
let mut vecback= Vec::new();
if data.is_empty() {
return (vecback, lenth);
}
// for info in data {
// lenth+=1; // info_type
// lenth+=8; // data length
// lenth += info.data.len() as u64; // data length
// vecback.push(info.info_type);
// vecback.extend_from_slice(&(info.data.len() as u64).to_le_bytes());
// vecback.extend_from_slice(&info.data);
// }
(vecback, lenth)
}
pub fn caculate_spectral_info_length(data: &Vec<serde_json::Value>) -> (Vec<u8>, u64) {
let mut lenth: u64 = 0;
let mut vecback= Vec::new();
if data.is_empty() {
return (vecback, lenth);
}
lenth+=2; // sensor_id
let lenthofinfo=data.len() as u16;
vecback.extend_from_slice(&lenthofinfo.to_le_bytes()); // Number of spectral info entries
for info in data {
lenth+=2;
lenth+=1;
let mut lenthofthisinfo:u16=0;
let json=info;
let json_string = serde_json::to_string(&json).unwrap();
let json_bytes = json_string.as_bytes();
lenthofthisinfo= json_bytes.len() as u16+1;
lenth += lenthofthisinfo as u64 ;
// 将长度转换为字节并添加到 vecback
vecback.extend_from_slice(&lenthofthisinfo.to_le_bytes());
vecback.push(0x00); // json 标识
vecback.extend_from_slice(json_bytes);
vecback.push(0x00); // 添加一个字节的0x00
}
(vecback, lenth)
}
pub fn wirte_iris_data(data:&OneIRISData,filepath:&str) -> Result<()> {
let mut file = File::create(filepath)?;
//写入光谱数据header
let SPectralData_Flag:u32=0x00FF00FF;
file.write_all(&SPectralData_Flag.to_le_bytes())?;
let mut sectionlenth: u64 = caculate_spectral_data_length(&data.spectral_data_section);
file.write_all(&(sectionlenth).to_le_bytes())?; // Section length
let numberofspectral=data.spectral_data_section.len() as u16;
file.write_all(&numberofspectral.to_le_bytes())?; // Number of spectral data entries
// Write spectral data section
for spectral_data in &data.spectral_data_section {
write_spectral_data(spectral_data, &mut file)?;
}
// Write section length
// Write spectral info section
let spectral_info_flag: u32 = 0xFF00FF00;
let (spectral_info_vec, spectral_info_length) = caculate_spectral_info_length(&data.spectral_info_section);
file.write_all(&spectral_info_flag.to_le_bytes())?; // Spectral info 区块标识
file.write_all(&spectral_info_length.to_le_bytes())?; // Section length
if spectral_info_length != 0 {
file.write_all(&spectral_info_vec)?; // Write the spectral info section data
}
let other_info_flag: u32 = 0xF0F0F0F0;
let (other_info_vec, other_info_length) = cacluate_other_info_length(&data.other_info_section);
file.write_all(&other_info_flag.to_le_bytes())?; // Other info 区块标识
file.write_all(&other_info_length.to_le_bytes())?; // Section length
if other_info_length != 0 {
file.write_all(&other_info_vec)?; // Write the other info section data
}
let image_info_flag: u32 = 0x0F0F0F0F;
file.write_all(&image_info_flag.to_le_bytes())?; // Image info 区块标识
let image_info_length = caculate_image_info_length(&data.image_info_section);
file.write_all(&image_info_length.to_le_bytes())?; // Section length
if image_info_length != 0 {
let numberofimageinfo = data.image_info_section.len() as u16;
file.write_all(&numberofimageinfo.to_le_bytes())?; // Write the image info section data
// Write image info section
for image_info in &data.image_info_section {
write_image_info(image_info, &mut file)?;
}
}
Ok(())
}

View File

@ -1,24 +1,23 @@
use tklog::{ use tklog::{
debugs, errors, fatals, infos, infos,
sync::Logger,LEVEL, LOG, sync::Logger, Format, MODE,
traces, warns, Format, MODE,async_traces,
}; };
use lazy_static::lazy_static; use lazy_static::lazy_static;
use std::{ use std::{
// fmt::format, // fmt::format,
borrow::{Borrow, BorrowMut}, sync::{Arc, Mutex}, thread::sleep borrow::{ BorrowMut}, sync::{Arc, Mutex}
}; };
struct LOGERME{ struct LOGERME{
LOGGER_RUST: Arc<Mutex<Logger>>, logger_rust: Arc<Mutex<Logger>>,
LOGGER_JS: Arc<Mutex<Logger>>, logger_js: Arc<Mutex<Logger>>,
} }
lazy_static! { lazy_static! {
static ref LOGERGloble: Arc<Mutex<LOGERME>> = Arc::new(Mutex::new( static ref LOGERGLOBLE: Arc<Mutex<LOGERME>> = Arc::new(Mutex::new(
LOGERME{ LOGERME{
LOGGER_RUST:Arc::new( Mutex::new(Logger::new())), logger_rust:Arc::new( Mutex::new(Logger::new())),
LOGGER_JS: Arc::new( Mutex::new(Logger::new())), logger_js: Arc::new( Mutex::new(Logger::new())),
} }
)); ));
@ -29,14 +28,14 @@ lazy_static! {
pub fn change_log_path(path: &str,String: &str) { pub fn change_log_path(path: &str,string: &str) {
if String=="RUST"{ if string=="RUST"{
let mut loggerglobel = LOGERGloble.lock().unwrap(); let loggerglobel = LOGERGLOBLE.lock().unwrap();
let mut log=loggerglobel.LOGGER_RUST.lock().unwrap(); let mut log=loggerglobel.logger_rust.lock().unwrap();
log.set_cutmode_by_time(path, MODE::DAY, 10, false); log.set_cutmode_by_time(path, MODE::DAY, 10, false);
}else if String=="JS"{ }else if string=="JS"{
let mut loggerglobel=LOGERGloble.lock().unwrap(); let loggerglobel=LOGERGLOBLE.lock().unwrap();
let mut log=loggerglobel.LOGGER_JS.lock().unwrap(); let mut log=loggerglobel.logger_js.lock().unwrap();
log.set_cutmode_by_time(path, MODE::DAY, 10, false); log.set_cutmode_by_time(path, MODE::DAY, 10, false);
} }
} }
@ -44,13 +43,13 @@ pub fn change_log_path(path: &str,String: &str) {
pub fn initlog() { pub fn initlog() {
//let mut logger = LOGERGloble.lock().unwrap().LOGGER_RUST; //let mut logger = LOGERGloble.lock().unwrap().LOGGER_RUST;
let mut loggerglobel = LOGERGloble.lock().unwrap(); let loggerglobel = LOGERGLOBLE.lock().unwrap();
let mut log=loggerglobel.LOGGER_RUST.lock().unwrap(); let mut log=loggerglobel.logger_rust.lock().unwrap();
log.set_console(true).set_format(Format::Date|Format::Time).set_formatter("{time} {file}{level}:{message}\n") log.set_console(true).set_format(Format::Date|Format::Time).set_formatter("{time} {file}{level}:{message}\n")
.set_cutmode_by_time("rust_log.log",MODE::DAY, 10, false); .set_cutmode_by_time("rust_log.log",MODE::DAY, 10, false);
// let mut logger = LOGERGloble.lock().unwrap().LOGGER_JS; // let mut logger = LOGERGloble.lock().unwrap().LOGGER_JS;
//let mut loggerglobel = LOGERGloble.lock().unwrap(); //let mut loggerglobel = LOGERGloble.lock().unwrap();
let mut log=loggerglobel.LOGGER_JS.lock().unwrap(); let mut log=loggerglobel.logger_js.lock().unwrap();
log.set_console(false).set_format(Format::Date|Format::Time).set_formatter("{time}:\t{message}\n") log.set_console(false).set_format(Format::Date|Format::Time).set_formatter("{time}:\t{message}\n")
.set_cutmode_by_time("js_log.log",MODE::DAY, 10, false); .set_cutmode_by_time("js_log.log",MODE::DAY, 10, false);
@ -59,8 +58,8 @@ pub fn initlog() {
pub fn logtorust<T>(str:T) pub fn logtorust<T>(str:T)
where T: std::fmt::Display where T: std::fmt::Display
{ {
let mut loggerglobe=LOGERGloble.lock().unwrap(); let loggerglobe=LOGERGLOBLE.lock().unwrap();
let mut log=Arc::clone(&loggerglobe.LOGGER_RUST); let mut log=Arc::clone(&loggerglobe.logger_rust);
let log1 = log.borrow_mut(); let log1 = log.borrow_mut();
infos!( log1, str); infos!( log1, str);
@ -69,8 +68,8 @@ where T: std::fmt::Display
pub fn logtojs<T>(str:T) pub fn logtojs<T>(str:T)
where T: std::fmt::Display where T: std::fmt::Display
{ {
let mut loggerglobe=LOGERGloble.lock().unwrap(); let loggerglobe=LOGERGLOBLE.lock().unwrap();
let mut log=Arc::clone(&loggerglobe.LOGGER_JS); let mut log=Arc::clone(&loggerglobe.logger_js);
let log1 = log.borrow_mut(); let log1 = log.borrow_mut();
infos!( log1, str); infos!( log1, str);

View File

@ -8,16 +8,16 @@ use std::{
thread::sleep, thread::sleep,
}; };
struct SeriesSettings { struct SeriesSettings {
pub PortName: String, pub port_name: String,
pub BaudRate: u32, pub band_rate: u32,
pub port: Option<Box<dyn serialport::SerialPort>>, pub port: Option<Box<dyn serialport::SerialPort>>,
pub isopen: bool, pub isopen: bool,
} }
lazy_static! { lazy_static! {
static ref PORT_INFO: Arc<Mutex<SeriesSettings>> = Arc::new(Mutex::new(SeriesSettings { static ref PORT_INFO: Arc<Mutex<SeriesSettings>> = Arc::new(Mutex::new(SeriesSettings {
PortName: String::from("NON"), port_name: String::from("NON"),
BaudRate: 9600, band_rate: 9600,
port: None, port: None,
isopen: false, isopen: false,
})); }));
@ -25,7 +25,7 @@ lazy_static! {
pub fn tryuseport() -> String { pub fn tryuseport() -> String {
let mut port_info = PORT_INFO.lock().unwrap(); let mut port_info = PORT_INFO.lock().unwrap();
if port_info.PortName == "NON" { if port_info.port_name == "NON" {
return format!("Port is not set"); return format!("Port is not set");
} }
if port_info.isopen { if port_info.isopen {
@ -36,7 +36,7 @@ pub fn tryuseport() -> String {
port_info.port = match serialport::new(port_info.PortName.clone(), port_info.BaudRate).open() { port_info.port = match serialport::new(port_info.port_name.clone(), port_info.band_rate).open() {
Ok(p) => Some(p), Ok(p) => Some(p),
Err(e) => { Err(e) => {
eprintln!("Failed to open Error: {}", e); eprintln!("Failed to open Error: {}", e);
@ -50,14 +50,17 @@ pub fn tryuseport() -> String {
pub fn set_port_info(portname: &String, baudrate: u32) { pub fn set_port_info(portname: &String, baudrate: u32) {
let mut port_info = PORT_INFO.lock().unwrap(); let mut port_info = PORT_INFO.lock().unwrap();
port_info.PortName = portname.to_string(); port_info.port_name = portname.to_string();
port_info.BaudRate = baudrate; port_info.band_rate = baudrate;
} }
pub fn get_port_name() -> Vec<String> { pub fn get_port_name() -> Vec<String> {
let ports = serialport::available_ports().expect("No ports found!"); let ports = serialport::available_ports().expect("No ports found!");
println!("Available ports:{}", ports.len());
let mut portnames: Vec<String> = Vec::new(); let mut portnames: Vec<String> = Vec::new();
println!("{}",portnames.len() );
// portnames.push("COM5".to_string());
for p in ports { for p in ports {
portnames.push(p.port_name); portnames.push(p.port_name);
} }
@ -66,13 +69,13 @@ pub fn get_port_name() -> Vec<String> {
pub fn _reopenport() -> String { pub fn _reopenport() -> String {
let mut port_info = PORT_INFO.lock().unwrap(); let mut port_info = PORT_INFO.lock().unwrap();
if port_info.PortName == "NON" { if port_info.port_name == "NON" {
return format!("Port is not set"); return format!("Port is not set");
} }
//关闭端口 //关闭端口
port_info.port = None; port_info.port = None;
//重新打开端口 //重新打开端口
port_info.port = match serialport::new(port_info.PortName.clone(), port_info.BaudRate).open() { port_info.port = match serialport::new(port_info.port_name.clone(), port_info.band_rate).open() {
Ok(p) => Some(p), Ok(p) => Some(p),
Err(e) => { Err(e) => {
eprintln!("Failed to open Error: {}", e); eprintln!("Failed to open Error: {}", e);
@ -85,25 +88,27 @@ pub fn _reopenport() -> String {
pub fn closeport() -> String { pub fn closeport() -> String {
let mut port_info = PORT_INFO.lock().unwrap(); let mut port_info = PORT_INFO.lock().unwrap();
if port_info.PortName == "NON" { if port_info.port_name == "NON" {
return format!("Port is not set"); return format!("Port is not set");
} }
//关闭端口 //关闭端口
port_info.port = None; port_info.port = None;
println!("Port is closed"); println!("Port is closed");
String::from("Port is closed") String::from("串口已关闭")
//String::from("Port is closed")
} }
pub fn sendtoprot(data: Vec<u8>) -> String { pub fn sendtoprot(data: Vec<u8>) -> String {
let mut port_info = PORT_INFO.lock().unwrap(); let mut port_info = PORT_INFO.lock().unwrap();
if port_info.PortName == "NON" { if port_info.port_name == "NON" {
return format!("Port is not set"); return format!("Port is not set");
} }
println!("{:?}", data.iter().map(|&byte| format!("{:02X}", byte)).collect::<Vec<String>>().join(" "));
match &mut port_info.port { match &mut port_info.port {
Some(p) => match p.write(&data) { Some(p) => match p.write(&data) {
Ok(_) => { Ok(_) => {
println!("Data sent"); println!("Data sent");
return String::from("Data sent"); return String::from("Data sent");
} }
Err(e) => { Err(e) => {
@ -119,14 +124,14 @@ pub fn sendtoprot(data: Vec<u8>) -> String {
pub fn clearserilport() -> String{ pub fn clearserilport() -> String{
let mut port_info = PORT_INFO.lock().unwrap(); let mut port_info = PORT_INFO.lock().unwrap();
if port_info.PortName == "NON" { if port_info.port_name == "NON" {
return "Port is not set".to_string(); return "Port is not set".to_string();
} }
let mut buf: Vec<u8> = vec![0; 1000]; let mut buf: Vec<u8> = vec![0; 1000];
match &mut port_info.port { match &mut port_info.port {
Some(p) => { Some(p) => {
p.set_timeout(Duration::from_millis(100)).unwrap(); p.set_timeout(Duration::from_millis(100)).unwrap();
while true{ loop{
let sizeread =match p.read(&mut buf){ let sizeread =match p.read(&mut buf){
Ok(size)=>{size}, Ok(size)=>{size},
Err(_e)=>{return "Port is not open".to_string()} Err(_e)=>{return "Port is not open".to_string()}
@ -148,7 +153,7 @@ pub fn clearserilport() -> String{
pub fn readdatafromport(waittime: u64, commanid: u8) -> Vec<u8> { pub fn readdatafromport(waittime: u64, commanid: u8) -> Vec<u8> {
let mut port_info = PORT_INFO.lock().unwrap(); let mut port_info = PORT_INFO.lock().unwrap();
if port_info.PortName == "NON" { if port_info.port_name == "NON" {
return "Port is not set".as_bytes().to_vec(); return "Port is not set".as_bytes().to_vec();
} }
let mut buf: Vec<u8> = vec![0; 1000]; let mut buf: Vec<u8> = vec![0; 1000];
@ -236,7 +241,27 @@ pub fn iris_calc_crc(p_buffer: &[u8]) -> u16 {
crc crc
} }
pub fn readforport()->Vec<u8>{
let mut port_info = PORT_INFO.lock().unwrap();
if port_info.port_name == "NON" {
return "Port is not set".as_bytes().to_vec();
}
let mut buf: Vec<u8> = vec![0; 5000];
match &mut port_info.port {
Some(p) => {
p.set_timeout(Duration::from_millis(10)).unwrap();
let sizeread =match p.read(&mut buf){
Ok(size)=>{size},
Err(_e)=>{0}
};
buf.truncate(sizeread);
return buf;
}
None => {
return Vec::new();
}
}
}
#[test] #[test]
fn test() { fn test() {
tryuseport(); tryuseport();

View File

@ -1,14 +1,16 @@
{ {
"build": { "build": {
"beforeDevCommand": "npm run dev", "beforeDevCommand": "npm run dev",
"beforeBuildCommand": "npm run build", "beforeBuildCommand": " npm run mybuild & npm run build",
"devPath": "http://localhost:1420", "devPath": "http://localhost:1420",
"distDir": "../dist", "distDir": "../dist",
"withGlobalTauri": true "withGlobalTauri": true
}, },
"package": { "package": {
"productName": "SpectralPlot", "productName": "SpectralPlot",
"version": "0.4.141" "version": "0.6.81"
}, },
"tauri": { "tauri": {
@ -22,6 +24,7 @@
"open": true "open": true
}, },
"fs": { "fs": {
"scope": ["**"], "scope": ["**"],
"all": true "all": true
@ -56,13 +59,21 @@
"targets": "all", "targets": "all",
"identifier": "lele.rlx", "identifier": "lele.rlx",
"resources": [ "resources": [
"config.json" "config.json","is11lib.dll" , "iris_is3lib.dll",
"msvcp140.dll",
"vcruntime140.dll",
"vcruntime140_1.dll",
"ucrtbase.dll"
], ],
"windows": {
},
"icon": [ "icon": [
"icons/32x32.png", "icons/icon.ico",
"icons/128x128.png", "icons/icon.ico",
"icons/128x128@2x.png", "icons/icon.ico",
"icons/icon.icns", "icons/icon.ico",
"icons/icon.ico" "icons/icon.ico"
] ]
} }

0
src-tauri/test.nsi Normal file
View File

BIN
src-tauri/ucrtbase.dll Normal file

Binary file not shown.

21
src-tauri/updatelog.md Normal file
View File

@ -0,0 +1,21 @@
# IRIS SpectralPlot 更新日志
---
## 公司信息
* **公司名称**:北京依锐思遥感技术有限公司
* **官方网站**[http://www.iris-rs.cn](http://www.iris-rs.cn)
* **联系邮箱**renlixin@iris-rs.cn
---
## 更新日志
* **v0.6.58** 增加了IS3的支持。
* **v0.6.59** 将连续保存功能分割为“连续(不保存)”和“连续保存”两个独立功能。
* **v0.6.60** 增加了IS3快门的控制功能。
* **v0.6.62** 修正了保存逻辑,并修复了波长倒置的问题。
* **v0.6.65** 增加了HH3定标功能。
* **v0.6.66** 增加了HH3波长定标所需的波长参数并将寻峰最小值调整为3000。
* **v0.6.81** 解决了is3控制时偶尔会卡顿的问题

BIN
src-tauri/vcruntime140.dll Normal file

Binary file not shown.

Binary file not shown.

View File

@ -1,26 +1,47 @@
<script setup> <script>
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
import Greet from "./components/Greet.vue"; import Greet from "./components/Greet.vue";
import AppHyperSpectral from "./AppHyperSpectral.vue";
import APPDataview from "./DataView/APPDataview.vue";
import EventBus from "./eventBus.js";
export default {
components: {
Greet,
AppHyperSpectral,
APPDataview
},
data() {
return {
currentView: 'AppHyperSpectral', // 当前显示的视图
viewList: ['AppHyperSpectral', 'APPDataview'],
indexofcomponent: 0,
};
},
mounted() {
EventBus.on('changemainvue', this.onchangemainvue);
console.log(window.__TAURI__);
},
methods: {
onchangemainvue(){
// 切换到下一个视图
this.indexofcomponent++;
if (this.indexofcomponent >= this.viewList.length) {
this.indexofcomponent = 0;
}
this.currentView = this.viewList[this.indexofcomponent];
}
}
};
</script> </script>
<template> <template>
<div class="container"> <keep-alive>
<component
:is="currentView"
<Greet /> style="user-select: none; width: 100vw; height: 100vh;"
</div> />
</keep-alive>
</template> </template>
<style scoped> <style scoped>
.logo.vite:hover {
filter: drop-shadow(0 0 2em #747bff);
}
.logo.vue:hover {
filter: drop-shadow(0 0 2em #249b73);
/* Your additional CSS code here */
}
</style> </style>

View File

@ -119,6 +119,7 @@ export default {
<template> <template>
<BToastOrchestrator /> <BToastOrchestrator />

View File

@ -0,0 +1,216 @@
<template>
<a-layout style="height: 100vh; width: 100vw;">
<a-layout-header>
<menubardatavue></menubardatavue>
</a-layout-header>
<a-layout>
<a-layout-sider :resize-directions="['right']" style=" min-width: 20vw;max-width: 50vw;">
<a-dropdown trigger="contextMenu" alignPoint :style="{ display: 'block' }">
<GuiLeftSider class="lefttree" v-on:NodeClicked="ononeFilechoese"
v-on:NodeDblClicked="onFileDblClick" v-on:FilesSelected="onFilesSelected"
v-on:FolderClicked="onFolderClicked" v-on:FolderDblClicked="onFolderDblClick"
v-on:SaveFilesRequested="onSaveFilesRequested" v-on:reset="resetTreeData">
</GuiLeftSider>
<template #content>
<a-doption @click="onShowCurvesClick">显示曲线</a-doption>
<a-doption @click="openCurveSaveDialogForSelectedFiles">数据导出</a-doption>
<!-- <a-doption>Option 3</a-doption> -->
</template>
</a-dropdown>
</a-layout-sider>
<a-layout-content class="right">
<GuiForDataShow ref="GuiForDataShow"></GuiForDataShow>
</a-layout-content>
</a-layout>
<!-- <a-layout-footer>Footer</a-layout-footer> -->
<!-- 保存文件弹窗 -->
<SaveFileDialog v-model:visible="showSaveDialog" :files="filesToSave" @save="handleSaveFiles"
@cancel="handleCancelSave" />
</a-layout>
</template>
<script>
import menubardatavue from './menuvue/menubar.vue';
import GuiForDataShow from './vuecomponents/GuiForDataShow.vue';
import GuiLeftSider from './vuecomponents/GuiLeftSider.vue';
import SaveFileDialog from './vuecomponents/SaveFileDialog.vue';
import { fs } from '@tauri-apps/api';
import { ElMessage } from 'element-plus';
export default {
name: 'APPDataview',
components: {
menubardatavue,
GuiForDataShow,
GuiLeftSider,
SaveFileDialog
},
data() {
return {
// 初始化数据
message: '欢迎使用 Vue!',
selectedFilePath: null, // 存储当前选中的文件路径
selectedFilePaths: [], // 存储多选的文件路径
treeData: [
{
title: 'Trunk 0-0',
key: '0-0',
children: [
{
title: 'Branch 0-0-0',
key: '0-0-0',
children: [
{
title: 'Leaf',
key: '0-0-0-0',
},
{
title: 'Leaf',
key: '0-0-0-1',
}
]
},
{
title: 'Branch 0-0-1',
key: '0-0-1',
children: [
{
title: 'Leaf',
key: '0-0-1-0',
},
]
},
],
},
],
showSaveDialog: false,
filesToSave: [],
}
},
methods: {
// 处理单个文件选择(单击)
async ononeFilechoese(filePath) {
// console.log('选中文件路径:', filePath);
// 只记录选中的文件路径,不立即加载数据
this.selectedFilePath = filePath;
},
// 处理文件双击事件
async onFileDblClick(filePath) {
// console.log('双击文件路径:', filePath);
// 双击时加载数据
this.$refs.GuiForDataShow.onloaddata([filePath]);
},
// 处理多个文件选择当使用Shift或Ctrl多选时
async onFilesSelected(filePaths) {
// console.log('多选文件路径:', filePaths);
// 存储多选的文件路径
this.selectedFilePaths = filePaths;
// 多选时,可以选择不自动加载数据,等待用户进一步操作
if (filePaths && filePaths.length > 0) {
this.selectedFilePath = filePaths[0];
}
},
// 处理文件夹点击事件
async onFolderClicked(folderPath, childFilePaths) {
// console.log('选中文件夹:', folderPath);
// console.log('文件夹下的文件:', childFilePaths);
// 存储文件夹下的文件路径
this.selectedFilePaths = childFilePaths;
},
// 处理文件夹双击事件
async onFolderDblClick(folderPath, childFilePaths) {
// console.log('双击文件夹:', folderPath);
// console.log('文件夹下的文件:', childFilePaths);
// 如果文件夹下有文件,则加载所有文件
if (childFilePaths && childFilePaths.length > 0) {
// 将所有文件路径传递给 GuiForDataShow 组件
this.$refs.GuiForDataShow.onloaddata(childFilePaths);
}
},
// 处理"显示曲线"菜单项点击事件
async onShowCurvesClick() {
// console.log('点击显示曲线菜单项');
// 如果有多选文件,则加载所有选中的文件
if (this.selectedFilePaths && this.selectedFilePaths.length > 0) {
// console.log('加载多选文件:', this.selectedFilePaths);
this.$refs.GuiForDataShow.onloaddata(this.selectedFilePaths);
} else if (this.selectedFilePath) {
// 如果只有单选文件,则加载单个文件
// console.log('加载单选文件:', this.selectedFilePath);
this.$refs.GuiForDataShow.onloaddata(this.selectedFilePath);
}
},
resetTreeData() {
this.selectedFilePaths = []
this.$refs.GuiForDataShow.onloaddata(this.selectedFilePaths);
},
// 处理保存文件请求
onSaveFilesRequested(selectedFiles) {
this.filesToSave = selectedFiles
this.showSaveDialog = true
},
// 处理保存文件
async handleSaveFiles(saveData) {
try {
const { files, location } = saveData
for (const file of files) {
// 构建目标文件路径
const fileName = file.label
const targetPath = `${location}/${fileName}`
// 复制文件
await fs.copyFile(file.path, targetPath)
}
ElMessage.success(`成功保存 ${files.length} 个文件到 ${location}`)
} catch (error) {
console.error('保存文件失败:', error)
alert('保存文件失败: ' + error.message)
}
},
// 取消保存
handleCancelSave() {
this.showSaveDialog = false
this.filesToSave = []
},
async openCurveSaveDialogForSelectedFiles() {
const paths = (this.selectedFilePaths && this.selectedFilePaths.length > 0)
? this.selectedFilePaths
: (this.selectedFilePath ? [this.selectedFilePath] : []);
if (!paths.length) {
alert('请先选择一个或多个文件后再导出');
return;
}
this.$refs.GuiForDataShow.openSaveCurveDialogByPaths(paths);
},
},
}
</script>
<style scoped>
/* 样式区域 */
h1 {
color: #42b983;
}
.right {
flex: 1;
background-color: #f3f5fa;
overflow: auto;
height: 100%;
width: 100%;
}
</style>

View File

@ -0,0 +1,12 @@
export default {
install(app, options) {
// 将整个 myFileMethod 实例挂载到全局属性 $fileUtils
app.config.globalProperties.$fileUtils = myFileMethod;
// 将 isElectron 函数也挂载到全局属性 $isElectron
app.config.globalProperties.$isElectron = isElectron;
// 如果还有其他全局组件、指令等,也可以在这里注册
// app.component('MyGlobalComponent', MyGlobalComponent);
// app.directive('my-directive', myDirective);
console.log('fileUtilsPlugin 已安装');
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 978 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Some files were not shown because too many files have changed in this diff Show More