← 所有文章

兩段線性曲線交界如何處理重複或跳變值

· 站長

以兩段 x=0..50→y=0..80、x=50..100→y=80..100 的案例,教導唯一邊界歸屬、跳變規格與反算多值限制。

一 先定兩段曲線與邊界歸屬

兩段線性換算不是把兩個 IF 接在一起就完成。先把輸入範圍、輸出端點和交界歸屬寫成規格。本篇案例採 x=0..100,分成第一段 x∈[0,50),由 y=0..80;第二段 x∈[50,100],由 y=80..100。第一段含左端不含右端,第二段含兩端,x=50 只有第二段能處理。

第一段斜率為 (80-0)/(50-0)=1.6,所以 y=1.6x。第二段斜率為 (100-80)/(100-50)=0.4,所以 y=80+0.4(x-50)。代入 x=25 得 40,x=50 得 80,x=75 得 90。這三個數字應先寫進離線測試表,再設計 PLC 中的分支。

每次運算先判斷輸入是否有效,再判斷它屬於哪一段;不要讓兩段各自用 x<=50,造成交界被重複處理。若資料超出 0..100,需明確選擇 Reject 或 Clamp,並保存原值。本文採用 OutOfRange 狀態示例,不把超界悄悄送入第一段或第二段。

區間 端點 公式 邊界規則
第一段 x=0..50 y=1.6x [0,50)
第二段 x=50..100 y=80+0.4(x-50) [50,100]
低於範圍 x<0 不計算 Reject/ClampLow
高於範圍 x>100 不計算 Reject/ClampHigh

兩段端點目前連續,第一段接近 50 時 y 接近 80,第二段在 50 時 y=80。連續不代表斜率相同;x=49.9 與 x=50.1 的輸出變化速度不同,這可能影響控制器對微小輸入變化的反應,必須列為適用限制。

兩段曲線的節點資料也要保留單位與版本。例如 x 是攝氏度、y 是百分比時,x=50 的物理意義必須寫清楚,不能只在程式註解留下數字。若日後把 y 改成工程單位,應建立新 curve_version,舊資料仍依原版本重算,避免同一歷史紀錄被兩套斜率解讀。

二 正算案例與重複 IF 的錯誤

用 本篇測試資料逐筆計算。x=0 走第一段得到 0,x=25 得 40;x=49 得 78.4。x=50 必須走第二段得到 80,x=75 得 90,x=100 得 100。若把 x=50 留在第一段,數值恰好仍為 80,錯誤可能被掩蓋;因此驗收還要檢查 branch_id,確認邊界歸屬不是只看 y。

若程式先寫 IF x<=50 計算第一段,再寫 IF x>=50 計算第二段,x=50 會被寫兩次。本例兩式在交界都得到80,數值暫時相同;若日後端點不同或分支有計數等副作用,執行順序就會影響結果。正確做法是先設定 branch_id=Invalid,再使用互斥的 IF/ELSE IF 或等價的單一路徑,讓每個有效 x 只產生一次輸出。

x 預期區段 計算 y 驗收
0 第一段 1.6×0 0 branch=A
25 第一段 1.6×25 40 branch=A
49 第一段 1.6×49 78.4 branch=A
50 第二段 80+0.4×0 80 branch=B
75 第二段 80+0.4×25 90 branch=B
100 第二段 80+0.4×50 100 branch=B

浮點數比較要考慮資料型別。如果 x 來自整數,邊界 50 可以精確比較;若 x 是量測後的浮點值,仍應保留原始值與比較結果,不能用任意四捨五入把 49.999 變成 50 而改變區段。是否要設死區或容差,是規格決定的另一件事。

本例的表格是數學驗收資料,不是某個 PLC 的現成指令。實作時需核對目標語言的浮點常數、型別轉換、比較運算和除法精度,並確認 x=100 的右端是否允許。

測試時除整數點外,還要使用靠近交界的 49.999 與 50.001。前者只能進第一段,後者只能進第二段;若浮點解析度不足,應在規格中定義可接受誤差與輸入量化方式。不能因兩筆 y 看起來接近,就省略 branch_id 的核對。

三 交界跳變先修規格

若第一段終點被規格寫成 y=80,第二段起點卻寫成 y=82,x=50 會出現兩個問題:第一段的最後一點趨近 80,第二段在交界直接給 82;若兩個分支都包含 50,還會有重複歸屬。這不是靠多寫一個 IF 就能修好的程式問題,而是輸入輸出規格本身不連續。

應先與製程負責人決定交界策略:修正第二段起點為 80 以保持連續;或明確接受 2 單位跳變,並在驗收與警報說明中記錄。若選擇平滑過渡,也要重新定義曲線,而不是在程式中偷偷加補償。本文後續沿用連續的 80,跳變版本只作失敗測試。

版本 第一段 x→y 第二段 x→y x=50結果 判定
連續規格 0→0、50→80 50→80、100→100 80 可用
跳變規格 0→0、50→80 50→82、100→100 依歸屬為80或82 需求未決,不可交付
重複IF 兩段都含50 兩段都含50 取決於最後寫入 程式錯誤
缺口規格 第一段<50 第二段>50 50無分支 漏值

驗收不只測 x=25、50、75,還要測 49.999、50、50.001,並記錄 branch_id、y_raw、y_display。若規格接受跳變,三個點的差異應出現在需求文件;若規格要求連續,則 x=50 左右的結果必須符合允差。

來源資料若本來就是校正表,也可能出現不單調或重複 x。先檢查節點排序、唯一性與端點,不能套用分段公式後才發現輸入表不滿足假設。

若現場要求輸出平滑,應把平滑器視為曲線外的另一個功能,分別驗收原始分段值與平滑後值。直接在交界處偷偷加減一個補償,會使反算公式失去對應關係。每次版本變更都要重新列出兩段斜率、端點和允差。

四 反算 多值與非單調限制

正算曲線只有在嚴格單調且區段輸出範圍清楚時,才適合直接反算。此例第一段 y=0..80,第二段 y=80..100,反算時 y∈[0,80) 走第一段 x=y/1.6;y∈[80,100] 走第二段 x=50+(y-80)/0.4。y=80 應選定唯一區段,例如歸給第二段,得到 x=50。

若兩段都能產生相同 y,例如第一段 y=0..80、第二段 y=80..0,反算 y=40 會有兩個 x。這是多值關係,不能用一個 IF 假裝只有一個答案。資料模型應回傳候選數量、候選 x 或拒絕反算,並說明控制用途不能直接採任意一個。

若曲線有平坦區,像 y=80 在 x=50..60 都不變,反算 y=80 會得到一整段 x,而不是單一 x。若輸出曲線非單調,反算不能直接對輸出值做單調二分搜尋;輸入節點仍可按x排序作正常正算插值。先用節點檢查輸入輸出是否嚴格遞增或遞減,再決定可用的反算演算法。

y輸入 反算區間 x計算 結果性質
0 第一段 0/1.6 x=0
40 第一段 40/1.6 x=25
80 第二段 50+(0/0.4) x=50,邊界唯一
90 第二段 50+10/0.4 x=75
100 第二段 50+20/0.4 x=100

反算的驗收要先定端點歸屬,再測 y=80。若把 y=80 先四捨五入或夾限,可能把 79.96 和 80.04 都送到同一段,造成看似穩定但實際錯誤。保留 y_raw、segment_id 和 clamp_state,才能追查分支決策。

反算流程應先檢查 y 是否位於某一段的輸出範圍,再決定區段。若兩段輸出範圍重疊,回傳候選清單與數量;若沒有候選,回傳 OutOfRange。把 y 先夾到 0..100 會掩蓋無效輸入,因此夾限狀態必須和結果分欄保存。

五 驗收 FAQ與來源

本篇驗收表應至少包括 x=0、25、49、50、75、100、-1、101,以及兩段跳變版的 x=50。每筆同時核對 y、segment_id、valid 與邊界狀態。若輸入超界採 Reject,就不得留下看似正常的 y;若採 Clamp,畫面值與狀態必須分開。

提交前再檢查三件事:每個有效 x 只有一個區段、端點規格沒有缺口或重複、反算在單調條件下能回到原 x。任何一項不成立,就先回到規格或資料表修正,不能用重複判斷把問題藏起來。

FAQ1:為什麼 x=50 必須明確指定第二段?答:因為第一段採 [0,50),第二段採 [50,100],這樣每個有效輸入只有唯一歸屬。

FAQ2:若第一段終點 80、第二段起點 82,應如何處理?答:先修正規格或明確接受跳變,不能靠兩個 IF 重複寫值掩蓋缺口。

FAQ3:y=80 反算是否一定只有 x=50?答:在本案例的連續且單調定義下是 x=50;若曲線平坦或非單調,可能是多個 x,必須回傳多值或拒絕。

FAQ4:NumPy 的 interp 可以直接當 PLC 指令嗎?答:不能。它只作一維插值的數學參考;PLC 實作仍需核對目標語言的型別、比較、除法與邊界行為。

參考:NumPy interp 官方文件:要求樣本點遞增,提供一維分段線性插值與左右邊界參數(僅作數學參考,非 PLC API)。

參考:NIST Dataplot Linear Interpolation:線性插值與端點計算概念(僅作數學參考)。

延伸閱讀


使用 PLC 工具箱 →