disturbance observer
Dependencies: mbed MATSUbed USBDevice
main.cpp@8:2ae2483893f0, 2020-12-01 (annotated)
- Committer:
- Mtshadow
- Date:
- Tue Dec 01 06:10:15 2020 +0000
- Revision:
- 8:2ae2483893f0
- Parent:
- 7:49afd76d633d
- Child:
- 9:66b71a3f4ffb
revert motor
Who changed what in which revision?
User | Revision | Line number | New 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 | 7:49afd76d633d | 32 | #define tfA 0.9981 |
Mtshadow | 7:49afd76d633d | 33 | #define tfB 0.7529 |
Mtshadow | 7:49afd76d633d | 34 | #define tfC 0.002457 |
Mtshadow | 7:49afd76d633d | 35 | #define tfD 0.000004588 |
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 | 7:49afd76d633d | 41 | #define bodylength 550.0 |
Mtshadow | 7:49afd76d633d | 42 | #define startdetect 10.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 | float Distterbance_estimate_tf_abs = 0; // 外乱推定値nの絶対値 |
Mtshadow | 7:49afd76d633d | 67 | float Dist_error = 0; |
Mtshadow | 7:49afd76d633d | 68 | float baseDist = 0; // 判別基準値 |
Mtshadow | 7:49afd76d633d | 69 | int cnt_ditect = 0; // しきい値を超えてからのカウント |
Mtshadow | 7:49afd76d633d | 70 | int cnt_find = 0; // 非磁性面の検出からのカウント |
Mtshadow | 7:49afd76d633d | 71 | int findnonmagnet =0; // 非磁性面検出信号 |
Mtshadow | 7:49afd76d633d | 72 | int cnt_run = 0; // 走行時間カウント |
Mtshadow | 7:49afd76d633d | 73 | bool run_eternal = false; |
Mtshadow | 7:49afd76d633d | 74 | int check = 0; |
Mtshadow | 7:49afd76d633d | 75 | |
Mtshadow | 7:49afd76d633d | 76 | //プロトタイプ宣言 |
Mtshadow | 7:49afd76d633d | 77 | // CANopen関連 |
Mtshadow | 7:49afd76d633d | 78 | void NMTPreOpn(void); //NMT PreOperationalへ移行 |
Mtshadow | 7:49afd76d633d | 79 | void NMTOpn(void); //NMT Operationalへ移行 |
Mtshadow | 7:49afd76d633d | 80 | void CtrlWord(int); //RxPDO1 |
Mtshadow | 7:49afd76d633d | 81 | void ModesOfOperation(void);//RxPDO2 |
Mtshadow | 7:49afd76d633d | 82 | void TgtVelCtrl(int); //RxPDO3 |
Mtshadow | 7:49afd76d633d | 83 | void sendCtrlRS(int); //SDO Reset |
Mtshadow | 7:49afd76d633d | 84 | void sendCtrlSD(int); //SDO Shutdown |
Mtshadow | 7:49afd76d633d | 85 | void sendCtrlEN(int); //SDO Enable |
Mtshadow | 7:49afd76d633d | 86 | //-------------------その他-------------------- |
Mtshadow | 7:49afd76d633d | 87 | void init(void); //マイコン初期化 |
Mtshadow | 7:49afd76d633d | 88 | void CANinit(void); //CANノード初期化 |
Mtshadow | 7:49afd76d633d | 89 | void SerialRX(void); //Serial受信処理 |
Mtshadow | 7:49afd76d633d | 90 | void flip(void); //タイマー割り込み |
Mtshadow | 7:49afd76d633d | 91 | void printPlantData(void); //速度指令値、出力値をPCに表示 |
Mtshadow | 7:49afd76d633d | 92 | void EstimateDisterbance(void);//指令値を推定 |
Mtshadow | 7:49afd76d633d | 93 | void detectNonmagnet(void); |
hardtail | 0:d696cd1aea56 | 94 | |
Mtshadow | 7:49afd76d633d | 95 | int main(){ |
Mtshadow | 7:49afd76d633d | 96 | init(); |
Mtshadow | 7:49afd76d633d | 97 | myled = 0b0101; |
Mtshadow | 7:49afd76d633d | 98 | while(1){ |
Mtshadow | 7:49afd76d633d | 99 | if(Serialdata == 's'){ |
Mtshadow | 7:49afd76d633d | 100 | run_eternal = false; |
Mtshadow | 7:49afd76d633d | 101 | break; |
Mtshadow | 7:49afd76d633d | 102 | }else if(Serialdata == 'e'){ |
Mtshadow | 7:49afd76d633d | 103 | run_eternal = true; |
Mtshadow | 7:49afd76d633d | 104 | break; |
Mtshadow | 7:49afd76d633d | 105 | } |
Mtshadow | 7:49afd76d633d | 106 | myled=~myled; |
Mtshadow | 7:49afd76d633d | 107 | wait(1); |
Mtshadow | 7:49afd76d633d | 108 | } |
Mtshadow | 7:49afd76d633d | 109 | Serialdata = 0; |
Mtshadow | 7:49afd76d633d | 110 | //node初期化 |
Mtshadow | 7:49afd76d633d | 111 | CANinit(); |
Mtshadow | 7:49afd76d633d | 112 | int count=0; |
Mtshadow | 7:49afd76d633d | 113 | myled=0; |
Mtshadow | 7:49afd76d633d | 114 | while(1){ |
Mtshadow | 7:49afd76d633d | 115 | if(!ENsig){ |
Mtshadow | 7:49afd76d633d | 116 | myled=count; |
Mtshadow | 7:49afd76d633d | 117 | count++; |
Mtshadow | 7:49afd76d633d | 118 | } |
Mtshadow | 7:49afd76d633d | 119 | else{ |
Mtshadow | 7:49afd76d633d | 120 | myled =~ myled; |
Mtshadow | 7:49afd76d633d | 121 | } |
Mtshadow | 7:49afd76d633d | 122 | wait(0.5); |
Mtshadow | 7:49afd76d633d | 123 | } |
Mtshadow | 7:49afd76d633d | 124 | } |
Mtshadow | 7:49afd76d633d | 125 | //マイコン初期化 |
Mtshadow | 7:49afd76d633d | 126 | void init(void){ |
Mtshadow | 7:49afd76d633d | 127 | //I/O設定 |
Mtshadow | 7:49afd76d633d | 128 | ENsig=SYNC_Disable; |
Mtshadow | 7:49afd76d633d | 129 | //CAN設定 |
Mtshadow | 7:49afd76d633d | 130 | canPort.frequency(1000000); //Bit Rate:1Mbps |
Mtshadow | 7:49afd76d633d | 131 | //割り込み設定 |
Mtshadow | 7:49afd76d633d | 132 | flipper.attach_us(&flip,5000); //汎用タイマー割り込み周期:5ms(5*10^3 us) |
Mtshadow | 7:49afd76d633d | 133 | pc.attach(SerialRX); //Serial受信割り込み開始 |
Mtshadow | 7:49afd76d633d | 134 | } |
Mtshadow | 7:49afd76d633d | 135 | //can node初期化 |
Mtshadow | 7:49afd76d633d | 136 | void CANinit(void){ |
Mtshadow | 7:49afd76d633d | 137 | //SDOコマンドで各nodeをリセット |
Mtshadow | 7:49afd76d633d | 138 | for(int nodeID=1;nodeID <= node;nodeID++){ |
Mtshadow | 7:49afd76d633d | 139 | sendCtrlRS(nodeID); |
Mtshadow | 7:49afd76d633d | 140 | sendCtrlSD(nodeID); |
Mtshadow | 7:49afd76d633d | 141 | sendCtrlEN(nodeID); |
Mtshadow | 7:49afd76d633d | 142 | } |
Mtshadow | 7:49afd76d633d | 143 | //NMTコマンドで全nodeをオペレーショナルに |
Mtshadow | 7:49afd76d633d | 144 | NMTPreOpn(); |
Mtshadow | 7:49afd76d633d | 145 | NMTOpn(); |
Mtshadow | 7:49afd76d633d | 146 | } |
Mtshadow | 7:49afd76d633d | 147 | //Serial受信割り込み処理 |
Mtshadow | 7:49afd76d633d | 148 | void SerialRX(void){ |
Mtshadow | 7:49afd76d633d | 149 | Serialdata = pc.getc(); |
Mtshadow | 7:49afd76d633d | 150 | //-------------送信コマンドを選択-------------- |
Mtshadow | 7:49afd76d633d | 151 | if(Serialdata == 'q'){ |
Mtshadow | 7:49afd76d633d | 152 | //Haltコマンド送信 |
Mtshadow | 7:49afd76d633d | 153 | ENsig = SYNC_Disable; |
Mtshadow | 7:49afd76d633d | 154 | CtrlWord(QuickStop); |
Mtshadow | 7:49afd76d633d | 155 | Serialdata = 0; |
Mtshadow | 7:49afd76d633d | 156 | } |
Mtshadow | 7:49afd76d633d | 157 | else if(Serialdata == '1'){ |
Mtshadow | 8:2ae2483893f0 | 158 | Velocity_Trend = -1000; |
Mtshadow | 7:49afd76d633d | 159 | TgtVelCtrl(Velocity_Trend); |
Mtshadow | 7:49afd76d633d | 160 | ENsig = SYNC_Enable; |
Mtshadow | 7:49afd76d633d | 161 | Serialdata = 0; |
Mtshadow | 7:49afd76d633d | 162 | } |
Mtshadow | 7:49afd76d633d | 163 | else if(Serialdata == '2'){ |
Mtshadow | 7:49afd76d633d | 164 | Velocity_Trend = 2000; |
Mtshadow | 7:49afd76d633d | 165 | TgtVelCtrl(Velocity_Trend); |
Mtshadow | 7:49afd76d633d | 166 | ENsig = SYNC_Enable; |
Mtshadow | 7:49afd76d633d | 167 | Serialdata = 0; |
Mtshadow | 7:49afd76d633d | 168 | } |
Mtshadow | 7:49afd76d633d | 169 | else if(Serialdata == '3'){ |
Mtshadow | 7:49afd76d633d | 170 | Velocity_Trend = 3000; |
Mtshadow | 7:49afd76d633d | 171 | TgtVelCtrl(Velocity_Trend); |
Mtshadow | 7:49afd76d633d | 172 | ENsig = SYNC_Enable; |
Mtshadow | 7:49afd76d633d | 173 | Serialdata = 0; |
Mtshadow | 7:49afd76d633d | 174 | } |
Mtshadow | 7:49afd76d633d | 175 | else if(Serialdata == '4'){ |
Mtshadow | 7:49afd76d633d | 176 | Velocity_Trend = 4000; |
Mtshadow | 7:49afd76d633d | 177 | TgtVelCtrl(Velocity_Trend); |
Mtshadow | 7:49afd76d633d | 178 | ENsig = SYNC_Enable; |
Mtshadow | 7:49afd76d633d | 179 | Serialdata = 0; |
Mtshadow | 7:49afd76d633d | 180 | } |
Mtshadow | 7:49afd76d633d | 181 | else if(Serialdata == 'h'){ |
Mtshadow | 7:49afd76d633d | 182 | //Haltコマンド送信 |
Mtshadow | 7:49afd76d633d | 183 | ENsig = SYNC_Disable; |
Mtshadow | 7:49afd76d633d | 184 | CtrlWord(Halt); |
Mtshadow | 7:49afd76d633d | 185 | Serialdata = 0; |
Mtshadow | 7:49afd76d633d | 186 | } |
Mtshadow | 7:49afd76d633d | 187 | else if(Serialdata == 'm'){ |
Mtshadow | 7:49afd76d633d | 188 | ENsig = SYNC_Disable; |
Mtshadow | 7:49afd76d633d | 189 | ModesOfOperation(); |
Mtshadow | 7:49afd76d633d | 190 | Serialdata = 0; |
Mtshadow | 7:49afd76d633d | 191 | } |
hardtail | 4:a6882e08058c | 192 | |
Mtshadow | 7:49afd76d633d | 193 | } |
Mtshadow | 7:49afd76d633d | 194 | //汎用タイマー |
Mtshadow | 7:49afd76d633d | 195 | void flip(void){ |
Mtshadow | 8:2ae2483893f0 | 196 | if(canPort.read(canmsgRx)){ |
Mtshadow | 7:49afd76d633d | 197 | cnt_run++; |
Mtshadow | 8:2ae2483893f0 | 198 | if(canmsgRx.id == 0x4a0) printPlantData(); |
Mtshadow | 7:49afd76d633d | 199 | } |
Mtshadow | 7:49afd76d633d | 200 | // 走行2分後に停止 |
Mtshadow | 7:49afd76d633d | 201 | if (cnt_run >= 12000 && run_eternal == false) { |
Mtshadow | 7:49afd76d633d | 202 | //Haltコマンド送信 |
Mtshadow | 7:49afd76d633d | 203 | ENsig = SYNC_Disable; |
Mtshadow | 7:49afd76d633d | 204 | CtrlWord(QuickStop); |
Mtshadow | 7:49afd76d633d | 205 | } |
Mtshadow | 7:49afd76d633d | 206 | |
Mtshadow | 7:49afd76d633d | 207 | |
Mtshadow | 7:49afd76d633d | 208 | |
Mtshadow | 7:49afd76d633d | 209 | } |
Mtshadow | 7:49afd76d633d | 210 | //速度出力値、指令値の表示 |
Mtshadow | 7:49afd76d633d | 211 | void printPlantData(void){ |
Mtshadow | 8:2ae2483893f0 | 212 | short Current_raw, Velocity_raw; |
Mtshadow | 8:2ae2483893f0 | 213 | |
Mtshadow | 8:2ae2483893f0 | 214 | Current_raw = canmsgRx.data[1]*0x100+canmsgRx.data[0]; //指令値の取得(電流) |
Mtshadow | 8:2ae2483893f0 | 215 | if (Current_raw > 10000) Current_demand = ((Current_raw - 1) ^ 0xffff) * -1; |
Mtshadow | 8:2ae2483893f0 | 216 | else Current_demand = Current_raw; |
Mtshadow | 8:2ae2483893f0 | 217 | |
Mtshadow | 8:2ae2483893f0 | 218 | //Velocity_actual = canmsgRx.data[5]*0x100+canmsgRx.data[4]; //出力値の取得(速度) |
Mtshadow | 8:2ae2483893f0 | 219 | Velocity_raw = canmsgRx.data[5]*0x100+canmsgRx.data[4]; |
Mtshadow | 8:2ae2483893f0 | 220 | if (Velocity_raw > 10000) Velocity_actual = ((Velocity_raw -1) ^ 0xffff) * -1; |
Mtshadow | 8:2ae2483893f0 | 221 | else Velocity_actual = Velocity_raw; |
Mtshadow | 7:49afd76d633d | 222 | |
Mtshadow | 7:49afd76d633d | 223 | EstimateDisterbance(); //外乱の推定 |
Mtshadow | 7:49afd76d633d | 224 | detectNonmagnet(); //非磁性面の判別 |
Mtshadow | 8:2ae2483893f0 | 225 | 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 | 8:2ae2483893f0 | 226 | if ( findnonmagnet == 1 && run_eternal == false) { |
Mtshadow | 8:2ae2483893f0 | 227 | /*cnt_find++; |
Mtshadow | 7:49afd76d633d | 228 | if (cnt_find >= 200) { |
Mtshadow | 7:49afd76d633d | 229 | //Haltコマンド送信 |
Mtshadow | 7:49afd76d633d | 230 | ENsig = SYNC_Disable; |
Mtshadow | 7:49afd76d633d | 231 | CtrlWord(QuickStop); |
Mtshadow | 8:2ae2483893f0 | 232 | }*/ |
Mtshadow | 8:2ae2483893f0 | 233 | //ENsig = SYNC_Disable; |
Mtshadow | 8:2ae2483893f0 | 234 | //CtrlWord(QuickStop); |
Mtshadow | 8:2ae2483893f0 | 235 | } |
Mtshadow | 7:49afd76d633d | 236 | findnonmagnet = 0; |
hardtail | 4:a6882e08058c | 237 | } |
hardtail | 4:a6882e08058c | 238 | |
Mtshadow | 7:49afd76d633d | 239 | void EstimateDisterbance(void){ |
Mtshadow | 7:49afd76d633d | 240 | //出力値のトレンド除去 |
Mtshadow | 8:2ae2483893f0 | 241 | Velocity_estimate = (Velocity_actual-Velocity_Trend)*Kv; |
Mtshadow | 7:49afd76d633d | 242 | //電流値トレンドの計算 |
Mtshadow | 8:2ae2483893f0 | 243 | Current_Trend = int((Current_Trend + Current_demand)/2); |
Mtshadow | 8:2ae2483893f0 | 244 | Current_estimate = (Current_demand-Current_Trend)*Km; |
Mtshadow | 7:49afd76d633d | 245 | /* |
Mtshadow | 7:49afd76d633d | 246 | 伝達関数 |
Mtshadow | 7:49afd76d633d | 247 | (tfAz - tfB) |
Mtshadow | 7:49afd76d633d | 248 | tf = ------------ |
Mtshadow | 7:49afd76d633d | 249 | (tfCz - tfD) |
Mtshadow | 7:49afd76d633d | 250 | */ |
Mtshadow | 7:49afd76d633d | 251 | Torque_estimate_tf = (tfA*Velocity_estimate - tfB*Velocity_estimate_z1 + tfD*Torque_estimate_tf)/tfC; |
Mtshadow | 7:49afd76d633d | 252 | Velocity_estimate_z1 = Velocity_estimate; |
Mtshadow | 8:2ae2483893f0 | 253 | Distterbance_estimate_tf = Torque_estimate_tf - Current_estimate; |
Mtshadow | 7:49afd76d633d | 254 | } |
Mtshadow | 7:49afd76d633d | 255 | |
Mtshadow | 7:49afd76d633d | 256 | void detectNonmagnet(void) { |
Mtshadow | 7:49afd76d633d | 257 | Velocity_meter = Velocity_actual * Kv; //回転数から速度に変換[m/s] |
Mtshadow | 7:49afd76d633d | 258 | distance += Velocity_meter * samplimgrate; //走行距離を計算 |
Mtshadow | 7:49afd76d633d | 259 | Distterbance_estimate_tf_abs = fabsf(Distterbance_estimate_tf); |
Mtshadow | 7:49afd76d633d | 260 | if (distance <= bodylength && distance >= startdetect) { |
Mtshadow | 7:49afd76d633d | 261 | check = 0; |
Mtshadow | 7:49afd76d633d | 262 | //外乱推定値の最大値を確認 |
Mtshadow | 7:49afd76d633d | 263 | if(Distterbance_estimate_tf_abs > baseDist) baseDist = Distterbance_estimate_tf_abs; |
Mtshadow | 7:49afd76d633d | 264 | } else if (distance > bodylength) { |
Mtshadow | 7:49afd76d633d | 265 | Dist_error = Distterbance_estimate_tf_abs / baseDist; |
Mtshadow | 7:49afd76d633d | 266 | if (Dist_error < 0.3) { |
Mtshadow | 7:49afd76d633d | 267 | check = 1; |
Mtshadow | 7:49afd76d633d | 268 | cnt_ditect++; |
Mtshadow | 8:2ae2483893f0 | 269 | if(cnt_ditect >= 90) { |
Mtshadow | 7:49afd76d633d | 270 | findnonmagnet = 1; |
Tiryoh | 2:f94af4a543bd | 271 | } |
Mtshadow | 7:49afd76d633d | 272 | } else { |
Mtshadow | 7:49afd76d633d | 273 | cnt_ditect = 0; |
hardtail | 0:d696cd1aea56 | 274 | } |
Mtshadow | 7:49afd76d633d | 275 | } |
Mtshadow | 7:49afd76d633d | 276 | |
Mtshadow | 7:49afd76d633d | 277 | } |
Mtshadow | 7:49afd76d633d | 278 | //NMT |
Mtshadow | 7:49afd76d633d | 279 | void NMTPreOpn(void){ |
Mtshadow | 7:49afd76d633d | 280 | //COB-ID:0 0x01-00-//-//-//-//-//-// |
Mtshadow | 7:49afd76d633d | 281 | canmsgTx.id = 0x0; |
Mtshadow | 7:49afd76d633d | 282 | canmsgTx.len = 2; |
Mtshadow | 7:49afd76d633d | 283 | canmsgTx.data[0] = 0x80;//0x01:enter NMT state "PreOperational" |
Mtshadow | 7:49afd76d633d | 284 | canmsgTx.data[1] = 0x00;//send All nodes |
Mtshadow | 7:49afd76d633d | 285 | canPort.write(canmsgTx); |
Mtshadow | 7:49afd76d633d | 286 | wait(0.2); |
Mtshadow | 7:49afd76d633d | 287 | } |
Mtshadow | 7:49afd76d633d | 288 | void NMTOpn(void){ |
Mtshadow | 7:49afd76d633d | 289 | //COB-ID:0 0x01-00-//-//-//-//-//-// |
Mtshadow | 7:49afd76d633d | 290 | canmsgTx.id = 0x0; |
Mtshadow | 7:49afd76d633d | 291 | canmsgTx.len = 2; |
Mtshadow | 7:49afd76d633d | 292 | canmsgTx.data[0] = 0x01;//0x01:enter NMT state "Operational" |
Mtshadow | 7:49afd76d633d | 293 | canmsgTx.data[1] = 0x00;//send All nodes |
Mtshadow | 7:49afd76d633d | 294 | canPort.write(canmsgTx); |
Mtshadow | 7:49afd76d633d | 295 | wait(0.2); |
Mtshadow | 7:49afd76d633d | 296 | } |
Mtshadow | 7:49afd76d633d | 297 | //PDO |
Mtshadow | 7:49afd76d633d | 298 | void CtrlWord(int type){ |
Mtshadow | 7:49afd76d633d | 299 | canmsgTx.id = RxPDO1; |
Mtshadow | 7:49afd76d633d | 300 | canmsgTx.len = 2; //Data Length |
Mtshadow | 7:49afd76d633d | 301 | if(type==Halt){ |
Mtshadow | 7:49afd76d633d | 302 | canmsgTx.data[0] = 0x0F;//data:0x01"0F" |
Mtshadow | 7:49afd76d633d | 303 | canmsgTx.data[1] = 0x01;//data:0x"01"0F |
Mtshadow | 7:49afd76d633d | 304 | } |
Mtshadow | 7:49afd76d633d | 305 | else if(type==QuickStop){ |
Mtshadow | 7:49afd76d633d | 306 | canmsgTx.data[0] = 0x0B;//data:0x00"0B" |
Mtshadow | 7:49afd76d633d | 307 | canmsgTx.data[1] = 0x00;//data:0x"00"0B |
Mtshadow | 7:49afd76d633d | 308 | } |
Mtshadow | 7:49afd76d633d | 309 | else if(type==ShutDown){ |
Mtshadow | 7:49afd76d633d | 310 | canmsgTx.data[0] = 0x06;//data:0x00"06" |
Mtshadow | 7:49afd76d633d | 311 | canmsgTx.data[1] = 0x00;//data:0x"00"06 |
hardtail | 0:d696cd1aea56 | 312 | } |
Mtshadow | 7:49afd76d633d | 313 | canPort.write(canmsgTx);//CANでデータ送信 |
Tiryoh | 2:f94af4a543bd | 314 | } |
Mtshadow | 7:49afd76d633d | 315 | void ModesOfOperation(void){ |
Mtshadow | 7:49afd76d633d | 316 | canmsgTx.id = RxPDO2; |
Mtshadow | 7:49afd76d633d | 317 | canmsgTx.len = 1; //Data Length |
Mtshadow | 7:49afd76d633d | 318 | canmsgTx.data[0] = 0x03;//data:0x03 = "Profile Velocity Mode" |
Mtshadow | 7:49afd76d633d | 319 | canPort.write(canmsgTx);//CANでデータ送信 |
Mtshadow | 7:49afd76d633d | 320 | } |
Mtshadow | 7:49afd76d633d | 321 | void TgtVelCtrl(int rpm){ |
Mtshadow | 7:49afd76d633d | 322 | //pc.printf("%drpm|0x%08x\r\n",rpm,rpm); |
Mtshadow | 7:49afd76d633d | 323 | canmsgTx.id = RxPDO3; |
Mtshadow | 7:49afd76d633d | 324 | canmsgTx.len = 6; //Data Length |
Mtshadow | 7:49afd76d633d | 325 | //Target Velocity |
Mtshadow | 8:2ae2483893f0 | 326 | if (rpm > 0) { |
Mtshadow | 8:2ae2483893f0 | 327 | for(char cnt=0;cnt<4;cnt++){ |
Mtshadow | 8:2ae2483893f0 | 328 | canmsgTx.data[cnt] = rpm % 256; |
Mtshadow | 8:2ae2483893f0 | 329 | rpm = rpm / 256; |
Mtshadow | 8:2ae2483893f0 | 330 | } |
Mtshadow | 8:2ae2483893f0 | 331 | } else { |
Mtshadow | 8:2ae2483893f0 | 332 | canmsgTx.data[0] = 0x17; |
Mtshadow | 8:2ae2483893f0 | 333 | canmsgTx.data[1] = 0xFC; |
Mtshadow | 8:2ae2483893f0 | 334 | canmsgTx.data[2] = 0xFF; |
Mtshadow | 8:2ae2483893f0 | 335 | canmsgTx.data[3] = 0xFF; |
Mtshadow | 8:2ae2483893f0 | 336 | /* |
Mtshadow | 8:2ae2483893f0 | 337 | rpm = (rpm ^ 0xffffffff) + 1; |
Mtshadow | 8:2ae2483893f0 | 338 | //printf("%x",rpm); |
Mtshadow | 8:2ae2483893f0 | 339 | for(char cnt=0;cnt<4;cnt++){ |
Mtshadow | 8:2ae2483893f0 | 340 | canmsgTx.data[cnt] = rpm & 0x000000FF; |
Mtshadow | 8:2ae2483893f0 | 341 | //printf("%x",rpm); |
Mtshadow | 8:2ae2483893f0 | 342 | rpm = rpm >> 2; |
Mtshadow | 8:2ae2483893f0 | 343 | } |
Mtshadow | 8:2ae2483893f0 | 344 | */ |
Mtshadow | 7:49afd76d633d | 345 | } |
Mtshadow | 7:49afd76d633d | 346 | //CtrlWord Enable |
Mtshadow | 7:49afd76d633d | 347 | canmsgTx.data[4] = 0x0F;//data:0x00"0F" |
Mtshadow | 7:49afd76d633d | 348 | canmsgTx.data[5] = 0x00;//data:0x"00"0F |
Mtshadow | 7:49afd76d633d | 349 | canPort.write(canmsgTx);//CANでデータ送信 |
Mtshadow | 7:49afd76d633d | 350 | } |
Mtshadow | 7:49afd76d633d | 351 | //SDO |
Mtshadow | 7:49afd76d633d | 352 | void sendCtrlRS(int nodeID){ |
Mtshadow | 7:49afd76d633d | 353 | canmsgTx.id = 0x600+nodeID; |
Mtshadow | 7:49afd76d633d | 354 | canmsgTx.len = 6; //Data Length |
Mtshadow | 7:49afd76d633d | 355 | canmsgTx.data[0] = 0x2B;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22| |
Mtshadow | 7:49afd76d633d | 356 | canmsgTx.data[1] = 0x40;//Index LowByte |
Mtshadow | 7:49afd76d633d | 357 | canmsgTx.data[2] = 0x60;//Index HighByte |
Mtshadow | 7:49afd76d633d | 358 | canmsgTx.data[3] = 0x00;//sub-Index |
Mtshadow | 7:49afd76d633d | 359 | canmsgTx.data[4] = 0x80;//data:0x00"80" = "Controlword(Reset)" |
Mtshadow | 7:49afd76d633d | 360 | canmsgTx.data[5] = 0x00;//data:0x"00"80 |
Mtshadow | 7:49afd76d633d | 361 | canPort.write(canmsgTx);//CANでデータ送信 |
Mtshadow | 7:49afd76d633d | 362 | wait(0.2); |
Mtshadow | 7:49afd76d633d | 363 | } |
Mtshadow | 7:49afd76d633d | 364 | void sendCtrlSD(int nodeID){ |
Mtshadow | 7:49afd76d633d | 365 | canmsgTx.id = 0x600+nodeID; |
Mtshadow | 7:49afd76d633d | 366 | canmsgTx.len = 6; //Data Length |
Mtshadow | 7:49afd76d633d | 367 | canmsgTx.data[0] = 0x2B;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22| |
Mtshadow | 7:49afd76d633d | 368 | canmsgTx.data[1] = 0x40;//Index LowByte |
Mtshadow | 7:49afd76d633d | 369 | canmsgTx.data[2] = 0x60;//Index HighByte |
Mtshadow | 7:49afd76d633d | 370 | canmsgTx.data[3] = 0x00;//sub-Index |
Mtshadow | 7:49afd76d633d | 371 | canmsgTx.data[4] = 0x06;//data:0x00"06" = "Controlword(Shutdown)" |
Mtshadow | 7:49afd76d633d | 372 | canmsgTx.data[5] = 0x00;//data:0x"00"06 |
Mtshadow | 7:49afd76d633d | 373 | canPort.write(canmsgTx);//CANでデータ送信 |
Mtshadow | 7:49afd76d633d | 374 | wait(0.2); |
Mtshadow | 7:49afd76d633d | 375 | } |
Mtshadow | 7:49afd76d633d | 376 | void sendCtrlEN(int nodeID){ |
Mtshadow | 7:49afd76d633d | 377 | canmsgTx.id = 0x600+nodeID; |
Mtshadow | 7:49afd76d633d | 378 | canmsgTx.len = 6; //Data Length |
Mtshadow | 7:49afd76d633d | 379 | canmsgTx.data[0] = 0x2B;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22| |
Mtshadow | 7:49afd76d633d | 380 | canmsgTx.data[1] = 0x40;//Index LowByte |
Mtshadow | 7:49afd76d633d | 381 | canmsgTx.data[2] = 0x60;//Index HighByte |
Mtshadow | 7:49afd76d633d | 382 | canmsgTx.data[3] = 0x00;//sub-Index |
Mtshadow | 7:49afd76d633d | 383 | canmsgTx.data[4] = 0x0F;//data:0x00"0F" = "Controlword(Enable)" |
Mtshadow | 7:49afd76d633d | 384 | canmsgTx.data[5] = 0x00;//data:0x"00"0F |
Mtshadow | 7:49afd76d633d | 385 | canPort.write(canmsgTx);//CANでデータ送信 |
Mtshadow | 7:49afd76d633d | 386 | wait(0.2); |
Mtshadow | 7:49afd76d633d | 387 | } |