PROCESS_STATE RoutineD( void ) { typedef enum { POWER_ON_A, WAIT_FOR_SENSOR3, POWER_OFF_A, OPEN_POINT1, OPEN_POINT2, OPEN_POINT3, POWER_ON_B, WAIT_FOR_SENSOR1, WAIT_FOR_TIMER, POWER_OFF_B, CLOSE_POINT1, CLOSE_POINT2, CLOSE_POINT3 } MOVEMENT_STATE; PROCESS_STATE ReturnStatus = In_Progress; static MOVEMENT_STATE MovementState = POWER_ON_A; switch ( MovementState ) { case POWER_ON_A : EnableMotorPower(); if ( TrainMotorHome( 800, 5 ) == Command_Complete ) { MovementState = WAIT_FOR_SENSOR3; } break; case WAIT_FOR_SENSOR3 : if ( TrainPresent( 3 ) == true ) { MovementState = POWER_OFF_A; } break; case POWER_OFF_A : if ( TrainMotorHome( 0, 5 ) == Command_Complete ) { DisableMotorPower(); MovementState = OPEN_POINT1; } break; case OPEN_POINT1 : if ( OpenPoint( 1 ) == Command_Complete ) { MovementState = OPEN_POINT2; } break; case OPEN_POINT2 : if ( OpenPoint( 2 ) == Command_Complete ) { MovementState = OPEN_POINT3; } break; case OPEN_POINT3 : if ( OpenPoint( 3 ) == Command_Complete ) { MovementState = POWER_ON_B; } break; case POWER_ON_B : EnableMotorPower(); if ( TrainMotorAway( 1023, 5 ) == Command_Complete ) { MovementState = WAIT_FOR_SENSOR1; } break; case WAIT_FOR_SENSOR1 : if ( TrainPresent( 1 ) == true ) { MovementState = WAIT_FOR_TIMER; Set_Timer(GENERIC, 0, 6, 0 ); } break; case WAIT_FOR_TIMER : if ( Check_Timer( GENERIC ) == MATURED ) { MovementState = POWER_OFF_B; } break; case POWER_OFF_B : if ( TrainMotorAway( 0, 5 ) == Command_Complete ) { DisableMotorPower(); MovementState = CLOSE_POINT1; } break; case CLOSE_POINT1 : if ( ClosePoint( 1 ) == Command_Complete ) { MovementState = CLOSE_POINT2; } break; case CLOSE_POINT2 : if ( ClosePoint( 2 ) == Command_Complete ) { MovementState = CLOSE_POINT3; } break; case CLOSE_POINT3 : if ( ClosePoint( 3 ) == Command_Complete ) { MovementState = POWER_ON_A; ReturnStatus = Command_Complete; } break; } return ReturnStatus; }
PROCESS_STATE TrainMotorAway( int speed, int AcDeceleration ) { static int Current_Backward_Speed = 0; int Steps = 0; PROCESS_STATE ReturnStatus = In_Progress; switch ( AcDeceleration ) { case 1: Steps = 100; break; case 2: Steps = 200; break; case 3: Steps = 300; break; case 4: Steps = 400; break; case 5: Steps = 500; break; } if ( Check_Timer( TRAIN_MOVEMENT ) == MATURED ) // Matured { if ( speed == Current_Backward_Speed ) { // putrsUSART( "Forward: Train at requested speed...\r\n" ); ReturnStatus = Command_Complete; } else if ( speed > Current_Backward_Speed ) { Current_Backward_Speed = Current_Backward_Speed + Steps; // putrsUSART( "Forward: +400\r\n" ); if ( Current_Backward_Speed > 1023) { // putrsUSART( "Forward: More than 1023 setting to 'speed'...\r\n" ); Current_Backward_Speed = speed; } SetDCPWM2( Current_Backward_Speed ); } else if ( speed < Current_Backward_Speed ) { Current_Backward_Speed = Current_Backward_Speed - Steps; // putrsUSART( "Forward: +400\r\n" ); if ( Current_Backward_Speed < speed ) { // putrsUSART( "Forward: less than 'speed' so setting to 'speed'...\r\n" ); Current_Backward_Speed = speed; } SetDCPWM2( Current_Backward_Speed ); } Set_Timer(TRAIN_MOVEMENT, 0, 1, 0 ); } return ReturnStatus; }
//=========================================================================== //=========================================================================== void TimeRun(TCGauge *CGauge, TPanel *aTimerPanel) { // -------------------------------------------------------------------------- // ---------- Тут нуно закрыть все предыдуще открытые окна вывода --------- // -------------------------------------------------------------------------- // ---------- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --------- // -------------------------------------------------------------------------- // ---- Очищаем входы, выходы всех элементов схемы --------- for (int i = 0; i < ElementList_Count; i++){ for (int k = 0; k < ElementList[i]->iPoints->Items_Count; k++) ElementList[i]->iPoints->Items[k]->ClearPoints(); for (int k = 0; k < ElementList[i]->oPoints->Items_Count; k++) ElementList[i]->oPoints->Items[k]->ClearPoints(); } // -- Инициализация элементов ----- for (int i = 0; i < ElementList_Count; i++) { // ----- Эт нада делать обязательно, потомучто если загружаем схему нада инициализировать указатели --- (мы их не пищем)--- ElementList[i]->pManagerParam = &ManagerParam; // --- ElementList[i]->pProjectParam = &ProjectParam; // --- ElementList[i]->pCurModelTime = &CurModelTime; // --- // ---- Собственно инициялизация элемента ------- // ---- ,а в точности она обязательна, кроме того чтобы сделать внутреннюю инициализацию - // ---- ,в ней нужно проставить размеры очередей ------ ElementList[i]->Init(); // --- Инициализация элемента --- } // ---- Нахожу максимальное значение порядка очередей данных элемента ----- int CurSystemOrder = 0; for (int i = 0; i < ElementList_Count; i++) if (CurSystemOrder < ElementList[i]->Order) CurSystemOrder = ElementList[i]->Order; // ---- Проставляю всем элементам значения наибольшего значения "глубины" очереди (порядка систмемы) ----- for (int i = 0; i < ElementList_Count; i++) ElementList[i]->Order = CurSystemOrder; // ---- Выставляю Новые входы, Выходы и родительские очереди --------- TElementPoint *iPoint = NULL; TElementPoint *oPoint = NULL; TElement *aSecondElement = NULL; TElement *aFirstElement = NULL; for (int i = 0; i < LinkList_Count; i++){ if (LinkList[i]->FirstElement != NULL && LinkList[i]->SecondElement != NULL){ aFirstElement = (TElement*)LinkList[i]->FirstElement; aSecondElement = (TElement*)LinkList[i]->SecondElement; iPoint = aSecondElement->iPoints->Items[LinkList[i]->NumberInput ]; // ---- Куда подсоединяеться линк ------ oPoint = aFirstElement ->oPoints->Items[LinkList[i]->NumberOutput]; // ---- Откуда выходит линк ------ // --------------------- Если второй элемент подсистема ----- if (aSecondElement->ClassName == "TSubSystem") { TSubSystem* ss = (TSubSystem*)LinkList[i]->SecondElement; aSecondElement = (TElement*)ss->InputList->Items[LinkList[i]->NumberInput]; iPoint = aSecondElement->iPoints->Items[0]; } // --------------------- Если первый элемент подсистема ----- if (aFirstElement->ClassName == "TSubSystem") { TSubSystem* ss = (TSubSystem*)LinkList[i]->FirstElement; oPoint = ((TElement*)ss->OutputList->Items[LinkList[i]->NumberOutput])->oPoints->Items[0]; } // --------------------- iPoint->Queue = oPoint->Queue; iPoint->AddElement(aFirstElement); oPoint->AddElement(aSecondElement); iPoint->EnableCalc = oPoint->EnableCalc; } } // ---- врутренняя инициализации перед просчетом ----- for (int i = 0; i < ElementList_Count; i++) { ElementList[i]->Recurse.CountIn = ElementList[i]->iPoints->Items_Count; ElementList[i]->Recurse.CountOut = ElementList[i]->oPoints->Items_Count; ElementList[i]->Recurse.State = rsBeginState; ElementList[i]->Recurse.inCalculateList = false; // --- !! И обязательно !! --- ElementList[i]->InitBeforeRun(); } // ------ Очищаю списки счета ---- CalculateList ->Clear(); InputList ->Clear(); int Level = 0; // --- ################# //afs = new TFileStream("123.123", fmCreate); // ------- Составляем очередь просчета ------- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ---- 2.0. Формируем список входных элементов ------- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// for (int i = 0; i < ElementList_Count; i++) if (ElementList[i]->iPoints->Items_Count == 0) if (ElementList[i]->ClassName != "TSubSystem" ) { //afs->Write(ElementList[i]->Caption.c_str() , ElementList[i]->Caption.Length()); //afs->Write("\n", 1); ElementRecurse(ElementList[i]); //afs->Write("\n", 1); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ---- 2.1. Формируем все остальныe элементы (Кроме суматоров и умножителей) ------- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// while (true) { MultiInputList->Clear(); OtherElements->Clear(); // ---- Формируем список элементов у которых много входов, и еще элемент не проинициализированный, и не суматор и умножитель ---- for (int i = 0; i < ElementList_Count; i++) if (ElementList[i]->Recurse.State != rsDone && ElementList[i]->ClassName != "TSubSystem" && ElementList[i]->ClassName != "TOutElementStandart" ) OtherElements->Add(ElementList[i]); // ----- Из созданого списка находим элементы, у которых осталось наиньшее количество незаполненых входных связей ----- Level = 1; while (true) { if (OtherElements->Count <= 0) break; // ---- ну тут и так понятно --- for (int i = 0; i < OtherElements->Count; i++) { TElement *el = (TElement*)OtherElements->Items[i]; //if (el->Recurse.CountIn == Level || el->Recurse.State != rsDone){ if (el->Recurse.CountIn == Level && el->Recurse.State != rsDone){ MultiInputList->Add(OtherElements->Items[i]); OtherElements->Items[i] = NULL; } } OtherElements->Pack(); Level++; } // ----- Продолжаем рекурсию ----------------- for (int i = 0; i < MultiInputList->Count; i++) if (((TElement*)MultiInputList->Items[i])->Recurse.State != rsDone) { //afs->Write(((TElement*)MultiInputList->Items[i])->Caption.c_str() , ((TElement*)MultiInputList->Items[i])->Caption.Length()); //afs->Write("\n", 1); ElementRecurse((TElement*)MultiInputList->Items[i]); //afs->Write("\n", 1); } // ------------ выход, если нет елементов на обработку ----------- if (MultiInputList->Count == 0) break; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////// Тупо добавляем выходы //////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// for (int i = 0; i < ElementList_Count; i++) if (ElementList[i]->ClassName == "TOutElementStandart" ) if (ElementList[i]->Recurse.State != rsDone ) CalculateList->Add(ElementList[i]); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ---------- УУУУУУУУрррррррраааааааа ПРОРЕКУРСИРОВАЛИ ---------- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// CGauge->MaxValue = ProjectParam.EndCalcTime / ProjectParam.AnalogT0; // ------ TElement **CalcElementList = NULL; TFloat RefreshTime = 0.0; TFloat StepRefreshTime = ProjectParam.EndCalcTime / 100.0; //TFloat StepRefreshTime = AnalogT0 * 1000; CurModelTime = 0; //RandSeed = 7098500758; try { // ------- CalcElementList = (TElement**) malloc (sizeof(TElement*)*CalculateList->Count); for (int i = 0; i < CalculateList->Count; i++) CalcElementList[i] = (TElement*)CalculateList->Items[i]; // ------- // --- ############# /*afs->Write("\n" , 1); afs->Write("\n" , 1); for (int i = 0; i < CalculateList->Count; i++) { TElement *el = FindElementByID(CalcElementList[i]->ParentId); afs->Write("( " , 2); afs->Write(el->Caption.c_str() , el->Caption.Length()); afs->Write(" )" , 2); afs->Write(CalcElementList[i]->Caption.c_str() , CalcElementList[i]->Caption.Length()); afs->Write("\n" , 1); } delete afs; */ // --- ############# while (!Stoped && CurModelTime <= ProjectParam.EndCalcTime) { // ---- if (!Paused) { for (int i = 0; i < CalculateList->Count; i++) CalcElementList[i]->Run(); CurModelTime += ProjectParam.AnalogT0; if (CurModelTime >= RefreshTime) { RefreshTime += StepRefreshTime; CGauge->Progress = CurModelTime / ProjectParam.AnalogT0; Set_Timer(aTimerPanel); Application->ProcessMessages(); } } else Application->ProcessMessages(); // ---- } // ---- Завершаем - кому нада счет ---- for (int i = 0; i < CalculateList->Count; i++) CalcElementList[i]->DoneRun(); } __finally { free (CalcElementList); } }