產品發表 包羅萬象 模型拍賣 綜合討論 直昇機 飛機 同協會 回首頁

 找回密碼
 申請
樓主: ej189

打造CP值最高的跨廠牌發射機 Deviation - DEVO10【固定下載】

 火... [複製鏈接]
發表於 2013年3月5日 06:50 PM | 顯示全部樓層

回復 930樓 suvsuvsuv 的帖子


關於 混控曲線(curves.c)中 多點直線( s16 interpolate(struct Curve *curve, s32 value) ) 的 "精度" 與 "偏差".

(1) 精度(分辨率) :
(1.1) interpolate() 函式

  1. 傳回值: "return PCT_TO_RANGE(curve->points[num_points-1]);"
  2. 範圍: CHAN_MIN_VALUE~CHAN_MAX_VALUE 即 -10000 ~ +10000
複製代碼
PCT_TO_RANGE() 的功能為 放大 100倍,
因此 傳回值為 : -10000, -10100, -10200, -10300 ... +9800, +9900, +10000.
相當於只有 200個刻度值 !!

(2) 偏差 :
(2.1) interpolate() 函式

  1. s32 step = 2 * 10000 / (num_points - 1) ;
  2. s32 pos1 = PCT_TO_RANGE(x / 100);
  3. s32 pos2 = PCT_TO_RANGE((x + step) / 100);
複製代碼
用step作為分隔每個區間的大小.
例如: 7點直線 則分成6個區間, 11點直線 則分成10個區間, 即(num_points-1)個區間.
其中: 7 與13點 直線 分成 6 與 12 個區間, 會遇到 除3的因子 無法整除而捨棄小數(只取整數).
並且 pos1與pos2又被 除100再乘100, 相當於捨棄最後兩位數.

當 7 與13點直線 時, 這個step用來逐次做為區間分隔, 逐次加乘又造成 區間偏差的積累.
最後一個區間只到 +9900 (偏差100).
也因此才會在 "for迴圈之外" 有此指令 "return PCT_TO_RANGE(curve->points[num_points-1]);"



(1.2) 建議 採用 先放大 100倍 "100*curve->points[ i ]" 計算後將值傳回, 讓精度回復 (1個刻度值: -10000~+10000).

  1. ----- curves.c --- interpolate() -----
  2. s32 tmp = (value-pos1)*  100*(curve->points[i+1] - curve->points)  / (pos2-pos1) + 100*curve->points;
  3. return tmp;
複製代碼
(2.2) 建議 減少區間偏差 方式:
(2.2.1) 恢復最後兩位數. 並放棄 step , 每次都計算 pos1與pos2區間.

  1. ----- curves.c --- interpolate() -----
  2. s32 pos1 = -10000 + i * 2 * 10000 / (num_points - 1) ;
  3. s32 pos2 = -10000 + (i+1) * 2 * 10000 / (num_points - 1) ;
複製代碼
則不需要 "for迴圈之外" 的指令 "return PCT_TO_RANGE(curve->points[num_points-1]);"
(2.2.2) 另一個較簡易的方式 只 恢復最後兩位數, 仍採用step計算 pos1與pos2區間.

  1. ----- curves.c --- interpolate() -----
  2. s32 pos1 = x;
  3. s32 pos2 = x + step;
複製代碼
這樣還是會有偏差, 但
7點直線最後一個區間可到 +9998 (偏差2).
13點直線最後一個區間可到 +9992 (偏差8).
還是需要 "for迴圈之外" 的指令 "return PCT_TO_RANGE(curve->points[num_points-1]);"


[ 本帖最後由 hmjack2008 於 2013年3月5日 06:56 PM 編輯 ]
回復 按讚

使用道具 舉報

發表於 2013年3月5日 07:59 PM | 顯示全部樓層
原帖由 hmjack2008 於 2013年3月5日 06:50 PM 發表

關於 混控曲線(curves.c)中 多點直線( s16 interpolate(struct Curve *curve, s32 value) ) 的 "精度" 與 "偏差".

(1) 精度(分辨率) :
(1.1) interpolate() 函式
傳回值: "return PCT_TO_RANGE(curve->points[num_ ...
hmj比较细心,我想了一下,第一个方案虽然精度烧微好一下,但是太多的乘法还是会导致计算时间稍长而降低混控的处理性能,综合来看,最理想的方式还是第2个方案。
已经将代码按您的建议修改了,请看看是否还有其他建议
回復 按讚

使用道具 舉報

發表於 2013年3月5日 09:06 PM | 顯示全部樓層
原帖由 suvsuvsuv 於 2013年3月5日 07:59 PM 發表
hmj比较细心,我想了一下,第一个方案虽然精度烧微好一下,但是太多的乘法还是会导致计算时间稍长而降低混控的处理性能,综合来看,最理想的方式还是第2个方案。
已经将代码按您的建议修改了,请看看是否还有其他建议 ...


我的建議是 (1.2)精度 & (2.2.2)偏差 一起改,
改後相較於原始的 不會增加計算, 反而  "減少2次除100" 及 "減少1次乘100" !!
curves.zip (2.85 KB, 下載次數: 96)
另, 建議:
(1)num_points 算式表達

  1. u8 CURVE_NumPoints(struct Curve *curve)
  2. ...
  3. return (curve->type + 1 - CURVE_3POINT) * 2 + 1;
複製代碼
改為 return (curve->type - CURVE_3POINT) * 2 + 3;
功能是一樣的, 但少了一次加法, 並且讓 curves.c 程序中 "num_points = (curve->type - CURVE_3POINT) * 2 + 3;" 的算式表達一致 !!

(2) 用CHAN_MAX_VALUE與CHAN_MIN_VALUE表達,增加程式可讀性.

  1. s16 interpolate(struct Curve *curve, s32 value)
  2.    s32 step = (CHAN_MAX_VALUE-CHAN_MIN_VALUE) / (num_points - 1) ;
  3. ...
  4.    s32 x = CHAN_MIN_VALUE + i * step;
複製代碼


[ 本帖最後由 hmjack2008 於 2013年3月5日 09:32 PM 編輯 ]
回復 按讚

使用道具 舉報

發表於 2013年3月5日 11:43 PM | 顯示全部樓層
留意了,不要過猶不及.

搖控器穩定是第一考慮.太複雜沒好處. 11点的曲綫依一般看法巳足夠了手控精度的需求了..弄不好就算在一万份之一的机会中掛机就得不償失...
回復 按讚

使用道具 舉報

發表於 2013年3月6日 10:06 AM | 顯示全部樓層
原帖由 cmpang 於 2013年3月5日 11:43 PM 發表
留意了,不要過猶不及.

搖控器穩定是第一考慮.太複雜沒好處. 11点的曲綫依一般看法巳足夠了手控精度的需求了..弄不好就算在一万份之一的机会中掛机就得不償失... ...


穩定中求發展 !
穩定 永遠是第一順位 !  認同 穩定 +1
回復 按讚

使用道具 舉報

發表於 2013年3月6日 10:19 AM | 顯示全部樓層
完全同意前面兩位的說法~~

功能太多太複雜,反而不一定好
遙控器還是要回歸穩定,為第一優先
回復 按讚

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 申請

本版積分規則

世界各國訪RCTW統計

手機版|台灣遙控模型-RCTW

GMT+8, 2024年12月14日 03:03 AM

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回復 返回頂部 返回列表