跳到正文
PreciSim
dev

vmc.dll API

C 风格导出的虚拟机台控制接口,任何语言都能 P/Invoke。

它是什么

vmc.dll(virtual machine control)把虚拟机台暴露成一组 C 函数。 用途有两个:自动化测试(在 CI 里跑标定流程)和教学(用 Python 写脚本驱动设备)。

接口是 C 风格导出,没有 C++ 名字修饰,没有 COM,没有 .NET 依赖—— ctypesP/InvokeJNA、LabVIEW 都能直接调。

生命周期

// 返回句柄,失败返回 NULL
VMC_HANDLE vmc_open(const char* machineConfigPath);
void       vmc_close(VMC_HANDLE h);
 
// 最近一次错误,线程局部
int         vmc_last_error(VMC_HANDLE h);
const char* vmc_last_error_message(VMC_HANDLE h);

所有函数返回 0 表示成功,负数表示错误码(见错误码)。

int vmc_axis_home(VMC_HANDLE h, const char* axisId);
int vmc_axis_move_abs(VMC_HANDLE h, const char* axisId, double targetMm, int waitMs);
int vmc_axis_move_rel(VMC_HANDLE h, const char* axisId, double deltaMm, int waitMs);
int vmc_axis_position(VMC_HANDLE h, const char* axisId, double* outMm);
int vmc_axis_stop(VMC_HANDLE h, const char* axisId);

waitMs = 0 表示不等待立即返回,-1 表示一直等到到位。

相机

// 抓一帧到调用方提供的缓冲区;bufSize 不足时返回 VMC_E_BUFFER_TOO_SMALL
int vmc_cam_grab(VMC_HANDLE h, const char* camId,
                 unsigned char* buf, int bufSize,
                 int* outWidth, int* outHeight, int* outStride);
 
int vmc_cam_set_exposure(VMC_HANDLE h, const char* camId, double us);
int vmc_cam_set_gain(VMC_HANDLE h, const char* camId, double db);

图像是 8 位灰度,行优先,stride 可能大于 width(对齐)。

IO

int vmc_io_read(VMC_HANDLE h, int channel, int* outValue);
int vmc_io_write(VMC_HANDLE h, int channel, int value);

标定链

// 同步跑完一条链;结果以 JSON 写入 outJson
int vmc_calib_run(VMC_HANDLE h, const char* procedureId,
                  const char* paramsJson,
                  char* outJson, int outJsonSize);
 
// 读当前生效的标定结果
int vmc_calib_get(VMC_HANDLE h, const char* procedureId,
                  char* outJson, int outJsonSize);

procedureId 取值:C1-pixel-sizeC2-hand-eyeC3-intrinsicsC4-galvo-fieldC5-z-focusC6-stage-geometry

返回的 JSON 含真值对照(虚拟设备才有):

{
  "procedure": "C1-pixel-size",
  "ok": true,
  "solved": { "mmPerPx": 0.019823, "thetaRad": 0.0041, "skew": 1.6e-4 },
  "truth":  { "mmPerPx": 0.019841, "thetaRad": 0.0039 },
  "verify": { "deviationMm": 0.018, "toleranceMm": 0.05, "pass": true },
  "residual": { "rmsPx": 0.081, "maxPx": 0.213 }
}

误差模型注入

测试里最有用的一组接口:故意把设备调坏,看你的程序会不会发现。

int vmc_fault_set(VMC_HANDLE h, const char* deviceId,
                  const char* faultJson);
int vmc_fault_clear(VMC_HANDLE h, const char* deviceId);
{ "backlashUm": 50, "noiseScale": 4.0, "k1": -0.08, "stuckAt": null }

版本与兼容

int vmc_version(char* outSemver, int size);

接口是版本化的1.x 内只增不改,破坏性变更只出现在大版本。 你的测试代码应该在启动时检查主版本号。

线程

一个 VMC_HANDLE 不是线程安全的。多线程请各开各的句柄,或者自己加锁。 虚拟设备本身支持多实例并行(CI 里并行跑测试没问题)。

最后更新: 2026/9/21
这页有帮助吗?