1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
| import numpy as np import matplotlib.pyplot as plt from dataclasses import dataclass
@dataclass class Microstructure: """五级环形柱微结构参数""" levels = [ {'radius_mm': 2.0, 'height_mm': 0.5, 'threshold_kPa': 5}, {'radius_mm': 1.5, 'height_mm': 1.0, 'threshold_kPa': 15}, {'radius_mm': 1.0, 'height_mm': 1.5, 'threshold_kPa': 30}, {'radius_mm': 0.5, 'height_mm': 2.0, 'threshold_kPa': 50}, {'radius_mm': 0.2, 'height_mm': 2.5, 'threshold_kPa': 80}, ] class PiezoresistiveSensor: """ 压阻式柔性传感器 五级微结构实现分级灵敏度 """ def __init__(self): self.structure = Microstructure() self.base_resistance = 100e3 self.elm_weights = None def pressure_to_resistance(self, pressure_kPa: float) -> float: """ 压力→电阻关系(五级分级) 每级接触提供额外的导电通道 """ r = self.base_resistance for i, level in enumerate(self.structure.levels): if pressure_kPa > level['threshold_kPa']: contact_ratio = min( (pressure_kPa - level['threshold_kPa']) / 10, 1.0 ) r *= (1 - 0.15 * contact_ratio * (1 + i*0.2)) return r def pressure_to_voltage(self, pressure_kPa: float, supply_v: float = 3.3) -> float: """分压电路输出""" r_sensor = self.pressure_to_resistance(pressure_kPa) r_reference = 100e3 return supply_v * r_reference / (r_sensor + r_reference) def elm_calibrate(self, pressures: np.ndarray, voltages: np.ndarray, n_hidden: int = 100): """ ELM极限学习机校准 快速非线性补偿:电压→压力 ELM优势:单次训练,无需迭代 """ n_samples = len(voltages) np.random.seed(42) W = np.random.randn(n_hidden, 1) * 10 b = np.random.randn(n_hidden, 1) * 5 H = 1 / (1 + np.exp(-(W @ voltages.reshape(1, -1) + b))) self.elm_weights = np.linalg.pinv(H.T) @ pressures def elm_predict(self, voltage: float) -> float: """ELM预测压力""" W = np.random.randn(len(self.elm_weights), 1) * 10 b = np.random.randn(len(self.elm_weights), 1) * 5 h = 1 / (1 + np.exp(-(W * voltage + b))) return np.dot(h.flatten(), self.elm_weights) def measure(self, voltage: float) -> float: """电压→压力(ELM校准后)""" if self.elm_weights is not None: return self.elm_predict(voltage) else: return (3.3 - voltage) / 3.3 * 100
class SeatPressureArray: """ 座椅靠背压力阵列 10×10传感器阵列 → 压力分布图 → 姿态分类 """ def __init__(self, rows: int = 10, cols: int = 10): self.rows = rows self.cols = cols self.sensors = [[PiezoresistiveSensor() for _ in range(cols)] for _ in range(rows)] def scan(self) -> np.ndarray: """扫描阵列压力分布""" pressure_map = np.zeros((self.rows, self.cols)) cx, cy = self.rows//2, self.cols//2 for i in range(self.rows): for j in range(self.cols): dist = np.sqrt((i-cx)**2 + (j-cy)**2) pressure_map[i, j] = max(0, 40 - dist * 8) return pressure_map def classify_posture(self, pressure_map: np.ndarray) -> dict: """ 从压力分布分类坐姿 输出:姿态类别+重心偏移 """ total = pressure_map.sum() if total == 0: return {'posture': 'Empty', 'offset': (0, 0)} cy = (pressure_map.sum(axis=1) * np.arange(self.rows)).sum() / total cx = (pressure_map.sum(axis=0) * np.arange(self.cols)).sum() / total offset_y = cy - self.rows/2 offset_x = cx - self.cols/2 if abs(offset_y) < 1.5 and abs(offset_x) < 1.5: posture = 'Normal' elif offset_y > 2: posture = 'Slouching' elif offset_y < -2: posture = 'Leaning Forward' elif offset_x > 2: posture = 'Leaning Right' elif offset_x < -2: posture = 'Leaning Left' else: posture = 'Asymmetric' return { 'posture': posture, 'offset': (offset_x, offset_y), 'total_pressure': total, 'center': (cx, cy), }
if __name__ == "__main__": sensor = PiezoresistiveSensor() pressures = np.linspace(0, 100, 100) resistances = [sensor.pressure_to_resistance(p) for p in pressures] voltages = [sensor.pressure_to_voltage(p) for p in pressures] print("五级微结构传感器特性:") for p in [0, 10, 25, 45, 65, 90]: r = sensor.pressure_to_resistance(p) v = sensor.pressure_to_voltage(p) print(f" {p:3.0f}kPa → R={r/1e3:.1f}kΩ, V={v:.2f}V") array = SeatPressureArray(10, 10) pressure_map = array.scan() result = array.classify_posture(pressure_map) print(f"\n座椅压力阵列:") print(f" 姿态: {result['posture']}") print(f" 重心: ({result['center'][0]:.1f}, {result['center'][1]:.1f})") print(f" 偏移: ({result['offset'][0]:.1f}, {result['offset'][1]:.1f})") print(f" 总压力: {result['total_pressure']:.0f}kPa")
|