压电定位平台采用闭环控制,核心原因是压电陶瓷的实际位移会受到迟滞、蠕变、温度、负载、安装刚度和驱动电压误差影响。开环控制只能根据电压或模型估算位移,闭环控制则用独立位置传感器测量实际运动,并根据位置误差修正驱动命令。
闭环并不等于自动获得高精度。闭环效果取决于传感器测量基准、噪声、分辨率、带宽、安装位置、控制器参数、采样同步和机械结构。评价压电定位平台时,应分别报告分辨率、重复性、准确度、稳定时间和闭环带宽,不能笼统写成“纳米精度”。
本文给出一个Python教学程序,用于分析位置日志中的稳态误差、峰峰噪声和多次定位重复性。示例数据由确定性输入生成,不是任何压电平台的产品实测数据。
1. 开环和闭环到底差在哪里
| 项目 | 开环压电控制 | 闭环压电控制 |
|---|---|---|
| 位移来源 | 电压与位移模型或标定曲线 | 位置传感器实时测量 |
| 迟滞影响 | 需要模型补偿,残差随历史路径变化 | 可由反馈误差修正,但受带宽和噪声限制 |
| 蠕变影响 | 保持期间位置可能继续漂移 | 控制器可修正漂移,但可能增加动作和噪声 |
| 负载变化 | 模型与实际位移可能不一致 | 传感器可观察负载导致的实际位置变化 |
| 结构复杂度 | 传感器、采集和控制环节较少 | 需要传感器、同步采集、控制器和稳定的机械基准 |
| 适用边界 | 重复性要求、环境和负载较稳定的场景 | 需要抑制漂移、负载变化或绝对位置误差的场景 |
2. 闭环定位必须先定义测量基准
位置传感器测到的是传感器测头与参考基准之间的相对位移。若传感器安装在柔性支架、基座或与执行器不同的结构上,传感器读数不一定等于工作端真实位移。
| 基准问题 | 可能造成的误判 | 验证方法 |
|---|---|---|
| 传感器测点远离工作端 | 读数稳定但末端发生结构变形 | 改变负载和测点,比较工作端与传感器读数 |
| 传感器安装支架柔性 | 闭环把支架变形当成执行器位移 | 做静态力加载和结构刚度检查 |
| 传感器零点漂移 | 控制器持续修正,输出出现慢变 | 记录传感器温度、零点和独立参考 |
| 采样不同步 | 误差相位变化,出现振荡或假超调 | 统一时间戳,测量采样延迟和抖动 |
| 传感器带宽不足 | 快速运动被滤波,稳定时间被低估 | 扫频或阶跃测试传感器幅相响应 |
3. 开环与闭环定位测试架构
闭环控制增加了位置传感器和反馈路径,测试时要同步记录命令、反馈与工作端结果。
4. 闭环定位测试步骤
- 固定机械安装、预紧、负载、环境温度和传感器测点。
- 记录位置传感器型号、量程、分辨率、采样率、滤波、校准状态和测量基准。
- 分别记录命令位移、驱动器实际输出、传感器反馈和工作端独立测量。
- 先做静止噪声测试,再做单向阶跃、往返定位和长时间保持。
- 每个目标位置等待规定稳定时间,避免把瞬态误差当作定位误差。
- 改变一个变量,例如负载、温度、方向或控制带宽,观察误差指标如何变化。
- 至少进行多次独立重复,分别计算重复性、最大误差和漂移。
- 报告数据状态,明确哪些是实测、理论、仿真或教学示例。
5. 软件、硬件与测试条件
| 类别 | 记录内容 |
|---|---|
| 压电平台 | 执行器、驱动器、机械负载、预紧、安装刚度和工作端测点 |
| 位置反馈 | 传感器类型、量程、分辨率、带宽、采样率、滤波、校准和基准 |
| 控制器 | 控制周期、输出更新率、控制算法、限幅、抗积分饱和和延迟 |
| 测试轨迹 | 目标位置、步长、方向、保持时间、往返次数和停止判据 |
| 环境 | 温度、振动、气流、机械支撑、线缆拖链和热稳定时间 |
| 本文软件 | Windows 11 64位,Python 3.12.13,仅使用csv、statistics和math标准库 |
6. 定位误差、重复性和噪声如何区分
position_error = measured_position - command_position
steady_state_error = mean(error_in_stable_window)
noise_peak_to_peak = max(feedback) - min(feedback)
repeatability = max(cycle_means) - min(cycle_means)
maximum_absolute_error = max(abs(position_error))
分辨率描述可分辨的最小变化,重复性描述多次回到同一目标的离散程度,准确度描述测量结果与参考真值的接近程度。三者需要不同测试设计,不能用一个数字替代。
7. Python定位日志分析代码
CSV列名为cycle_id、command_um、measured_um和stable_flag。程序对稳定窗口计算平均误差、最大绝对误差、窗口噪声和多次循环重复性。数据单位使用um只是示例单位,不代表产品指标。
python piezo_closed_loop_test.py --self-test
python piezo_closed_loop_test.py position_log.csv
from __future__ import annotations
import argparse
import csv
import json
import math
import statistics
from pathlib import Path
REQUIRED = {"cycle_id", "command_um", "measured_um", "stable_flag"}
def number(value: str, field: str, line: int) -> float:
try:
result = float(value)
except (TypeError, ValueError) as exc:
raise ValueError(f"invalid {field} at line {line}") from exc
if not math.isfinite(result):
raise ValueError(f"non-finite {field} at line {line}")
return result
def load(path: Path):
with path.open("r", encoding="utf-8-sig", newline="") as handle:
reader = csv.DictReader(handle)
missing = REQUIRED - set(reader.fieldnames or [])
if missing:
raise ValueError(f"missing columns: {sorted(missing)}")
rows = []
for line, raw in enumerate(reader, start=2):
rows.append({"cycle_id": raw["cycle_id"], "command_um": number(raw["command_um"], "command_um", line), "measured_um": number(raw["measured_um"], "measured_um", line), "stable_flag": raw["stable_flag"].strip().lower() in {"1", "true", "yes"}})
if not rows:
raise ValueError("CSV contains no rows")
return rows
def analyze(rows):
stable = [row for row in rows if row["stable_flag"]]
if not stable:
raise ValueError("no stable samples")
errors = [row["measured_um"] - row["command_um"] for row in stable]
cycle_means = {}
for row, error in zip(stable, errors):
cycle_means.setdefault(row["cycle_id"], []).append(error)
means = [statistics.fmean(values) for values in cycle_means.values()]
return {"stable_sample_count": len(stable), "cycle_count": len(means), "mean_error_um": statistics.fmean(errors), "maximum_absolute_error_um": max(abs(value) for value in errors), "noise_peak_to_peak_um": max(errors) - min(errors), "repeatability_um": max(means) - min(means)}
def self_test():
rows = [{"cycle_id": str(cycle), "command_um": 10.0, "measured_um": value, "stable_flag": True} for cycle, value in [(1, 10.10), (1, 10.18), (2, 10.14), (2, 10.16), (3, 10.16), (3, 10.22)]]
result = analyze(rows)
assert result["stable_sample_count"] == 6
assert result["cycle_count"] == 3
assert abs(result["mean_error_um"] - 0.16) < 1e-12
assert abs(result["maximum_absolute_error_um"] - 0.22) < 1e-12
assert abs(result["noise_peak_to_peak_um"] - 0.12) < 1e-12
assert abs(result["repeatability_um"] - 0.05) < 1e-12
print("SELF_TEST_OK")
print(json.dumps(result, ensure_ascii=False, indent=2))
def main():
parser = argparse.ArgumentParser(description="Analyze piezo closed-loop positioning logs")
parser.add_argument("csv_path", nargs="?", type=Path)
parser.add_argument("--self-test", action="store_true")
args = parser.parse_args()
if args.self_test:
self_test()
elif args.csv_path is None:
parser.error("csv_path is required")
else:
print(json.dumps(analyze(load(args.csv_path)), ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
代码只分析已标记的稳定窗口,不自动判断稳定时间,也不替代控制器安全限幅和传感器校准。
8. 教学结果
自检构造3次定位循环,每次目标10.0 um,每次包含两个稳定样本。结果用于验证统计计算,不代表任何产品性能。
| 项目 | 结果 | 状态 |
|---|---|---|
| 稳定样本数 | 6 | 通过 |
| 平均误差 | 0.16 um | 教学计算 |
| 最大绝对误差 | 0.22 um | 教学计算 |
| 窗口峰峰噪声 | 0.12 um | 教学计算 |
| 三次循环重复性 | 0.05 um | 教学计算 |
闭环可以减小部分误差,但测量基准、噪声和带宽仍决定最终结果。
9. 常见问题
9.1 压电平台开环一定不能用吗
不是。环境、负载和轨迹稳定,且允许通过标定和模型补偿控制误差时,开环可能更简单。是否闭环取决于目标指标和扰动边界。
9.2 闭环后就一定没有迟滞吗
不会。反馈可以修正可观测的位移误差,但传感器分辨率、带宽、控制延迟和机械耦合会限制修正效果。
9.3 位置传感器分辨率等于平台分辨率吗
不等于。平台分辨率还受噪声、量化、控制器、机械结构和测量基准影响,不能只看传感器标称分辨率。

9.4 为什么闭环会振荡
可能与控制增益、传感器延迟、机械共振、滤波相位和输出限幅有关。应先记录命令、反馈和控制周期,再逐项改变参数。
9.5 重复性和准确度怎么区分
重复性关注多次回到同一目标的一致程度,准确度关注结果与参考真值的接近程度,需要不同的参考和测试设计。
9.6 传感器装在基座上可以测工作端吗
不一定。基座、支架和工作端可能存在相对变形,应验证传感器测点与实际工作点的机械关系。

9.7 为什么要记录稳定时间
没有稳定窗口,瞬态超调、蠕变和噪声会混入定位误差,导致结果不可重复比较。
9.8 示例um数据能作为产品精度吗
不能。示例只验证代码,产品精度必须有型号、仪器、环境、样本数和统计方法完整的测试记录。
10. 结论
压电定位平台采用闭环,是为了测量实际位置并抑制迟滞、蠕变、负载和驱动误差带来的偏差。但闭环本身不是性能承诺,必须同时验证传感器基准、噪声、带宽、采样同步、控制参数和机械结构。
发布或比较压电定位平台时,应分别报告分辨率、重复性、准确度、稳定时间和闭环带宽。本文Python程序和示意数据用于复现统计方法,不代表任何具体产品实测指标。

参考资料
- IEEE,ANSI/IEEE Std 176-1987,IEEE Standard on Piezoelectricity,1988。官方来源
- JCGM,JCGM 100:2008,Evaluation of measurement data - Guide to the expression of uncertainty in measurement。官方来源
- ISO,ISO 230-2:2014,Test code for machine tools - Part 2: Determination of accuracy and repeatability of positioning。标准组织页面
- ISO,ISO 5725-1:1994,Accuracy of measurement methods and results - Part 1。标准组织页面
- Python Software Foundation,csv - CSV File Reading and Writing,Python 3.12文档。Python文档
- Python Software Foundation,statistics - Mathematical statistics functions,Python 3.12文档。Python文档



418

被折叠的 条评论
为什么被折叠?



