# 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 |


### 分析電池壓降
#### 3300:
:::spoiler
可用靜推資料:
> 1203145946
> 1203152250

壓降/電流:4.939/53.528
風速20-1:

峰值壓降:5.07 :arrow_right: 峰值電流:54.948 :arrow_right: 峰值功率:1041.8 W
推力:2.9099;power/thrust = 358.0 (W/kg)
:::
#### 10000:
:::spoiler
可用靜推資料:
> 1203132838
> 1124130928

壓降/電流:5.06/49.674
20-2

峰值壓降:5.69 :arrow_right: 峰值電流:55.859 :arrow_right: 峰值功率:1004.7 W
推力:2.9091;power/thrust = 345.4 (W/kg)
15-1

峰值壓降:6.145 :arrow_right: 峰值電流:60.325 :arrow_right: 峰值功率:1119.1 W
推力:3.3865;power/thrust = 330.5 (W/kg)
10-2

峰值壓降:5.79 :arrow_right: 峰值電流:56.840 :arrow_right: 峰值功率:1049.1 W
推力:3.9892;power/thrust = 263.0 (W/kg)
:::
#### 4200
:::spoiler

壓降/電流:3.80/55.131
10-1

峰值壓降:4.80 :arrow_right: 峰值電流:69.639 :arrow_right: 峰值功率:1378 W
推力:4.5493;power/thrust = 302.9 (W/kg)
15-2

峰值壓降: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)