Initial commit

This commit is contained in:
zhangshun
2026-06-01 15:55:59 +08:00
commit 40f9bdb590
1799 changed files with 362227 additions and 0 deletions

394
scripts/build.ps1 Normal file
View File

@@ -0,0 +1,394 @@
# build.ps1 - 智能 WASM 构建脚本
param(
[switch]$Clean,
[switch]$Serve,
[switch]$Test,
[string]$BuildType = "Release"
)
Write-Host "=========================================" -ForegroundColor Cyan
Write-Host " 智能 JSON-WASM 项目构建系统 " -ForegroundColor Cyan
Write-Host "=========================================" -ForegroundColor Cyan
Write-Host ""
# 1. 设置环境变量
$EmsdkPath = "E:\emsdk"
if (-not (Test-Path $EmsdkPath)) {
Write-Host "[错误] 未找到 Emscripten" -ForegroundColor Red
Write-Host "请确保 Emscripten 安装在: $EmsdkPath" -ForegroundColor Yellow
exit 1
}
# 设置 PATH
$env:PATH = "$EmsdkPath\upstream\emscripten;$env:PATH"
Write-Host "[✓] 设置 Emscripten 环境" -ForegroundColor Green
# 2. 清理旧构建
if ($Clean) {
Write-Host "[ ] 清理构建文件..." -ForegroundColor Cyan
Remove-Item -Path "build", "public/wasm" -Recurse -Force -ErrorAction SilentlyContinue
Write-Host "[✓] 清理完成" -ForegroundColor Green
}
# 3. 创建目录
New-Item -Path "build", "public/wasm" -ItemType Directory -Force | Out-Null
# 4. 编译 WASM
Write-Host "[ ] 编译智能 WASM 模块..." -ForegroundColor Cyan
$startTime = Get-Date
# 编译命令 - 使用当前真实业务模块源码
$compileResult = emcc `
src/KinematicsWebAPI.cpp `
src/main.cpp `
src/Robot.cpp `
src/spc_core.cpp `
src/QuadrupedRobotSimulation/RobotConfig.cpp `
src/QuadrupedRobotSimulation/BaseClass.cpp `
src/QuadrupedRobotSimulation/KinematicsSimulation.cpp `
src/QuadrupedRobotSimulation/CompleteJsonExporter.cpp `
src/QuadrupedRobotSimulation/KinematicsReverse.cpp `
src/QuadrupedRobotSimulation/KinematicsHelper.cpp `
src/QuadrupedRobotSimulation/SharedGeometry.cpp `
src/FourBarMechanism/CrankSliderMechanism.cpp `
src/FourBarMechanism/CrankRockingBlockMechanism_Forward.cpp `
src/FourBarMechanism/CrankRockingBlockMechanism_Inverse.cpp `
src/FourBarMechanism/FourBarMechanism.cpp `
src/FourBarMechanism/SliderCrankMechanism.cpp `
src/RobotManager.cpp `
src/utils.cpp `
src/math_utils.cpp `
src/smart_json_wrapper.cpp `
src/kdl_parser/src/kdl_parser.cpp `
src/kdl_parser/src/joint.cpp `
src/kdl_parser/src/link.cpp `
src/kdl_parser/src/model.cpp `
src/kdl_parser/src/pose.cpp `
src/kdl_parser/src/tinystr.cpp `
src/kdl_parser/src/tinyxml.cpp `
src/kdl_parser/src/tinyxml2.cpp `
src/kdl_parser/src/tinyxmlerror.cpp `
src/kdl_parser/src/tinyxmlparser.cpp `
src/kdl_parser/src/twist.cpp `
src/kdl_parser/src/world.cpp `
-I./inc `
-I./inc/QuadrupedRobotSimulation `
-I./inc/FourBarMechanism `
-I./inc/SharedGeometry `
-I./src/kdl_parser/include `
-I./KDL/install_wasm/include `
-I./Eigen3 `
-I./Eigen3/eigen3 `
-L./KDL/install_wasm/lib `
-lorocos-kdl `
-std=c++17 `
-s WASM=1 `
-s EXPORTED_FUNCTIONS='["_init_func","_func","_smart_process_json","_smart_get_function_list","_smart_get_function_info","_smart_test_match","_smart_get_version","_smart_free_string","_wasm_malloc","_wasm_free","_malloc","_free","_add","_subtract","_multiply","_divide","_fibonacci","_create_buffer","_destroy_buffer","_compute_sum","_get_greeting","_main"]' `
-s EXPORTED_RUNTIME_METHODS='["UTF8ToString","stringToUTF8","lengthBytesUTF8","ccall","cwrap","HEAPU8","HEAP8","HEAPF32","HEAPF64","allocateUTF8"]' `
-s MODULARIZE=1 `
-s EXPORT_NAME='createSmartMathModule' `
-s ALLOW_MEMORY_GROWTH=1 `
-s ENVIRONMENT='web,node,worker' `
-s ASSERTIONS=1 `
-s DISABLE_EXCEPTION_CATCHING=0 `
-s INITIAL_MEMORY=67108864 `
-s MAXIMUM_MEMORY=268435456 `
-s STACK_SIZE=5242880 `
-s USE_PTHREADS=0 `
-O3 `
-Wno-deprecated-literal-operator `
-o public/wasm/smart_math.js 2>&1
$endTime = Get-Date
$duration = ($endTime - $startTime).TotalSeconds
if ($LASTEXITCODE -ne 0) {
Write-Host "[✗] 编译失败" -ForegroundColor Red
Write-Host $compileResult -ForegroundColor Red
exit 1
}
Write-Host "[✓] 编译完成" -ForegroundColor Green
# 5. 检查生成的文件
$jsFile = Get-Item "public/wasm/smart_math.js" -ErrorAction SilentlyContinue
$wasmFile = Get-Item "public/wasm/smart_math.wasm" -ErrorAction SilentlyContinue
if (-not $jsFile -or -not $wasmFile) {
Write-Host "[✗] 未找到生成文件" -ForegroundColor Red
exit 1
}
$jsSize = $jsFile.Length / 1KB
$wasmSize = $wasmFile.Length / 1KB
# 6. 显示构建结果
Write-Host ""
Write-Host "🎉 构建成功!" -ForegroundColor Green
Write-Host ("" * 50) -ForegroundColor DarkGray
Write-Host "📦 生成文件:" -ForegroundColor White
Write-Host "├─ smart_math.js ($($jsSize.ToString('F1')) KB)" -ForegroundColor Gray
Write-Host "└─ smart_math.wasm ($($wasmSize.ToString('F1')) KB)" -ForegroundColor Gray
Write-Host ""
Write-Host "✨ 功能特性:" -ForegroundColor White
Write-Host "├─ ✅ 机器人正逆解业务接口 (func/init_func)" -ForegroundColor Gray
Write-Host "├─ ✅ SPC / 四足机器人 / 连杆机构业务接口" -ForegroundColor Gray
Write-Host "├─ ✅ 智能 JSON 数学测试接口" -ForegroundColor Gray
Write-Host "├─ ✅ Node / Web 双环境加载" -ForegroundColor Gray
Write-Host "├─ ✅ 与 Emscripten 内存管理兼容" -ForegroundColor Gray
Write-Host "└─ ✅ 批量回归测试可直接调用" -ForegroundColor Gray
Write-Host ""
Write-Host "📁 输出目录: $((Get-Location).Path)\public\wasm" -ForegroundColor Gray
Write-Host "⏱️ 编译耗时: $($duration.ToString('F2'))" -ForegroundColor Gray
Write-Host ""
# 7. 生成 JavaScript 包装器(可选)
Write-Host "[ ] 生成 JavaScript 包装器..." -ForegroundColor Cyan
$jsWrapper = @"
// Smart WASM JSON API JavaScript
class SmartWasmAPI {
constructor() {
this.module = null;
this.initialized = false;
}
async initialize() {
if (this.initialized) return;
// WASM
this.module = await createSmartMathModule();
this.initialized = true;
console.log('Smart WASM API ');
return this;
}
async initializeBusinessApi() {
if (!this.initialized) {
await this.initialize();
}
let responsePtr = null;
try {
responsePtr = this.module._init_func();
const responseStr = this.module.UTF8ToString(responsePtr);
return JSON.parse(responseStr);
} finally {
if (responsePtr) {
this.module._smart_free_string(responsePtr);
}
}
}
async processBusinessRequest(jsonRequest) {
if (!this.initialized) {
await this.initialize();
}
let requestPtr = null;
let responsePtr = null;
try {
requestPtr = this.module.allocateUTF8(JSON.stringify(jsonRequest));
responsePtr = this.module._func(requestPtr);
const responseStr = this.module.UTF8ToString(responsePtr);
return JSON.parse(responseStr);
} catch (error) {
console.error(' JSON :', error);
throw error;
} finally {
if (requestPtr) {
this.module._free(requestPtr);
}
if (responsePtr) {
this.module._smart_free_string(responsePtr);
}
}
}
// JSON
async processJsonRequest(jsonRequest) {
if (!this.initialized) {
await this.initialize();
}
let requestPtr = null;
let responsePtr = null;
try {
// JSON WASM
requestPtr = this.module.allocateUTF8(JSON.stringify(jsonRequest));
// WASM
responsePtr = this.module._smart_process_json(requestPtr);
// JavaScript
const responseStr = this.module.UTF8ToString(responsePtr);
// JSON
return JSON.parse(responseStr);
} catch (error) {
console.error(' JSON :', error);
throw error;
} finally {
//
if (requestPtr) {
this.module._free(requestPtr);
}
if (responsePtr) {
this.module._smart_free_string(responsePtr);
}
}
}
//
async getFunctionList() {
if (!this.initialized) {
await this.initialize();
}
let responsePtr = null;
try {
responsePtr = this.module._smart_get_function_list();
const responseStr = this.module.UTF8ToString(responsePtr);
return JSON.parse(responseStr);
} catch (error) {
console.error(':', error);
throw error;
} finally {
if (responsePtr) {
this.module._smart_free_string(responsePtr);
}
}
}
//
async callFunction(funcName, params = {}) {
const request = {
req_cmd: funcName,
...params
};
return await this.processJsonRequest(request);
}
//
async testSmartMatch(jsonRequest) {
if (!this.initialized) {
await this.initialize();
}
let requestPtr = null;
let responsePtr = null;
try {
requestPtr = this.module.allocateUTF8(JSON.stringify(jsonRequest));
responsePtr = this.module._smart_test_match(requestPtr);
const responseStr = this.module.UTF8ToString(responsePtr);
return JSON.parse(responseStr);
} catch (error) {
console.error(':', error);
throw error;
} finally {
if (requestPtr) {
this.module._free(requestPtr);
}
if (responsePtr) {
this.module._smart_free_string(responsePtr);
}
}
}
//
async getVersion() {
if (!this.initialized) {
await this.initialize();
}
let responsePtr = null;
try {
responsePtr = this.module._smart_get_version();
const responseStr = this.module.UTF8ToString(responsePtr);
return JSON.parse(responseStr);
} catch (error) {
console.error(':', error);
throw error;
} finally {
if (responsePtr) {
this.module._smart_free_string(responsePtr);
}
}
}
// JSON
callMathFunction(name, ...args) {
if (!this.initialized) {
throw new Error('WASM ');
}
switch (name.toLowerCase()) {
case 'add':
return this.module._add(args[0] || 0, args[1] || 0);
case 'subtract':
return this.module._subtract(args[0] || 0, args[1] || 0);
case 'multiply':
return this.module._multiply(args[0] || 0, args[1] || 0);
case 'divide':
return this.module._divide(args[0] || 0, args[1] || 1);
case 'fibonacci':
return this.module._fibonacci(args[0] || 0);
default:
throw new Error(': ' + name);
}
}
}
//
if (typeof window !== 'undefined') {
window.SmartWasmAPI = SmartWasmAPI;
}
export default SmartWasmAPI;
"@
$jsWrapper | Out-File -FilePath "public/wasm/smart_api_wrapper.js" -Encoding UTF8
Write-Host "[✓] 生成 JavaScript 包装器" -ForegroundColor Green
# 8. 本地测试(可选)
if ($Test) {
Write-Host "[ ] 运行本地测试..." -ForegroundColor Cyan
try {
node --version 2>&1 | Out-Null
if ($LASTEXITCODE -eq 0) {
Write-Host "[ ] 执行 WASM 回归测试..." -ForegroundColor Cyan
node scripts/run_wasm_tests.js
}
} catch {
Write-Host "[!] 本地测试跳过(需要 Node.js" -ForegroundColor Yellow
}
}
# 9. 启动开发服务器(可选)
if ($Serve) {
Write-Host "[ ] 启动开发服务器..." -ForegroundColor Cyan
Write-Host " 访问: http://localhost:8080/smart_test.html" -ForegroundColor Yellow
Write-Host " 按 Ctrl+C 停止服务器" -ForegroundColor Yellow
Write-Host ""
Set-Location "public"
python -m http.server 8080
}
Write-Host ""
Write-Host "🚀 使用提示:" -ForegroundColor White
Write-Host "├─ 在 VS Code 中按 F5 启动调试" -ForegroundColor Gray
Write-Host "├─ 使用 Ctrl+Shift+B 快速构建" -ForegroundColor Gray
Write-Host "├─ 查看 public/wasm/smart_api_wrapper.js 了解 JavaScript API 使用" -ForegroundColor Gray
Write-Host "└─ 运行 \`npm run serve\` 启动开发服务器" -ForegroundColor Gray
Write-Host ""