![C語(yǔ)言程序設(shè)計(jì)報(bào)告書_第1頁(yè)](http://file4.renrendoc.com/view/59703fb9131d2cbaaabbfb02323ac4f8/59703fb9131d2cbaaabbfb02323ac4f81.gif)
![C語(yǔ)言程序設(shè)計(jì)報(bào)告書_第2頁(yè)](http://file4.renrendoc.com/view/59703fb9131d2cbaaabbfb02323ac4f8/59703fb9131d2cbaaabbfb02323ac4f82.gif)
![C語(yǔ)言程序設(shè)計(jì)報(bào)告書_第3頁(yè)](http://file4.renrendoc.com/view/59703fb9131d2cbaaabbfb02323ac4f8/59703fb9131d2cbaaabbfb02323ac4f83.gif)
![C語(yǔ)言程序設(shè)計(jì)報(bào)告書_第4頁(yè)](http://file4.renrendoc.com/view/59703fb9131d2cbaaabbfb02323ac4f8/59703fb9131d2cbaaabbfb02323ac4f84.gif)
![C語(yǔ)言程序設(shè)計(jì)報(bào)告書_第5頁(yè)](http://file4.renrendoc.com/view/59703fb9131d2cbaaabbfb02323ac4f8/59703fb9131d2cbaaabbfb02323ac4f85.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
3 《C語(yǔ)言程序設(shè)計(jì)》實(shí)驗(yàn)設(shè)計(jì)報(bào)告 學(xué)院:_機(jī)電工程專業(yè)班級(jí):自動(dòng)化31班學(xué)生姓名:王劉鄞 學(xué)號(hào)導(dǎo)老師:段江濤 設(shè)計(jì)題目:___三層電梯狀態(tài)機(jī)編程__2016年05月18日目錄1.設(shè)計(jì)題目:三層電梯狀態(tài)機(jī) 3前期只考慮了三層電梯模型,由此產(chǎn)生了(版本一)后期對(duì)電梯程序進(jìn)行了修改,適應(yīng)多樓層(版本二)2.設(shè)計(jì)方案: 32.1前期設(shè)計(jì)方案(版本一)2.2后期改進(jìn)及樓層推廣,適應(yīng)多樓層(版本二)3.狀態(tài)機(jī)建模: 33.1狀態(tài)圖建立圖一:狀態(tài)圖 圖二:思維圖3.2狀態(tài)機(jī)功能模塊 3.3函數(shù)以及調(diào)用關(guān)系 4.代碼分析及程序優(yōu)化 94.1版本一與版本二初始化比較分析4.2版本一與版本二上升函數(shù)部分比較分析4.3版本一與版本二下降函數(shù)部分比較分析4.4版本一與版本二開門函數(shù)部分比較分析4.5版本一與版本二關(guān)門函數(shù)部分比較分析4.6兩種版本的的評(píng)估及比較分析5.系統(tǒng)運(yùn)行測(cè)試結(jié)果分析 17測(cè)試一:電梯內(nèi)樓層按鍵的使用及演示(目前基于三層)測(cè)試二:樓層外上下按鍵的使用及演示測(cè)試三:開關(guān)門按鈕的使用及演示測(cè)試四:自動(dòng)到一樓綜合測(cè)試分析以上測(cè)試結(jié)果對(duì)于版本一及版本二都適用,實(shí)測(cè)正確。6.學(xué)習(xí)心得及一些改進(jìn)和調(diào)試過程中的心得體會(huì) 263.2狀態(tài)機(jī)功能模塊 一:初始化二:移動(dòng)下降模塊上升模塊三:開關(guān)門開門模塊關(guān)門模塊可能發(fā)生的Events:E1:門內(nèi)開門按鈕(OpenDoorLight)E2:門內(nèi)關(guān)門按鈕(CloseDoorLight)E3:門內(nèi)樓層按鈕(PanelFloorLight)目前使用三個(gè)按鈕(1,2,3)E4:門外up呼叫按鈕(CallLight)E5:門外down呼叫按鈕(CallLight)3.2函數(shù)以及調(diào)用關(guān)系:狀態(tài)機(jī)主要函數(shù)及自己發(fā)揮部分/*****************************************************************************/voidIdlestate(int*state);//初始化函數(shù)voidmovingup(int*state);//向上升函數(shù)voidmovingdown(int*state);//下降函數(shù)voidDooropen(int*state);//開門函數(shù)voidDoorclosing(int*state)//門關(guān)閉函數(shù)初始化函數(shù)根據(jù)條件跳轉(zhuǎn)上升下降及開門函數(shù);上升下降函數(shù)根據(jù)條件跳轉(zhuǎn)開門函數(shù);門開函數(shù)根據(jù)條件調(diào)用門關(guān)閉函數(shù);門關(guān)閉根據(jù)條件調(diào)用初始化及門開;三層電梯使用到的函數(shù)/*******************************************************************///系統(tǒng)是否運(yùn)行boolIsElevatorRunning();//電梯門外Up/Down呼叫按鈕燈(CallLight)boolGetPanelFloorLight(intfloor);voidSetCallLight(intfloor,boolup,bools);//電梯門內(nèi)樓層按鈕燈(PanelFloorLight)boolGetPanelFloorLight(intfloor);//IdleWhatFloorToGoTo()等函數(shù)中用voidSetPanelFloorLight(intfloor,bools);//電梯門內(nèi)開關(guān)門按鈕燈boolGetOpenDoorLight();voidSetOpenDoorLight(bools);boolGetCloseDoorLight();voidSetCloseDoorLight(bools);//電梯箱體門boolIsDoorOpen(intfloor);boolIsDoorClosed(intfloor);voidSetDoor(intfloor,boolopen);//設(shè)置電機(jī)功率,power=1,全速上升;-1,全速下降;0,停止voidSetMotorPower(doublepower);//一定時(shí)間無(wú)動(dòng)作,自動(dòng)到1樓externvoidAutoTo1Floor();//取消自動(dòng)到1樓externvoidCancelTo1Floor();//獲取電梯箱體當(dāng)前所在樓層doubleGetFloor();//浮點(diǎn)數(shù),如1.5,表示電梯箱體處在1層到2層的中間intGetNearestFloor();//GetFloor()函數(shù)的四舍五入值if(fabs(GetFloor()-GetNearestFloor())<Lib_FloorTolerance){到達(dá)GetNearestFloor()層}//靜態(tài)監(jiān)測(cè),電梯處于空閑狀態(tài),確定下一步的運(yùn)動(dòng)方向和所到樓層(目標(biāo)樓層)intIdleWhatFloorToGoTo(bool*up);intfloor;boolup;floor=IdleWhatFloorToGoTo(&up);//動(dòng)態(tài)監(jiān)測(cè),電梯正在上升時(shí),檢測(cè)將要到達(dá)停止的最近樓層(目標(biāo)樓層)intGoingUpToFloor();//動(dòng)態(tài)監(jiān)測(cè),電梯正在下降時(shí),檢測(cè)將要到達(dá)停止的最近樓層(目標(biāo)樓層)intGoingDownToFloor();/*******************************************************************/3.3分別對(duì)每個(gè)狀態(tài)進(jìn)行分析Idle狀態(tài),電梯停止在某樓層,門是關(guān)閉的,處于靜止?fàn)顟B(tài),等待相關(guān)事件的發(fā)生,從而轉(zhuǎn)換到下一個(gè)狀態(tài)。(S1)檢查E3、E4、E5事件。靜態(tài)檢測(cè),boolup;目標(biāo)樓層=IdleWhatFloorToGoTo(&up);關(guān)閉本層門外up按鈕,SetCallLight();即消費(fèi)門外up按鈕,防止下一周期重復(fù)處理此按鈕行為。(S2)同(S1),消費(fèi)門外down按鈕。1層以上,一定時(shí)間無(wú)動(dòng)作,自動(dòng)下降到1樓。AutoTo1Floor();[其它 狀態(tài), 取消此功能,CancelTo1Floor()](S3)檢查E1事件,開門,消費(fèi)開門按鈕;上升(up&&E4事件),開門,消費(fèi)門外up按鈕下降(!up&&E5事件),開門,消費(fèi)門外down按鈕(S4)檢查E2事件,此時(shí)門應(yīng)該是關(guān)閉的,因此僅讀取關(guān)門燈,并關(guān)閉關(guān)門燈,即消費(fèi)按鍵行為,防止下一周期重復(fù)處理該按鈕的行為。if(GetCloseDoorLight()){SetCloseDoorLight(false);return;}Moving狀態(tài):MovingUp/MovingDown跳轉(zhuǎn)到DoorOpen(S5)檢查E3、E4、E5事件。動(dòng)態(tài)檢測(cè),目標(biāo)樓層floor=GoingUpToFloor();if(fabs(GetFloor()-floor)<Lib_FloorTolerance)到達(dá)目標(biāo)樓層,停止,開門消費(fèi)門外up按鈕;到了最高層Lib_FloorNum,消費(fèi)門外down按鈕。消費(fèi)門內(nèi)樓層按鈕。(D)檢查E1、E2事件,無(wú)動(dòng)作,消費(fèi)開/關(guān)門按鈕。(S6)檢查E3、E4、E5事件。動(dòng)態(tài)檢測(cè),目標(biāo)樓層=GoingDownToFloor();其它與 (S5)類似。DoorOpen狀態(tài):電梯門打開跳轉(zhuǎn)到DoorClosing(S7)檢查E2事件,轉(zhuǎn)而關(guān)門,GetCloseDoorLight(),SetDoor();消費(fèi)關(guān)門按 鈕。開門結(jié)束后,自動(dòng)進(jìn)入關(guān)門狀態(tài)。IsDoorOpen();SetDoor();檢查E1事件,無(wú)動(dòng)作,消費(fèi)開門按鈕。DoorClosing狀態(tài):正在關(guān)門跳轉(zhuǎn)到DoorOpen(S8)檢查E1事件,轉(zhuǎn)而開門。GetOpenDoorLight();SetDoor();消費(fèi)關(guān)門按鈕。檢查E2事件,無(wú)動(dòng)作,消費(fèi)關(guān)門按鈕。DoorClosing狀態(tài):正在關(guān)門Idle(S9)關(guān)門結(jié)束后,進(jìn)入Idle狀態(tài)。IsDoorClosed();4.1版本一與版本二初始化比較分析版本一使用switch語(yǔ)句進(jìn)行判斷,1層以上,一定時(shí)間無(wú)動(dòng)作,自動(dòng)下降到1樓。AutoTo1Floor();[其它狀態(tài),取消此功能,CancelTo1Floor()分別在某一層可能發(fā)生的事件進(jìn)行判斷,并進(jìn)行相應(yīng)的處理。沒有使用部分函數(shù)代碼及注解分析如下:floor=GetNearestFloor(); up=1;//up這里只是充當(dāng)數(shù)值上或者下switch(floor)//到了每一層進(jìn)行判斷各層會(huì)發(fā)生的狀況 { case1: if(GetCallLight(1,up))//在第一樓向上的按了 { *state=DoorOpen; //開門 printf("Transition:fromIdlestatetoDoorOpen.\n"); return; } //如果在2,3層或者是按樓層鍵 if(GetPanelFloorLight(2)|GetCallLight(2,up)|GetCallLight(2,0)| GetPanelFloorLight(3)|GetCallLight(3,0)) { *state=MovingUp;//上升狀態(tài) printf("Transition:fromIdlestatetoMovingUp.\n"); return; } //開關(guān)門判斷 if(GetOpenDoorLight())//如果開門按鈕打開 { SetDoor(floor,true);//開門 SetOpenDoorLight(false); *state=DoorOpen; return; } if(GetCloseDoorLight())//有關(guān)門按鍵就關(guān)門 { SetDoor(floor,false); SetCloseDoorLight(false); *state=DoorClosing; return; } break; case2: //在第二層 if(GetPanelFloorLight(3)|GetCallLight(3,0)|GetCallLight(3,up)) //第三層出現(xiàn)按鍵有用 { *state=MovingUp; //上升 printf("Transition:fromIdlestatetoMovingUp.\n"); return; } if(GetPanelFloorLight(1)|GetCallLight(1,0)|GetCallLight(1,up))//第一層按鍵 { *state=MovingDown;//下降 SetCallLight(floor,0,false); printf("Transition:fromIdlestatetoMovingDown.\n"); return; } if(GetOpenDoorLight())//如果開門按鈕打開 { SetDoor(floor,true);//開門 SetOpenDoorLight(false); *state=DoorOpen; return; } if(GetCloseDoorLight())//有關(guān)門按鍵就關(guān)門 { SetDoor(floor,false); SetCloseDoorLight(false); *state=DoorClosing; return; }AutoTo1Floor();//自動(dòng)到一樓 break; case3: //第三層碰到的情況 if(GetPanelFloorLight(1)|GetPanelFloorLight(2)|GetCallLight(2,0)| GetCallLight(1,1)|GetCallLight(2,1)) { *state=MovingDown; SetCallLight(floor,0,false);//下降 printf("Transition:fromIdlestatetoMovingDown.\n"); return; } if(GetOpenDoorLight())//如果開門按鈕打開 { SetDoor(floor,true);//開門 SetOpenDoorLight(false); *state=DoorOpen; return; } if(GetCloseDoorLight())//有關(guān)門按鍵就關(guān)門 { SetDoor(floor,false); SetCloseDoorLight(false); *state=DoorClosing; return; } AutoTo1Floor();//自動(dòng)到一樓 break;以上是版本一的初始化函數(shù)版本二使用靜態(tài)檢測(cè),boolup;目標(biāo)樓層=IdleWhatFloorToGoTo(&up);只對(duì)事件進(jìn)行判斷voidIdlestate(int*state){ intfloor,nowfloor; boolup; nowfloor=GoingDownToFloor(); if(nowfloor==1) { if(GetCallLight(1,1)) { *state=DoorOpen; SetCallLight(1,1,false); printf("Transition:fromIdlestatetoDoorOpen.\n"); return; } } floor=IdleWhatFloorToGoTo(&up);//靜態(tài)檢測(cè)上升到那一樓 if(floor>-1) { //判斷電梯樓層按鈕程序 if(up&&GetPanelFloorLight(floor))//向上的按鈕按了就向上運(yùn)行 { // SetCallLight(floor,up,false); *state=MovingUp; //狀態(tài)翻轉(zhuǎn) printf("Transition:fromIdlestatetoMovingUp.\n"); return; //減少代碼運(yùn)行時(shí)間 } if(!up&&GetPanelFloorLight(floor)) { // SetCallLight(floor,!up,false); *state=MovingDown; printf("Transition:fromIdlestatetoMovingDown.\n"); return; } //電梯內(nèi)上下按鈕的程序 if(GetCallLight(floor,up)|GetCallLight(floor,!up))//樓層上下呼叫 { if(up==true) //開始消費(fèi) { *state=MovingUp; printf("Transition:fromIdlestatetoMovingUp.\n"); return; } if(up==false) { *state=MovingDown; printf("Transition:fromIdlestatetoMovingUp.\n"); return; } } //開關(guān)門函數(shù)處理 if(GetCloseDoorLight()) //關(guān)門燈判斷 { SetCloseDoorLight(false); *state=DoorClosing; printf("Transition:fromIdlestatetoDoorClosing.\n"); return; } if(GetOpenDoorLight()) //開門燈判斷 { SetOpenDoorLight(false); *state=DoorOpen; printf("Transition:fromIdlestatetoDoorOpen.\n"); return; } } ///對(duì)自動(dòng)下降函數(shù)的處理 if(nowfloor>1) { AutoTo1Floor(); //printf("進(jìn)去了1111\n");//測(cè)試用 }}4.2版本一與版本二上升函數(shù)部分比較分析版本二在版本一的基礎(chǔ)上修改不大,局部進(jìn)行了部分調(diào)整,但沒什么變化。版本一這個(gè)函數(shù)已經(jīng)接近完善。兩者的思路相似只是一個(gè)消費(fèi)的過程,其它絕大多數(shù)都在初始化中進(jìn)行了判斷。版本一voidmovingup(int*state){ intfloor; boolup=1; CancelTo1Floor(); floor=GoingUpToFloor(); //動(dòng)態(tài)檢測(cè) if(GetPanelFloorLight(floor)) //滅燈的過程,防止重復(fù)消費(fèi) SetPanelFloorLight(floor,false); if(GetCallLight(floor,up)) SetCallLight(floor,up,false); if(GetCallLight(floor,0)) SetCallLight(floor,0,false); if(fabs(GetFloor()-floor)<Lib_FloorTolerance)//判斷距離,調(diào)節(jié)電機(jī) { SetMotorPower(0); SetDoor(floor,1); *state=DoorOpen; printf("Transition:fromMovinguptoDowmOpen.\n"); return; } else SetMotorPower(1);}版本二voidmovingup(int*state){ intfloor; boolup=1; CancelTo1Floor();//取消自動(dòng)到一樓 floor=GoingUpToFloor(); //判斷到那一層 if(fabs(GetFloor()-floor)<Lib_FloorTolerance) //距離判斷 { if(GetCallLight(floor,up)|GetCallLight(floor,!up))//樓層上下呼叫 { SetCallLight(floor,up,false);//滅燈 SetCallLight(floor,!up,false); } if(GetPanelFloorLight(floor)) //滅燈樓層按鈕 SetPanelFloorLight(floor,false); SetMotorPower(0); SetDoor(floor,1); *state=DoorOpen; printf("Transition:fromMovinguptoDowmOpen.\n"); return; } else SetMotorPower(1);}4.3版本一與版本二下降函數(shù)部分比較分析版本二在版本一的基礎(chǔ)上修改不大,局部進(jìn)行了部分調(diào)整,但沒什么變化。版本一的這個(gè)函數(shù),在調(diào)試過程中遇到了麻煩。兩者的思路相似只是一個(gè)消費(fèi)的過程,其它絕大多數(shù)都在初始化中進(jìn)行了判斷。版本一voidmovingdown(int*state){ intfloor; boolup=1; CancelTo1Floor(); if(GetPanelFloorLight(1)|GetPanelFloorLight(2)|GetCallLight(2,0)|GetCallLight(1,1)|GetCallLight(2,1)|GetPanelFloorLight(1)|GetCallLight(1,0)|GetCallLight(1,up)) { floor=GoingDownToFloor(); //滅燈 }//加上這個(gè)解決了不能到一樓的BUG floor=1; if(GetPanelFloorLight(floor)) SetPanelFloorLight(floor,false); if(GetCallLight(floor,!up)) SetCallLight(floor,!up,false); if(GetCallLight(floor,up)) SetCallLight(floor,up,false); if(fabs(GetFloor()-floor)<Lib_FloorTolerance) { SetMotorPower(0); SetDoor(floor,1); *state=DoorOpen; printf("Transition:frommovingdowntoDoorOpen.\n"); return; } else SetMotorPower(-1);}版本二:voidmovingdown(int*state){ intfloor;// boolup=1; CancelTo1Floor(); //{// floor=1;// if(GetCallLight(floor,!up)|GetCallLight(floor,up)|GetPanelFloorLight(floor))//{// 去掉了那一部分,精簡(jiǎn)了代碼 floor=GoingDownToFloor(); //} if(GetPanelFloorLight(floor)) SetPanelFloorLight(floor,false); if(fabs(GetFloor()-floor)<Lib_FloorTolerance) { if(GetCallLight(floor,up)|GetCallLight(floor,!up))//樓層上下呼叫 { SetCallLight(floor,up,false);//滅燈 SetCallLight(floor,!up,false); } if(GetPanelFloorLight(floor)) SetPanelFloorLight(floor,false); SetMotorPower(0); SetDoor(floor,1); *state=DoorOpen; printf("Transition:frommovingdowntoDoorOpen.\n"); return; } else SetMotorPower(-1); }4.4版本一與版本二開門函數(shù)部分比較分析voidDooropen(int*state){ intfloor; floor=GetNearestFloor(); CancelTo1Floor(); if(GetCloseDoorLight())//有關(guān)門按鍵就關(guān)門 { SetDoor(floor,false); SetCloseDoorLight(false); *state=DoorClosing; return; } elseif(IsDoorOpen(floor)) //如果門是關(guān)閉的就進(jìn)去,返回門是否是打開的,true表示門是打開的,否則門是關(guān)閉的或者正在打開/關(guān)閉 { SetDoor(floor,false); *state=DoorClosing; return; } if(GetOpenDoorLight())//如果開門按鈕打開 { SetDoor(floor,true); SetOpenDoorLight(false); }}4.5版本一與版本二關(guān)門函數(shù)部分比較分析兩個(gè)版本幾乎一樣//關(guān)門函數(shù)的編寫voidDoorclosing(int*state){ intfloor; floor=GetNearestFloor();//判斷到最近的樓層 CancelTo1Floor(); if(GetCloseDoorLight()) //判斷關(guān)門 { SetCloseDoorLight(false); SetDoor(floor,false); } elseif(GetOpenDoorLight()) //判斷開門 { SetDoor(floor,true);//開門 SetOpenDoorLight(false); *state=DoorOpen; return; } elseif(IsDoorClosed(floor)) //判斷門是否開了 { *state=Idle; // printf("進(jìn)去了\n");//用來(lái)測(cè)試 return; }}4.6兩種版本的的評(píng)估及比較分析版本一:這個(gè)初期未完成任務(wù),而沒過于想太多,在運(yùn)行調(diào)試過程中能正確執(zhí)行,但是局限性比較
溫馨提示
- 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 木工承包合同協(xié)議書
- 二零二五年度智能硬件知識(shí)產(chǎn)權(quán)授權(quán)與保密合同
- 健身房整裝清包合同樣本
- 風(fēng)力發(fā)電葉片運(yùn)輸合同
- 二零二五年度辦公室門套定制與建筑節(jié)能改造合同
- 港口物流居間合同委托書
- 電子設(shè)備采購(gòu)合同
- 法院判決離婚協(xié)議書
- 醫(yī)療器械外包合同
- 設(shè)備維護(hù)管理作業(yè)指導(dǎo)書
- (2024年)肺栓塞的護(hù)理課件
- 小學(xué)數(shù)學(xué)三年級(jí)下冊(cè)第八單元《數(shù)學(xué)廣角-搭配(二)》大單元集體備課整體設(shè)計(jì)
- (高清版)TDT 1031.6-2011 土地復(fù)墾方案編制規(guī)程 第6部分:建設(shè)項(xiàng)目
- 2024年江蘇省高中學(xué)業(yè)水平測(cè)試生物試卷
- 露天采場(chǎng)危險(xiǎn)有害因素辨識(shí)
- 食品感官評(píng)價(jià)員培訓(xùn)方案
- 蘇教版一年級(jí)上、下冊(cè)勞動(dòng)與技術(shù)教案
- 柔性生產(chǎn)線技術(shù)及其影響
- 智研咨詢發(fā)布:2023年中國(guó)醫(yī)院后勤服務(wù)行業(yè)市場(chǎng)現(xiàn)狀、發(fā)展概況、未來(lái)前景分析報(bào)告
- 七上-動(dòng)點(diǎn)、動(dòng)角問題12道好題-解析
- 《企業(yè)所得稅法稅法》課件
評(píng)論
0/150
提交評(píng)論