disturbance observer

Dependencies:   mbed MATSUbed USBDevice

Committer:
Mtshadow
Date:
Mon Dec 27 06:56:54 2021 +0000
Revision:
10:21ea2a241025
Parent:
9:66b71a3f4ffb
success detect nonmagnet at horizon

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Mtshadow 7:49afd76d633d 1 /*
Mtshadow 7:49afd76d633d 2 外乱推定→走行面の検出を行う
Mtshadow 7:49afd76d633d 3 やること
Mtshadow 7:49afd76d633d 4 ・100Hzで離散化したプラントの逆モデルの実装
Mtshadow 7:49afd76d633d 5 ・推定外乱から磁気吸着力変化の検出
Mtshadow 7:49afd76d633d 6 リビジョン
Mtshadow 7:49afd76d633d 7 mbed 127:25aea2a3f4e3
Mtshadow 7:49afd76d633d 8 */
Mtshadow 7:49afd76d633d 9
hardtail 0:d696cd1aea56 10 #include "mbed.h"
hardtail 1:68364bcdd696 11 #include "USBSerial.h"
Mtshadow 7:49afd76d633d 12 #include "math.h"
Mtshadow 7:49afd76d633d 13
Mtshadow 7:49afd76d633d 14 // Board settings
Mtshadow 7:49afd76d633d 15 #define LED1 P0_29
Mtshadow 7:49afd76d633d 16 #define LED2 P0_28
Mtshadow 7:49afd76d633d 17 #define LED3 P0_27
Mtshadow 7:49afd76d633d 18 #define LED4 P0_26
Mtshadow 7:49afd76d633d 19
Mtshadow 7:49afd76d633d 20 // CANopen settings
Mtshadow 7:49afd76d633d 21 #define RxPDO1 0x220
Mtshadow 7:49afd76d633d 22 #define RxPDO2 0x320
Mtshadow 7:49afd76d633d 23 #define RxPDO3 0x420
Mtshadow 7:49afd76d633d 24 #define Halt 1
Mtshadow 7:49afd76d633d 25 #define QuickStop 2
Mtshadow 7:49afd76d633d 26 #define ShutDown 3
Mtshadow 7:49afd76d633d 27 #define SYNC_Enable 0
Mtshadow 7:49afd76d633d 28 #define SYNC_Disable 1
Mtshadow 7:49afd76d633d 29 #define node 2
Mtshadow 7:49afd76d633d 30
Mtshadow 7:49afd76d633d 31 // Disturbance Observer settings
Mtshadow 9:66b71a3f4ffb 32 #define tfA 193.5
Mtshadow 9:66b71a3f4ffb 33 #define tfB 0.7529
Mtshadow 9:66b71a3f4ffb 34 #define tfC 1
Mtshadow 9:66b71a3f4ffb 35 #define tfD 0.5219
Mtshadow 7:49afd76d633d 36
Mtshadow 7:49afd76d633d 37 // 定数
Mtshadow 7:49afd76d633d 38 #define Kv 0.092421
Mtshadow 7:49afd76d633d 39 #define Km 0.0092
Mtshadow 7:49afd76d633d 40 #define samplimgrate 0.01
Mtshadow 10:21ea2a241025 41 #define startdetect 20.0
Mtshadow 10:21ea2a241025 42 #define enddetect 200.0
Mtshadow 7:49afd76d633d 43 #define Kn 116
Mtshadow 7:49afd76d633d 44
Mtshadow 7:49afd76d633d 45 USBSerial pc; //PCとのシリアル通信
Mtshadow 7:49afd76d633d 46 char Serialdata;
Mtshadow 7:49afd76d633d 47 CANMessage canmsgTx; //送信データ処理用
Mtshadow 8:2ae2483893f0 48 CANMessage canmsgRx; //受信データ処理用
Mtshadow 7:49afd76d633d 49 Ticker flipper; //汎用タイマー
hardtail 0:d696cd1aea56 50
Mtshadow 7:49afd76d633d 51 DigitalOut ENsig(P0_10);
Mtshadow 7:49afd76d633d 52 BusOut myled(LED1, LED2, LED3,LED4);
Mtshadow 7:49afd76d633d 53 CAN canPort(P0_13, P0_18); //CAN name(PinName rd, PinName td)
hardtail 0:d696cd1aea56 54
Mtshadow 7:49afd76d633d 55 //グローバル変数
Mtshadow 7:49afd76d633d 56 //char Serialdata; //シリアル受信データ
Mtshadow 8:2ae2483893f0 57 float Current_demand=0, Velocity_actual=0; //電流入力値,速度出力値
Mtshadow 7:49afd76d633d 58 float Torque_estimate_tf=0; //トルク入力推定値
Mtshadow 7:49afd76d633d 59 float Distterbance_estimate_tf=0; //外乱トルク推定値
Mtshadow 7:49afd76d633d 60 float Velocity_estimate_z1; //推定時保持データ
Mtshadow 7:49afd76d633d 61 float Velocity_estimate=0; //推定時現在速度
Mtshadow 8:2ae2483893f0 62 float Current_estimate=0; //推定時現在電流
Mtshadow 8:2ae2483893f0 63 int Velocity_Trend=0, Current_Trend=0; //除去するトレンド
Mtshadow 7:49afd76d633d 64 float distance = 0; //走行距離[mm]
Mtshadow 7:49afd76d633d 65 float Velocity_meter; // 走行速度[mm/s]
Mtshadow 7:49afd76d633d 66 bool run_eternal = false;
Mtshadow 7:49afd76d633d 67 int check = 0;
Mtshadow 9:66b71a3f4ffb 68 bool decimal = false;
Mtshadow 7:49afd76d633d 69
Mtshadow 10:21ea2a241025 70 // 判別用
Mtshadow 10:21ea2a241025 71 float Distterbance_estimate_tf_abs = 0; // 外乱推定値nの絶対値
Mtshadow 10:21ea2a241025 72 float Dist_error = 0; // 低下割合
Mtshadow 10:21ea2a241025 73 float baseDist = 0; // 判別基準値
Mtshadow 10:21ea2a241025 74 int cnt_ditect = 0; // しきい値を超えてからのカウント
Mtshadow 10:21ea2a241025 75 int cnt_find = 0; // 非磁性面の検出からのカウント
Mtshadow 10:21ea2a241025 76 int findnonmagnet =0; // 非磁性面検出信号
Mtshadow 10:21ea2a241025 77 int cnt_run = 0; // 走行時間カウント
Mtshadow 10:21ea2a241025 78
Mtshadow 7:49afd76d633d 79 //プロトタイプ宣言
Mtshadow 7:49afd76d633d 80 // CANopen関連
Mtshadow 7:49afd76d633d 81 void NMTPreOpn(void); //NMT PreOperationalへ移行
Mtshadow 7:49afd76d633d 82 void NMTOpn(void); //NMT Operationalへ移行
Mtshadow 7:49afd76d633d 83 void CtrlWord(int); //RxPDO1
Mtshadow 7:49afd76d633d 84 void ModesOfOperation(void);//RxPDO2
Mtshadow 7:49afd76d633d 85 void TgtVelCtrl(int); //RxPDO3
Mtshadow 7:49afd76d633d 86 void sendCtrlRS(int); //SDO Reset
Mtshadow 7:49afd76d633d 87 void sendCtrlSD(int); //SDO Shutdown
Mtshadow 7:49afd76d633d 88 void sendCtrlEN(int); //SDO Enable
Mtshadow 7:49afd76d633d 89 //-------------------その他--------------------
Mtshadow 7:49afd76d633d 90 void init(void); //マイコン初期化
Mtshadow 7:49afd76d633d 91 void CANinit(void); //CANノード初期化
Mtshadow 7:49afd76d633d 92 void SerialRX(void); //Serial受信処理
Mtshadow 7:49afd76d633d 93 void flip(void); //タイマー割り込み
Mtshadow 7:49afd76d633d 94 void printPlantData(void); //速度指令値、出力値をPCに表示
Mtshadow 7:49afd76d633d 95 void EstimateDisterbance(void);//指令値を推定
Mtshadow 7:49afd76d633d 96 void detectNonmagnet(void);
hardtail 0:d696cd1aea56 97
Mtshadow 7:49afd76d633d 98 int main(){
Mtshadow 7:49afd76d633d 99 init();
Mtshadow 7:49afd76d633d 100 myled = 0b0101;
Mtshadow 7:49afd76d633d 101 while(1){
Mtshadow 7:49afd76d633d 102 if(Serialdata == 's'){
Mtshadow 7:49afd76d633d 103 run_eternal = false;
Mtshadow 7:49afd76d633d 104 break;
Mtshadow 7:49afd76d633d 105 }else if(Serialdata == 'e'){
Mtshadow 7:49afd76d633d 106 run_eternal = true;
Mtshadow 7:49afd76d633d 107 break;
Mtshadow 7:49afd76d633d 108 }
Mtshadow 7:49afd76d633d 109 myled=~myled;
Mtshadow 7:49afd76d633d 110 wait(1);
Mtshadow 7:49afd76d633d 111 }
Mtshadow 7:49afd76d633d 112 Serialdata = 0;
Mtshadow 7:49afd76d633d 113 //node初期化
Mtshadow 7:49afd76d633d 114 CANinit();
Mtshadow 7:49afd76d633d 115 int count=0;
Mtshadow 7:49afd76d633d 116 myled=0;
Mtshadow 7:49afd76d633d 117 while(1){
Mtshadow 7:49afd76d633d 118 if(!ENsig){
Mtshadow 7:49afd76d633d 119 myled=count;
Mtshadow 7:49afd76d633d 120 count++;
Mtshadow 7:49afd76d633d 121 }
Mtshadow 7:49afd76d633d 122 else{
Mtshadow 7:49afd76d633d 123 myled =~ myled;
Mtshadow 7:49afd76d633d 124 }
Mtshadow 7:49afd76d633d 125 wait(0.5);
Mtshadow 7:49afd76d633d 126 }
Mtshadow 7:49afd76d633d 127 }
Mtshadow 7:49afd76d633d 128 //マイコン初期化
Mtshadow 7:49afd76d633d 129 void init(void){
Mtshadow 7:49afd76d633d 130 //I/O設定
Mtshadow 7:49afd76d633d 131 ENsig=SYNC_Disable;
Mtshadow 7:49afd76d633d 132 //CAN設定
Mtshadow 7:49afd76d633d 133 canPort.frequency(1000000); //Bit Rate:1Mbps
Mtshadow 7:49afd76d633d 134 //割り込み設定
Mtshadow 7:49afd76d633d 135 flipper.attach_us(&flip,5000); //汎用タイマー割り込み周期:5ms(5*10^3 us)
Mtshadow 7:49afd76d633d 136 pc.attach(SerialRX); //Serial受信割り込み開始
Mtshadow 7:49afd76d633d 137 }
Mtshadow 7:49afd76d633d 138 //can node初期化
Mtshadow 7:49afd76d633d 139 void CANinit(void){
Mtshadow 7:49afd76d633d 140 //SDOコマンドで各nodeをリセット
Mtshadow 7:49afd76d633d 141 for(int nodeID=1;nodeID <= node;nodeID++){
Mtshadow 7:49afd76d633d 142 sendCtrlRS(nodeID);
Mtshadow 7:49afd76d633d 143 sendCtrlSD(nodeID);
Mtshadow 7:49afd76d633d 144 sendCtrlEN(nodeID);
Mtshadow 7:49afd76d633d 145 }
Mtshadow 7:49afd76d633d 146 //NMTコマンドで全nodeをオペレーショナルに
Mtshadow 7:49afd76d633d 147 NMTPreOpn();
Mtshadow 7:49afd76d633d 148 NMTOpn();
Mtshadow 7:49afd76d633d 149 }
Mtshadow 7:49afd76d633d 150 //Serial受信割り込み処理
Mtshadow 7:49afd76d633d 151 void SerialRX(void){
Mtshadow 7:49afd76d633d 152 Serialdata = pc.getc();
Mtshadow 7:49afd76d633d 153 //-------------送信コマンドを選択--------------
Mtshadow 9:66b71a3f4ffb 154 if (decimal) {
Mtshadow 9:66b71a3f4ffb 155 if(Serialdata == '1'){
Mtshadow 9:66b71a3f4ffb 156 Velocity_Trend = 100;
Mtshadow 9:66b71a3f4ffb 157 TgtVelCtrl(Velocity_Trend);
Mtshadow 9:66b71a3f4ffb 158 ENsig = SYNC_Enable;
Mtshadow 9:66b71a3f4ffb 159 Serialdata = 0;
Mtshadow 9:66b71a3f4ffb 160 }
Mtshadow 9:66b71a3f4ffb 161 else if(Serialdata == '2'){
Mtshadow 9:66b71a3f4ffb 162 Velocity_Trend = 200;
Mtshadow 9:66b71a3f4ffb 163 TgtVelCtrl(Velocity_Trend);
Mtshadow 9:66b71a3f4ffb 164 ENsig = SYNC_Enable;
Mtshadow 9:66b71a3f4ffb 165 Serialdata = 0;
Mtshadow 9:66b71a3f4ffb 166 }
Mtshadow 9:66b71a3f4ffb 167 else if(Serialdata == '3'){
Mtshadow 9:66b71a3f4ffb 168 Velocity_Trend = 300;
Mtshadow 9:66b71a3f4ffb 169 TgtVelCtrl(Velocity_Trend);
Mtshadow 9:66b71a3f4ffb 170 ENsig = SYNC_Enable;
Mtshadow 9:66b71a3f4ffb 171 Serialdata = 0;
Mtshadow 9:66b71a3f4ffb 172 }
Mtshadow 9:66b71a3f4ffb 173 else if(Serialdata == '4'){
Mtshadow 9:66b71a3f4ffb 174 Velocity_Trend = 400;
Mtshadow 9:66b71a3f4ffb 175 TgtVelCtrl(Velocity_Trend);
Mtshadow 9:66b71a3f4ffb 176 ENsig = SYNC_Enable;
Mtshadow 9:66b71a3f4ffb 177 Serialdata = 0;
Mtshadow 9:66b71a3f4ffb 178 }
Mtshadow 9:66b71a3f4ffb 179 else if(Serialdata == '5'){
Mtshadow 9:66b71a3f4ffb 180 Velocity_Trend = 500;
Mtshadow 9:66b71a3f4ffb 181 TgtVelCtrl(Velocity_Trend);
Mtshadow 9:66b71a3f4ffb 182 ENsig = SYNC_Enable;
Mtshadow 9:66b71a3f4ffb 183 Serialdata = 0;
Mtshadow 9:66b71a3f4ffb 184 }
Mtshadow 9:66b71a3f4ffb 185 else if(Serialdata == '6'){
Mtshadow 9:66b71a3f4ffb 186 Velocity_Trend = 600;
Mtshadow 9:66b71a3f4ffb 187 TgtVelCtrl(Velocity_Trend);
Mtshadow 9:66b71a3f4ffb 188 ENsig = SYNC_Enable;
Mtshadow 9:66b71a3f4ffb 189 Serialdata = 0;
Mtshadow 9:66b71a3f4ffb 190 }
Mtshadow 9:66b71a3f4ffb 191 else if(Serialdata == '7'){
Mtshadow 9:66b71a3f4ffb 192 Velocity_Trend = 700;
Mtshadow 9:66b71a3f4ffb 193 TgtVelCtrl(Velocity_Trend);
Mtshadow 9:66b71a3f4ffb 194 ENsig = SYNC_Enable;
Mtshadow 9:66b71a3f4ffb 195 Serialdata = 0;
Mtshadow 9:66b71a3f4ffb 196 }
Mtshadow 9:66b71a3f4ffb 197 else if(Serialdata == '8'){
Mtshadow 9:66b71a3f4ffb 198 Velocity_Trend = 800;
Mtshadow 9:66b71a3f4ffb 199 TgtVelCtrl(Velocity_Trend);
Mtshadow 9:66b71a3f4ffb 200 ENsig = SYNC_Enable;
Mtshadow 9:66b71a3f4ffb 201 Serialdata = 0;
Mtshadow 9:66b71a3f4ffb 202 }
Mtshadow 9:66b71a3f4ffb 203 else if(Serialdata == '9'){
Mtshadow 9:66b71a3f4ffb 204 Velocity_Trend = 900;
Mtshadow 9:66b71a3f4ffb 205 TgtVelCtrl(Velocity_Trend);
Mtshadow 9:66b71a3f4ffb 206 ENsig = SYNC_Enable;
Mtshadow 9:66b71a3f4ffb 207 Serialdata = 0;
Mtshadow 9:66b71a3f4ffb 208 }
Mtshadow 9:66b71a3f4ffb 209 decimal = false;
Mtshadow 9:66b71a3f4ffb 210 } else {
Mtshadow 9:66b71a3f4ffb 211 if(Serialdata == '1'){
Mtshadow 9:66b71a3f4ffb 212 Velocity_Trend = 1000;
Mtshadow 9:66b71a3f4ffb 213 TgtVelCtrl(Velocity_Trend);
Mtshadow 9:66b71a3f4ffb 214 ENsig = SYNC_Enable;
Mtshadow 9:66b71a3f4ffb 215 Serialdata = 0;
Mtshadow 9:66b71a3f4ffb 216 }
Mtshadow 9:66b71a3f4ffb 217 else if(Serialdata == '2'){
Mtshadow 9:66b71a3f4ffb 218 Velocity_Trend = 2000;
Mtshadow 9:66b71a3f4ffb 219 TgtVelCtrl(Velocity_Trend);
Mtshadow 9:66b71a3f4ffb 220 ENsig = SYNC_Enable;
Mtshadow 9:66b71a3f4ffb 221 Serialdata = 0;
Mtshadow 9:66b71a3f4ffb 222 }
Mtshadow 9:66b71a3f4ffb 223 else if(Serialdata == '3'){
Mtshadow 9:66b71a3f4ffb 224 Velocity_Trend = 3000;
Mtshadow 9:66b71a3f4ffb 225 TgtVelCtrl(Velocity_Trend);
Mtshadow 9:66b71a3f4ffb 226 ENsig = SYNC_Enable;
Mtshadow 9:66b71a3f4ffb 227 Serialdata = 0;
Mtshadow 9:66b71a3f4ffb 228 }
Mtshadow 9:66b71a3f4ffb 229 else if(Serialdata == '4'){
Mtshadow 9:66b71a3f4ffb 230 Velocity_Trend = 4000;
Mtshadow 9:66b71a3f4ffb 231 TgtVelCtrl(Velocity_Trend);
Mtshadow 9:66b71a3f4ffb 232 ENsig = SYNC_Enable;
Mtshadow 9:66b71a3f4ffb 233 Serialdata = 0;
Mtshadow 9:66b71a3f4ffb 234 }
Mtshadow 9:66b71a3f4ffb 235 }
Mtshadow 9:66b71a3f4ffb 236
Mtshadow 7:49afd76d633d 237 if(Serialdata == 'q'){
Mtshadow 7:49afd76d633d 238 //Haltコマンド送信
Mtshadow 7:49afd76d633d 239 ENsig = SYNC_Disable;
Mtshadow 7:49afd76d633d 240 CtrlWord(QuickStop);
Mtshadow 7:49afd76d633d 241 Serialdata = 0;
Mtshadow 7:49afd76d633d 242 }
Mtshadow 9:66b71a3f4ffb 243 else if(Serialdata == '0'){
Mtshadow 9:66b71a3f4ffb 244 decimal = true;
Mtshadow 9:66b71a3f4ffb 245 ENsig = SYNC_Disable;
Mtshadow 7:49afd76d633d 246 Serialdata = 0;
Mtshadow 7:49afd76d633d 247 }
Mtshadow 7:49afd76d633d 248 else if(Serialdata == 'h'){
Mtshadow 7:49afd76d633d 249 //Haltコマンド送信
Mtshadow 7:49afd76d633d 250 ENsig = SYNC_Disable;
Mtshadow 7:49afd76d633d 251 CtrlWord(Halt);
Mtshadow 7:49afd76d633d 252 Serialdata = 0;
Mtshadow 7:49afd76d633d 253 }
Mtshadow 7:49afd76d633d 254 else if(Serialdata == 'm'){
Mtshadow 7:49afd76d633d 255 ENsig = SYNC_Disable;
Mtshadow 7:49afd76d633d 256 ModesOfOperation();
Mtshadow 7:49afd76d633d 257 Serialdata = 0;
Mtshadow 7:49afd76d633d 258 }
hardtail 4:a6882e08058c 259
Mtshadow 7:49afd76d633d 260 }
Mtshadow 7:49afd76d633d 261 //汎用タイマー
Mtshadow 7:49afd76d633d 262 void flip(void){
Mtshadow 8:2ae2483893f0 263 if(canPort.read(canmsgRx)){
Mtshadow 7:49afd76d633d 264 cnt_run++;
Mtshadow 9:66b71a3f4ffb 265 if(canmsgRx.id == 0x4a0) printPlantData(); // 左モータの情報を表示
Mtshadow 7:49afd76d633d 266 }
Mtshadow 9:66b71a3f4ffb 267 // 走行4分後に停止
Mtshadow 9:66b71a3f4ffb 268 if (cnt_run >= 24000 && run_eternal == false) {
Mtshadow 7:49afd76d633d 269 //Haltコマンド送信
Mtshadow 7:49afd76d633d 270 ENsig = SYNC_Disable;
Mtshadow 7:49afd76d633d 271 CtrlWord(QuickStop);
Mtshadow 7:49afd76d633d 272 }
Mtshadow 7:49afd76d633d 273
Mtshadow 7:49afd76d633d 274
Mtshadow 7:49afd76d633d 275
Mtshadow 7:49afd76d633d 276 }
Mtshadow 7:49afd76d633d 277 //速度出力値、指令値の表示
Mtshadow 7:49afd76d633d 278 void printPlantData(void){
Mtshadow 8:2ae2483893f0 279 short Current_raw, Velocity_raw;
Mtshadow 8:2ae2483893f0 280
Mtshadow 8:2ae2483893f0 281 Current_raw = canmsgRx.data[1]*0x100+canmsgRx.data[0]; //指令値の取得(電流)
Mtshadow 8:2ae2483893f0 282 if (Current_raw > 10000) Current_demand = ((Current_raw - 1) ^ 0xffff) * -1;
Mtshadow 8:2ae2483893f0 283 else Current_demand = Current_raw;
Mtshadow 8:2ae2483893f0 284
Mtshadow 8:2ae2483893f0 285 //Velocity_actual = canmsgRx.data[5]*0x100+canmsgRx.data[4]; //出力値の取得(速度)
Mtshadow 8:2ae2483893f0 286 Velocity_raw = canmsgRx.data[5]*0x100+canmsgRx.data[4];
Mtshadow 9:66b71a3f4ffb 287 //if (Velocity_raw > 10000) Velocity_actual = ((Velocity_raw -1) ^ 0xffff) * -1;
Mtshadow 9:66b71a3f4ffb 288 //else Velocity_actual = Velocity_raw;
Mtshadow 9:66b71a3f4ffb 289 Velocity_actual = Velocity_raw;
Mtshadow 7:49afd76d633d 290
Mtshadow 7:49afd76d633d 291 EstimateDisterbance(); //外乱の推定
Mtshadow 7:49afd76d633d 292 detectNonmagnet(); //非磁性面の判別
Mtshadow 8:2ae2483893f0 293 pc.printf("%f,%f,%f,%f,%f,%f,%d\r\n",Current_demand,Velocity_actual,Torque_estimate_tf,Distterbance_estimate_tf,baseDist,Dist_error,findnonmagnet);
Mtshadow 9:66b71a3f4ffb 294
Mtshadow 10:21ea2a241025 295 // ロボット停止処理
Mtshadow 8:2ae2483893f0 296 if ( findnonmagnet == 1 && run_eternal == false) {
Mtshadow 8:2ae2483893f0 297 /*cnt_find++;
Mtshadow 7:49afd76d633d 298 if (cnt_find >= 200) {
Mtshadow 7:49afd76d633d 299 //Haltコマンド送信
Mtshadow 7:49afd76d633d 300 ENsig = SYNC_Disable;
Mtshadow 7:49afd76d633d 301 CtrlWord(QuickStop);
Mtshadow 8:2ae2483893f0 302 }*/
Mtshadow 10:21ea2a241025 303 ENsig = SYNC_Disable;
Mtshadow 10:21ea2a241025 304 CtrlWord(QuickStop);
Mtshadow 8:2ae2483893f0 305 }
Mtshadow 7:49afd76d633d 306 findnonmagnet = 0;
hardtail 4:a6882e08058c 307 }
hardtail 4:a6882e08058c 308
Mtshadow 7:49afd76d633d 309 void EstimateDisterbance(void){
Mtshadow 7:49afd76d633d 310 //出力値のトレンド除去
Mtshadow 8:2ae2483893f0 311 Velocity_estimate = (Velocity_actual-Velocity_Trend)*Kv;
Mtshadow 7:49afd76d633d 312 //電流値トレンドの計算
Mtshadow 8:2ae2483893f0 313 Current_Trend = int((Current_Trend + Current_demand)/2);
Mtshadow 8:2ae2483893f0 314 Current_estimate = (Current_demand-Current_Trend)*Km;
Mtshadow 7:49afd76d633d 315 /*
Mtshadow 7:49afd76d633d 316 伝達関数
Mtshadow 7:49afd76d633d 317 (tfAz - tfB)
Mtshadow 7:49afd76d633d 318 tf = ------------
Mtshadow 7:49afd76d633d 319 (tfCz - tfD)
Mtshadow 7:49afd76d633d 320 */
Mtshadow 7:49afd76d633d 321 Torque_estimate_tf = (tfA*Velocity_estimate - tfB*Velocity_estimate_z1 + tfD*Torque_estimate_tf)/tfC;
Mtshadow 7:49afd76d633d 322 Velocity_estimate_z1 = Velocity_estimate;
Mtshadow 8:2ae2483893f0 323 Distterbance_estimate_tf = Torque_estimate_tf - Current_estimate;
Mtshadow 7:49afd76d633d 324 }
Mtshadow 7:49afd76d633d 325
Mtshadow 7:49afd76d633d 326 void detectNonmagnet(void) {
Mtshadow 7:49afd76d633d 327 Velocity_meter = Velocity_actual * Kv; //回転数から速度に変換[m/s]
Mtshadow 7:49afd76d633d 328 distance += Velocity_meter * samplimgrate; //走行距離を計算
Mtshadow 7:49afd76d633d 329 Distterbance_estimate_tf_abs = fabsf(Distterbance_estimate_tf);
Mtshadow 10:21ea2a241025 330 if (distance <= enddetect && distance >= startdetect) {
Mtshadow 7:49afd76d633d 331 check = 0;
Mtshadow 7:49afd76d633d 332 //外乱推定値の最大値を確認
Mtshadow 7:49afd76d633d 333 if(Distterbance_estimate_tf_abs > baseDist) baseDist = Distterbance_estimate_tf_abs;
Mtshadow 10:21ea2a241025 334 } else if (distance > enddetect) {
Mtshadow 10:21ea2a241025 335 // 低下割合算出
Mtshadow 7:49afd76d633d 336 Dist_error = Distterbance_estimate_tf_abs / baseDist;
Mtshadow 10:21ea2a241025 337
Mtshadow 10:21ea2a241025 338 // しきい値判断
Mtshadow 10:21ea2a241025 339 if (Dist_error < 0.5) {
Mtshadow 7:49afd76d633d 340 check = 1;
Mtshadow 7:49afd76d633d 341 cnt_ditect++;
Mtshadow 10:21ea2a241025 342 // 低下時間判断
Mtshadow 10:21ea2a241025 343 if(cnt_ditect >= 50) {
Mtshadow 7:49afd76d633d 344 findnonmagnet = 1;
Tiryoh 2:f94af4a543bd 345 }
Mtshadow 7:49afd76d633d 346 } else {
Mtshadow 7:49afd76d633d 347 cnt_ditect = 0;
hardtail 0:d696cd1aea56 348 }
Mtshadow 7:49afd76d633d 349 }
Mtshadow 7:49afd76d633d 350 }
Mtshadow 7:49afd76d633d 351 //NMT
Mtshadow 7:49afd76d633d 352 void NMTPreOpn(void){
Mtshadow 7:49afd76d633d 353 //COB-ID:0 0x01-00-//-//-//-//-//-//
Mtshadow 7:49afd76d633d 354 canmsgTx.id = 0x0;
Mtshadow 7:49afd76d633d 355 canmsgTx.len = 2;
Mtshadow 7:49afd76d633d 356 canmsgTx.data[0] = 0x80;//0x01:enter NMT state "PreOperational"
Mtshadow 7:49afd76d633d 357 canmsgTx.data[1] = 0x00;//send All nodes
Mtshadow 7:49afd76d633d 358 canPort.write(canmsgTx);
Mtshadow 7:49afd76d633d 359 wait(0.2);
Mtshadow 7:49afd76d633d 360 }
Mtshadow 7:49afd76d633d 361 void NMTOpn(void){
Mtshadow 7:49afd76d633d 362 //COB-ID:0 0x01-00-//-//-//-//-//-//
Mtshadow 7:49afd76d633d 363 canmsgTx.id = 0x0;
Mtshadow 7:49afd76d633d 364 canmsgTx.len = 2;
Mtshadow 7:49afd76d633d 365 canmsgTx.data[0] = 0x01;//0x01:enter NMT state "Operational"
Mtshadow 7:49afd76d633d 366 canmsgTx.data[1] = 0x00;//send All nodes
Mtshadow 7:49afd76d633d 367 canPort.write(canmsgTx);
Mtshadow 7:49afd76d633d 368 wait(0.2);
Mtshadow 7:49afd76d633d 369 }
Mtshadow 7:49afd76d633d 370 //PDO
Mtshadow 7:49afd76d633d 371 void CtrlWord(int type){
Mtshadow 7:49afd76d633d 372 canmsgTx.id = RxPDO1;
Mtshadow 7:49afd76d633d 373 canmsgTx.len = 2; //Data Length
Mtshadow 7:49afd76d633d 374 if(type==Halt){
Mtshadow 7:49afd76d633d 375 canmsgTx.data[0] = 0x0F;//data:0x01"0F"
Mtshadow 7:49afd76d633d 376 canmsgTx.data[1] = 0x01;//data:0x"01"0F
Mtshadow 7:49afd76d633d 377 }
Mtshadow 7:49afd76d633d 378 else if(type==QuickStop){
Mtshadow 7:49afd76d633d 379 canmsgTx.data[0] = 0x0B;//data:0x00"0B"
Mtshadow 7:49afd76d633d 380 canmsgTx.data[1] = 0x00;//data:0x"00"0B
Mtshadow 7:49afd76d633d 381 }
Mtshadow 7:49afd76d633d 382 else if(type==ShutDown){
Mtshadow 7:49afd76d633d 383 canmsgTx.data[0] = 0x06;//data:0x00"06"
Mtshadow 7:49afd76d633d 384 canmsgTx.data[1] = 0x00;//data:0x"00"06
hardtail 0:d696cd1aea56 385 }
Mtshadow 7:49afd76d633d 386 canPort.write(canmsgTx);//CANでデータ送信
Tiryoh 2:f94af4a543bd 387 }
Mtshadow 7:49afd76d633d 388 void ModesOfOperation(void){
Mtshadow 7:49afd76d633d 389 canmsgTx.id = RxPDO2;
Mtshadow 7:49afd76d633d 390 canmsgTx.len = 1; //Data Length
Mtshadow 7:49afd76d633d 391 canmsgTx.data[0] = 0x03;//data:0x03 = "Profile Velocity Mode"
Mtshadow 7:49afd76d633d 392 canPort.write(canmsgTx);//CANでデータ送信
Mtshadow 7:49afd76d633d 393 }
Mtshadow 7:49afd76d633d 394 void TgtVelCtrl(int rpm){
Mtshadow 7:49afd76d633d 395 //pc.printf("%drpm|0x%08x\r\n",rpm,rpm);
Mtshadow 7:49afd76d633d 396 canmsgTx.id = RxPDO3;
Mtshadow 7:49afd76d633d 397 canmsgTx.len = 6; //Data Length
Mtshadow 7:49afd76d633d 398 //Target Velocity
Mtshadow 8:2ae2483893f0 399 if (rpm > 0) {
Mtshadow 8:2ae2483893f0 400 for(char cnt=0;cnt<4;cnt++){
Mtshadow 8:2ae2483893f0 401 canmsgTx.data[cnt] = rpm % 256;
Mtshadow 8:2ae2483893f0 402 rpm = rpm / 256;
Mtshadow 8:2ae2483893f0 403 }
Mtshadow 8:2ae2483893f0 404 } else {
Mtshadow 8:2ae2483893f0 405 canmsgTx.data[0] = 0x17;
Mtshadow 8:2ae2483893f0 406 canmsgTx.data[1] = 0xFC;
Mtshadow 8:2ae2483893f0 407 canmsgTx.data[2] = 0xFF;
Mtshadow 8:2ae2483893f0 408 canmsgTx.data[3] = 0xFF;
Mtshadow 8:2ae2483893f0 409 /*
Mtshadow 8:2ae2483893f0 410 rpm = (rpm ^ 0xffffffff) + 1;
Mtshadow 8:2ae2483893f0 411 //printf("%x",rpm);
Mtshadow 8:2ae2483893f0 412 for(char cnt=0;cnt<4;cnt++){
Mtshadow 8:2ae2483893f0 413 canmsgTx.data[cnt] = rpm & 0x000000FF;
Mtshadow 8:2ae2483893f0 414 //printf("%x",rpm);
Mtshadow 8:2ae2483893f0 415 rpm = rpm >> 2;
Mtshadow 8:2ae2483893f0 416 }
Mtshadow 8:2ae2483893f0 417 */
Mtshadow 7:49afd76d633d 418 }
Mtshadow 7:49afd76d633d 419 //CtrlWord Enable
Mtshadow 7:49afd76d633d 420 canmsgTx.data[4] = 0x0F;//data:0x00"0F"
Mtshadow 7:49afd76d633d 421 canmsgTx.data[5] = 0x00;//data:0x"00"0F
Mtshadow 7:49afd76d633d 422 canPort.write(canmsgTx);//CANでデータ送信
Mtshadow 7:49afd76d633d 423 }
Mtshadow 7:49afd76d633d 424 //SDO
Mtshadow 7:49afd76d633d 425 void sendCtrlRS(int nodeID){
Mtshadow 7:49afd76d633d 426 canmsgTx.id = 0x600+nodeID;
Mtshadow 7:49afd76d633d 427 canmsgTx.len = 6; //Data Length
Mtshadow 7:49afd76d633d 428 canmsgTx.data[0] = 0x2B;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22|
Mtshadow 7:49afd76d633d 429 canmsgTx.data[1] = 0x40;//Index LowByte
Mtshadow 7:49afd76d633d 430 canmsgTx.data[2] = 0x60;//Index HighByte
Mtshadow 7:49afd76d633d 431 canmsgTx.data[3] = 0x00;//sub-Index
Mtshadow 7:49afd76d633d 432 canmsgTx.data[4] = 0x80;//data:0x00"80" = "Controlword(Reset)"
Mtshadow 7:49afd76d633d 433 canmsgTx.data[5] = 0x00;//data:0x"00"80
Mtshadow 7:49afd76d633d 434 canPort.write(canmsgTx);//CANでデータ送信
Mtshadow 7:49afd76d633d 435 wait(0.2);
Mtshadow 7:49afd76d633d 436 }
Mtshadow 7:49afd76d633d 437 void sendCtrlSD(int nodeID){
Mtshadow 7:49afd76d633d 438 canmsgTx.id = 0x600+nodeID;
Mtshadow 7:49afd76d633d 439 canmsgTx.len = 6; //Data Length
Mtshadow 7:49afd76d633d 440 canmsgTx.data[0] = 0x2B;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22|
Mtshadow 7:49afd76d633d 441 canmsgTx.data[1] = 0x40;//Index LowByte
Mtshadow 7:49afd76d633d 442 canmsgTx.data[2] = 0x60;//Index HighByte
Mtshadow 7:49afd76d633d 443 canmsgTx.data[3] = 0x00;//sub-Index
Mtshadow 7:49afd76d633d 444 canmsgTx.data[4] = 0x06;//data:0x00"06" = "Controlword(Shutdown)"
Mtshadow 7:49afd76d633d 445 canmsgTx.data[5] = 0x00;//data:0x"00"06
Mtshadow 7:49afd76d633d 446 canPort.write(canmsgTx);//CANでデータ送信
Mtshadow 7:49afd76d633d 447 wait(0.2);
Mtshadow 7:49afd76d633d 448 }
Mtshadow 7:49afd76d633d 449 void sendCtrlEN(int nodeID){
Mtshadow 7:49afd76d633d 450 canmsgTx.id = 0x600+nodeID;
Mtshadow 7:49afd76d633d 451 canmsgTx.len = 6; //Data Length
Mtshadow 7:49afd76d633d 452 canmsgTx.data[0] = 0x2B;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22|
Mtshadow 7:49afd76d633d 453 canmsgTx.data[1] = 0x40;//Index LowByte
Mtshadow 7:49afd76d633d 454 canmsgTx.data[2] = 0x60;//Index HighByte
Mtshadow 7:49afd76d633d 455 canmsgTx.data[3] = 0x00;//sub-Index
Mtshadow 7:49afd76d633d 456 canmsgTx.data[4] = 0x0F;//data:0x00"0F" = "Controlword(Enable)"
Mtshadow 7:49afd76d633d 457 canmsgTx.data[5] = 0x00;//data:0x"00"0F
Mtshadow 7:49afd76d633d 458 canPort.write(canmsgTx);//CANでデータ送信
Mtshadow 7:49afd76d633d 459 wait(0.2);
Mtshadow 7:49afd76d633d 460 }