# 1231動推 [TOC] ### 目的 上次動推過程混亂、不夠嚴謹,這次計畫好後再次進行測試 ### 儀器設備 * 推測平台本體與校正裝置 * AT3530馬達 * 14×7槳 * 電變:hobbywing 100A * pixhawk 板 * 電流電壓調整裝置(電阻) * 電流測量連接器 * 安裝推測軟體的筆電 * 6s 3300mAh、10000mAh、4200mAh 滿電電池 * 電池延長線 * 電路板接電腦的線 * c型夾 * 100A保險絲 * 小木塊(用來夾C型夾) ### 步驟 #### 木工廠預備 1. 確認要測的電池電量滿電 2. 將pixhawk接上電腦和電阻,使用QGround校正電壓和電流 3. 校正好推測平台 4. 使用舊電池簡單測試過一遍 #### 實驗室實驗 1. 裝置固定好 3. 推測平台、PIXHAWK接上電腦 4. 開啟QGROUND 5. 確認連接上PIXHAWK 6. 淨空,電腦操作員與預備拔電池人員就位 7. 馬達接上電源 8. 確認QGROUND有無報錯(先前實驗已關閉GPS和磁力計,compass報錯不用管) 9. 確認推測平台是否當掉(數值是否持續為0沒有變化) 10. QGROUND 切為 ARMED 11. 切到控制馬達頁面 12. 開始記錄數值(確認正在連續紀錄) 13. 手動拉油門到預備油門(50%,風速20m/s時為60%) 14. 馬達穩定後開啟風洞 15. 等待空速計穩定後再將馬達依設定拉至100%再拉至預備油門) > [name=20林佳佑]要不要統一等待15秒方便資料分析 16. 馬達穩定後關閉風洞 17. 將馬達拉至0% 18. 確認馬達停止運作 19. 結束推測平台連續紀錄 20. QGROUND 切為 DISARMED 21. 拔電池 22. 拔電路板的線 23. 資料分析(每次做完一組數據紀錄時間、測試項目和下載log檔) ### 設定 風洞風速 : 1. 10 m/s 2. 15 m/s 3. 20 m/s 油門設定 : :::info 油門設定: * 油門 秒數 * 預備油門 (開啟風洞) * 等待空速計穩定 * 70% 3sec * 80% 3sec * 90% 3sec * 100% 10sec * 90% 3sec * 80% 3sec * 70% 3sec * 預備油門 3sec * 關閉風洞 * 0% ::: * 預計實驗時間 46 秒 (假設等待空速計穩定花費15秒) ### 過程 * 風速10-1 * 時間: 15:57 * 風速: 10 * 電池(電量變化): 4200(98%~83% (85%)) * 測試過程描述: * 風速15-1 * 時間: 16:05 * 風速: 15 * 電池(電量變化): 10000(99%~89%) * 測試過程描述: * 風速20 * 時間: 16:14 * 風速: 20 * 電池(電量變化):3300(99%~86%) * 測試過程描述:失敗 * 風速20-1 * 時間: 16:21 * 風速: 20 * 電池(電量變化):3300(85%~55% (62%)) * 測試過程描述: * 風速10-2 * 時間: 16:26 * 風速: 10 * 電池(電量變化):10000(92%~78% (82%)) * 測試過程描述: * 風速15-2 * 時間: 16:36 * 風速: 15 * 電池(電量變化):4200(85%~56% (63%)) * 測試過程描述: * 風速20-2 * 時間: 16:45 * 風速: 20 * 電池(電量變化):10000(83%~65% (69%)) * 測試過程描述: ### code :::spoiler var test = [ [1400, 3], [1250, 3], [1000, 3]]; var stabilityTolerance = 0.15; var conti=40; var maxWaitTime = 25; var count=0; var time =0.025; var settunneltime=0; var ave=1; var checkInterval=1; // Test repeat var repeat = 1; // set to 1 to run the sequence only once var ramptime=2; // ESC initialization var minVal = 1000; // ESC initialization value (us) var initDur = 4; // ESC initialization time (s) var mid=1300; var midramptime=5; var filePrefix = "CustomSequence"; ///////////////// Beginning of the script ////////////////// // ESC initialization rcb.console.print("Initializing ESC..."); rcb.output.set("esc",minVal); rcb.wait(main, initDur); // hide console debug info rcb.console.setVerbose(false); // start new log file rcb.files.newLogFile({prefix: filePrefix}); var thrust=0; var unit=0; // runs the sequence var index = -1; var total = repeat; var totalTime = 0; var steptimesum=0; //var utcTime = new Date().getTime(); var recentReadings = []; var current=0; var stabilitySamples=40; var allstartTimestamp = new Date().getTime(); var stableTimestamp=0; var fluctuation = 0; var record=function(){rcb.sensors.read(function(data){ data.time.displayValue = totalTime; rcb.files.newLogEntry(data); rcb.console.print("sample saved"); }, ave); }; function main(){ function callback(result){ current = result.current.displayValue; unit = result.current.displayUnit; rcb.console.print("current: " + current + " " + unit); //recentReadings.push(current); //rcb.console.print("diff" + recentReadings[stabilitySamples-1]-recentReadings[0] ); if(Math.abs(current)>=stabilityTolerance){ count+=1; }else{ count=0; } // 如果陣列太長,移除最舊的數據 (保持滑動視窗大小) if ( count >= conti) { rcb.console.print(">>> 偵測到推力穩定!(波動 < " + stabilityTolerance + ")"); stableTimestamp = new Date().getTime(); sequence(); return; } else { // 安全機制:檢查是否超時 if( totalTime> maxWaitTime) { rcb.console.print("警告:等待穩定超時"); rcb.output.ramp("esc",mid, minVal, midramptime ); rcb.wait(function() {rcb.endScript(); }, midramptime); return; } else { // 還沒穩定,等待一段時間後再次檢查 (迴圈) totalTime=(new Date().getTime() - allstartTimestamp)/1000; record(); rcb.wait(checkStabilityLoop,time); } } } rcb.output.ramp("esc",minVal, mid, midramptime ); rcb.console.print("油門" +mid+ "%"); // 呼叫偵測函數 rcb.wait( checkStabilityLoop,midramptime+settunneltime ); function checkStabilityLoop() { //rcb.console.print("123"); // 讀取感應器數據 rcb.sensors.read(callback,1); } function sequence(){ if(index > -1){ if(index === test.length){ // end of sequence index = -1; sequence(); }else{ var elapsed=0; var stepduration = test[index][1]; // get step info var pwm = test[index][0]; var expwm=minVal; //test[index-1][0]; if(index===0){ rcb.output.ramp("esc", mid, pwm, ramptime ); }else{ expwm=test[index-1][0]; rcb.output.ramp("esc", expwm, pwm, ramptime ); } index ++; rcb.console.print("set esc time" +totalTime + " , " + pwm + " for " + stepduration + "s..."); // set the output // var recordStep=function (){ if(elapsed >= stepduration+ramptime){ //steptimesum+=stepduration; //totalTime=steptimesum; sequence(); }else{ var remaining = stepduration - elapsed; //var waitTime = Math.min(time, remaining); var startTimestamp = new Date().getTime(); // take a sample record(); var endTimestamp = new Date().getTime(); var functiontime=endTimestamp-startTimestamp; elapsed += time; totalTime +=time; //rcb.console.print("sample time" +totalTime+" function time"+functiontime); if(time < (functiontime/1000)*1.1){ rcb.output.ramp("esc", pwm, minVal, 5 ); rcb.console.print("sample time < function time, sample time has to bigger than " +functiontime/1000+ " ms" ); rcb.wait(5); rcb.output.set("esc",minVal); rcb.endScript(); } rcb.wait(recordStep,Math.max(0,time-functiontime/1000)); } }; recordStep(); } }else{ if(repeat > 0){ rcb.console.print("Sequence " + (total-repeat+1) + " of " + total); repeat--; index++; sequence(); }else{ var allendTimestamp = new Date().getTime(); rcb.console.print("real duration:" +(allendTimestamp-allstartTimestamp)/1000); rcb.console.print("end time" +totalTime); rcb.endScript(); } } }} ::: :::spoiler //, [1500, 7], [1700, 5], [1850, 5], [1950, 5], [2000,7], [1750, 5], [1500, 5], //[[1150, 3], [1250, 5], [1500, 5], [1750, 5], [1850, 3], [1950, 3], [2000,5], [1750, 3], [1500, 3], [1250, 3], [1000, 3]]; var test = [ [1400, 3], [1250, 3], [1000, 3]]; var stabilityTolerance = 1; var maxWaitTime = 25; var count=0; var time =0.025; var settunneltime=0; var ave=1; var checkInterval=1; // Test repeat var repeat = 1; // set to 1 to run the sequence only once var ramptime=2; // ESC initialization var minVal = 1000; // ESC initialization value (us) var initDur = 4; // ESC initialization time (s) var mid=1300; var midramptime=5; var filePrefix = "CustomSequence"; ///////////////// Beginning of the script ////////////////// // ESC initialization rcb.console.print("Initializing ESC..."); rcb.output.set("esc",minVal); rcb.wait(main, initDur); // hide console debug info rcb.console.setVerbose(false); // start new log file rcb.files.newLogFile({prefix: filePrefix}); var thrust=0; var unit=0; // runs the sequence var index = -1; var total = repeat; var totalTime = 0; var steptimesum=0; //var utcTime = new Date().getTime(); var recentReadings = []; var stabilitySamples=10; var allstartTimestamp = new Date().getTime(); var stableTimestamp=0; var fluctuation = 0; function callback(result){ thrust = result.thrust.displayValue; unit = result.thrust.displayUnit; rcb.console.print("Thrust: " + thrust.toPrecision(3) + " " + unit); } function main(){ var record=function(){rcb.sensors.read(function(data){ data.time.displayValue = totalTime; rcb.files.newLogEntry(data); //rcb.console.print("sample saved"); }, ave); }; rcb.output.ramp("esc",minVal, mid, midramptime ); rcb.console.print("油門" +mid+ "% - 開始偵測推力穩定度..."); // 呼叫偵測函數 rcb.wait( checkStabilityLoop ,midramptime+settunneltime ); function checkStabilityLoop() { rcb.console.print("123"); // 讀取感應器數據 rcb.sensors.read(callback,1); rcb.console.print(thrust.toPrecision(3)); if(thrust.toPrecision(3)>stabilityTolerance){ count+=1; }else{ count=0; } //recentReadings.push(thrust.toPrecision(3)); // 如果陣列太長,移除最舊的數據 (保持滑動視窗大小) if ( count >= 10) { rcb.console.print(">>> 偵測到推力穩定!(波動 < " + stabilityTolerance + ")"); stableTimestamp = new Date().getTime(); sequence(); } else { // 安全機制:檢查是否超時 if( totalTime> maxWaitTime) { rcb.console.print("警告:等待穩定超時"); rcb.output.ramp("esc",mid, minVal, midramptime ); rcb.wait(function() {rcb.endScript(); }, midramptime); return; } else { // 還沒穩定,等待一段時間後再次檢查 (迴圈) totalTime=(new Date().getTime() - allstartTimestamp)/1000; record(); rcb.wait(checkStabilityLoop, checkInterval); } } } } function sequence(){ if(index > -1){ if(index === test.length){ // end of sequence index = -1; sequence(); }else{ var elapsed=0; var stepduration = test[index][1]; // get step info var pwm = test[index][0]; var expwm=minVal; //test[index-1][0]; if(index===0){ rcb.output.ramp("esc", mid, pwm, ramptime ); }else{ expwm=test[index-1][0]; rcb.output.ramp("esc", expwm, pwm, ramptime ); } index ++; rcb.console.print("set esc time" +totalTime + " , " + pwm + " for " + stepduration + "s..."); // set the output // var recordStep=function (){ if(elapsed >= stepduration+ramptime){ //steptimesum+=stepduration; //totalTime=steptimesum; sequence(); }else{ var remaining = stepduration - elapsed; //var waitTime = Math.min(time, remaining); var startTimestamp = new Date().getTime(); // take a sample record(); var endTimestamp = new Date().getTime(); var functiontime=endTimestamp-startTimestamp; elapsed += time; totalTime +=time; //rcb.console.print("sample time" +totalTime+" function time"+functiontime); if(time < (functiontime/1000)*1.1){ rcb.output.ramp("esc", pwm, minVal, 5 ); rcb.console.print("sample time < function time, sample time has to bigger than " +functiontime/1000+ " ms" ); rcb.wait(5); rcb.output.set("esc",minVal); rcb.endScript(); } rcb.wait(recordStep,Math.max(0,time-functiontime/1000)); } }; recordStep(); } }else{ if(repeat > 0){ rcb.console.print("Sequence " + (total-repeat+1) + " of " + total); repeat--; index++; sequence(); }else{ var allendTimestamp = new Date().getTime(); rcb.console.print("real duration:" +(allendTimestamp-allstartTimestamp)/1000); rcb.console.print("end time" +totalTime); rcb.endScript(); } } } ::: ### 結果 完啦 1. 不知什麼原因,電流資料未被記錄,無法得知電流與功耗。 2. 對於所有測試,10000mAh推力表現皆較差,其推力不如 4200 or 3300 的新電池 3. 對於唯一一次油門到100%的狀況,其推力並未明顯增加,最大僅 2.9091 kgf(甚至比3300那顆的88%還低),比AT3530的2827g大不了多少,但沒有功耗資料無法比較其效率 |Thrust|AT3530(100%)|XM5050(88%)| |--|------|------| | 0m/s|4686|4554 | |10m/s|4175|4549 | |15m/s|3712|3782 | |20m/s|2827|2910 | |製造商|4805|4791 | ![image](https://hackmd.io/_uploads/S19uVc8EZl.png) ![image](https://hackmd.io/_uploads/SJuyB5UVbl.png) ### 分析電池壓降 #### 3300: :::spoiler 可用靜推資料: > 1203145946 > 1203152250 ![image](https://hackmd.io/_uploads/ryync1KEbx.png) 壓降/電流:4.939/53.528 風速20-1: ![image](https://hackmd.io/_uploads/HJwmskYEWx.png) 峰值壓降:5.07 :arrow_right: 峰值電流:54.948 :arrow_right: 峰值功率:1041.8 W 推力:2.9099;power/thrust = 358.0 (W/kg) ::: #### 10000: :::spoiler 可用靜推資料: > 1203132838 > 1124130928 ![image](https://hackmd.io/_uploads/BJSDAJtVZg.png) 壓降/電流:5.06/49.674 20-2 ![image](https://hackmd.io/_uploads/r1sFAJKN-e.png) 峰值壓降:5.69 :arrow_right: 峰值電流:55.859 :arrow_right: 峰值功率:1004.7 W 推力:2.9091;power/thrust = 345.4 (W/kg) 15-1 ![image](https://hackmd.io/_uploads/SJT_1gt4-l.png) 峰值壓降:6.145 :arrow_right: 峰值電流:60.325 :arrow_right: 峰值功率:1119.1 W 推力:3.3865;power/thrust = 330.5 (W/kg) 10-2 ![image](https://hackmd.io/_uploads/rksGeeF4be.png) 峰值壓降:5.79 :arrow_right: 峰值電流:56.840 :arrow_right: 峰值功率:1049.1 W 推力:3.9892;power/thrust = 263.0 (W/kg) ::: #### 4200 :::spoiler ![image](https://hackmd.io/_uploads/SJLnRGKEWl.png) 壓降/電流:3.80/55.131 10-1 ![image](https://hackmd.io/_uploads/ryX1xXKNbe.png) 峰值壓降:4.80 :arrow_right: 峰值電流:69.639 :arrow_right: 峰值功率:1378 W 推力:4.5493;power/thrust = 302.9 (W/kg) 15-2 ![image](https://hackmd.io/_uploads/BkxSe7F4-e.png) 峰值壓降:4.77 :arrow_right: 峰值電流:69.204 :arrow_right: 峰值功率:1333.4 W 推力:3.7817;power/thrust = 352.56 (W/kg) ::: --- |Power/Thrust|AT3530(100%)|XM5050(88%)| |--|------|------| | 0m/s|233.7|246.1 | |10m/s|273.6|263.0 | |15m/s|301.7|330.5 | |20m/s|359.4|358.0 | |製造商|262.9|258.5 | :warning: :warning: :warning: :warning: > XM5050估計值較為樂觀(最悲觀為上述*1.08)