123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489 |
- /// \file DecisionMaker.cpp
- /// \brief Initialize behaviors state machine, and calculate required parameters for the state machine transition conditions
- /// \author Hatem Darweesh
- /// \date Dec 14, 2016
- #include "op_planner/DecisionMaker.h"
- #include "op_utility/UtilityH.h"
- #include "op_planner/PlanningHelpers.h"
- #include "op_planner/MappingHelpers.h"
- #include "op_planner/MatrixOperations.h"
- namespace PlannerHNS
- {
- DecisionMaker::DecisionMaker()
- {
- m_iCurrentTotalPathId = 0;
- pLane = 0;
- m_pCurrentBehaviorState = 0;
- m_pGoToGoalState = 0;
- m_pStopState= 0;
- m_pWaitState= 0;
- m_pMissionCompleteState= 0;
- m_pAvoidObstacleState = 0;
- m_pTrafficLightStopState = 0;
- m_pTrafficLightWaitState = 0;
- m_pStopSignStopState = 0;
- m_pStopSignWaitState = 0;
- m_pFollowState = 0;
- m_MaxLaneSearchDistance = 3.0;
- m_pStopState = 0;
- m_pMissionCompleteState = 0;
- m_pGoalState = 0;
- m_pGoToGoalState = 0;
- m_pWaitState = 0;
- m_pInitState = 0;
- m_pFollowState = 0;
- m_pAvoidObstacleState = 0;
- }
- DecisionMaker::~DecisionMaker()
- {
- delete m_pStopState;
- delete m_pMissionCompleteState;
- delete m_pGoalState;
- delete m_pGoToGoalState;
- delete m_pWaitState;
- delete m_pInitState;
- delete m_pFollowState;
- delete m_pAvoidObstacleState;
- delete m_pTrafficLightStopState;
- delete m_pTrafficLightWaitState;
- delete m_pStopSignWaitState;
- delete m_pStopSignStopState;
- }
- void DecisionMaker::Init(const ControllerParams& ctrlParams, const PlannerHNS::PlanningParams& params,const CAR_BASIC_INFO& carInfo)
- {
- m_CarInfo = carInfo;
- m_ControlParams = ctrlParams;
- m_params = params;
- m_pidVelocity.Init(0.01, 0.004, 0.01);
- m_pidVelocity.Setlimit(m_params.maxSpeed, 0);
- m_pidStopping.Init(0.05, 0.05, 0.1);
- m_pidStopping.Setlimit(m_params.horizonDistance, 0);
- m_pidFollowing.Init(0.05, 0.05, 0.01);
- m_pidFollowing.Setlimit(m_params.minFollowingDistance, 0);
- InitBehaviorStates();
- if(m_pCurrentBehaviorState)
- m_pCurrentBehaviorState->SetBehaviorsParams(&m_params);
- }
- void DecisionMaker::InitBehaviorStates()
- {
- m_pStopState = new StopState(&m_params, 0, 0);
- m_pMissionCompleteState = new MissionAccomplishedStateII(m_pStopState->m_pParams, m_pStopState->GetCalcParams(), 0);
- m_pGoalState = new GoalStateII(m_pStopState->m_pParams, m_pStopState->GetCalcParams(), m_pMissionCompleteState);
- m_pGoToGoalState = new ForwardStateII(m_pStopState->m_pParams, m_pStopState->GetCalcParams(), m_pGoalState);
- m_pInitState = new InitStateII(m_pStopState->m_pParams, m_pStopState->GetCalcParams(), m_pGoToGoalState);
- m_pFollowState = new FollowStateII(m_pStopState->m_pParams, m_pStopState->GetCalcParams(), m_pGoToGoalState);
- m_pAvoidObstacleState = new SwerveStateII(m_pStopState->m_pParams, m_pStopState->GetCalcParams(), m_pGoToGoalState);
- m_pStopSignWaitState = new StopSignWaitStateII(m_pStopState->m_pParams, m_pStopState->GetCalcParams(), m_pGoToGoalState);
- m_pStopSignStopState = new StopSignStopStateII(m_pStopState->m_pParams, m_pStopState->GetCalcParams(), m_pStopSignWaitState);
- m_pTrafficLightWaitState = new TrafficLightWaitStateII(m_pStopState->m_pParams, m_pStopState->GetCalcParams(), m_pGoToGoalState);
- m_pTrafficLightStopState = new TrafficLightStopStateII(m_pStopState->m_pParams, m_pStopState->GetCalcParams(), m_pGoToGoalState);
- m_pGoToGoalState->InsertNextState(m_pAvoidObstacleState);
- m_pGoToGoalState->InsertNextState(m_pStopSignStopState);
- m_pGoToGoalState->InsertNextState(m_pTrafficLightStopState);
- m_pGoToGoalState->InsertNextState(m_pFollowState);
- m_pGoToGoalState->decisionMakingCount = 0;//m_params.nReliableCount;
- m_pGoalState->InsertNextState(m_pGoToGoalState);
- m_pStopSignWaitState->decisionMakingTime = m_params.stopSignStopTime;
- m_pStopSignWaitState->InsertNextState(m_pStopSignStopState);
- m_pStopSignWaitState->InsertNextState(m_pGoalState);
- m_pTrafficLightStopState->InsertNextState(m_pTrafficLightWaitState);
- m_pTrafficLightWaitState->InsertNextState(m_pTrafficLightStopState);
- m_pTrafficLightWaitState->InsertNextState(m_pGoalState);
- m_pFollowState->InsertNextState(m_pAvoidObstacleState);
- m_pFollowState->InsertNextState(m_pStopSignStopState);
- m_pFollowState->InsertNextState(m_pTrafficLightStopState);
- m_pFollowState->InsertNextState(m_pGoalState);
- m_pFollowState->decisionMakingCount = 0;//m_params.nReliableCount;
- m_pInitState->decisionMakingCount = 0;//m_params.nReliableCount;
- m_pCurrentBehaviorState = m_pInitState;
- }
- bool DecisionMaker::GetNextTrafficLight(const int& prevTrafficLightId, const std::vector<PlannerHNS::TrafficLight>& trafficLights, PlannerHNS::TrafficLight& trafficL)
- {
- for(unsigned int i = 0; i < trafficLights.size(); i++)
- {
- double d = hypot(trafficLights.at(i).pos.y - state.pos.y, trafficLights.at(i).pos.x - state.pos.x);
- if(d <= trafficLights.at(i).stoppingDistance)
- {
- double a_diff = UtilityHNS::UtilityH::AngleBetweenTwoAnglesPositive(UtilityHNS::UtilityH::FixNegativeAngle(trafficLights.at(i).pos.a) , UtilityHNS::UtilityH::FixNegativeAngle(state.pos.a));
- if(a_diff < M_PI_2 && trafficLights.at(i).id != prevTrafficLightId)
- {
- //std::cout << "Detected Light, ID = " << trafficLights.at(i).id << ", Distance = " << d << ", Angle = " << trafficLights.at(i).pos.a*RAD2DEG << ", Car Heading = " << state.pos.a*RAD2DEG << ", Diff = " << a_diff*RAD2DEG << std::endl;
- trafficL = trafficLights.at(i);
- return true;
- }
- }
- }
- return false;
- }
- void DecisionMaker::CalculateImportantParameterForDecisionMaking(const PlannerHNS::VehicleState& car_state,
- const int& goalID, const bool& bEmergencyStop, const std::vector<TrafficLight>& detectedLights,
- const TrajectoryCost& bestTrajectory)
- {
- if(m_TotalPath.size() == 0) return;
- PreCalculatedConditions* pValues = m_pCurrentBehaviorState->GetCalcParams();
- if(m_CarInfo.max_deceleration != 0)
- pValues->minStoppingDistance = -pow(car_state.speed, 2)/(m_CarInfo.max_deceleration);
- pValues->iCentralTrajectory = m_pCurrentBehaviorState->m_pParams->rollOutNumber/2;
- if(pValues->iPrevSafeTrajectory < 0)
- pValues->iPrevSafeTrajectory = pValues->iCentralTrajectory;
- pValues->stoppingDistances.clear();
- pValues->currentVelocity = car_state.speed;
- pValues->bTrafficIsRed = false;
- pValues->currentTrafficLightID = -1;
- pValues->bFullyBlock = false;
- pValues->distanceToNext = bestTrajectory.closest_obj_distance;
- pValues->velocityOfNext = bestTrajectory.closest_obj_velocity;
- if(bestTrajectory.index >=0 && bestTrajectory.index < (int)m_RollOuts.size())
- pValues->iCurrSafeTrajectory = bestTrajectory.index;
- else
- pValues->iCurrSafeTrajectory = pValues->iCentralTrajectory;
- pValues->bFullyBlock = bestTrajectory.bBlocked;
- if(bestTrajectory.lane_index >=0)
- pValues->iCurrSafeLane = bestTrajectory.lane_index;
- else
- {
- PlannerHNS::RelativeInfo info;
- PlannerHNS::PlanningHelpers::GetRelativeInfoRange(m_TotalPath, state, m_params.rollOutDensity*m_params.rollOutNumber/2.0 + 0.1, info);
- pValues->iCurrSafeLane = info.iGlobalPath;
- }
- double critical_long_front_distance = m_CarInfo.wheel_base/2.0 + m_CarInfo.length/2.0 + m_params.verticalSafetyDistance;
- if(ReachEndOfGlobalPath(pValues->minStoppingDistance + critical_long_front_distance, pValues->iCurrSafeLane))
- pValues->currentGoalID = -1;
- else
- pValues->currentGoalID = goalID;
- m_iCurrentTotalPathId = pValues->iCurrSafeLane;
- int stopLineID = -1;
- int stopSignID = -1;
- int trafficLightID = -1;
- double distanceToClosestStopLine = 0;
- bool bGreenTrafficLight = true;
- distanceToClosestStopLine = PlanningHelpers::GetDistanceToClosestStopLineAndCheck(m_TotalPath.at(pValues->iCurrSafeLane), state, m_params.giveUpDistance, stopLineID, stopSignID, trafficLightID) - critical_long_front_distance;
- //std::cout << "StopLineID" << stopLineID << ", StopSignID: " << stopSignID << ", TrafficLightID: " << trafficLightID << ", Distance: " << distanceToClosestStopLine << ", MinStopDistance: " << pValues->minStoppingDistance << std::endl;
- if(distanceToClosestStopLine > m_params.giveUpDistance && distanceToClosestStopLine < (pValues->minStoppingDistance + 1.0))
- {
- if(m_pCurrentBehaviorState->m_pParams->enableTrafficLightBehavior)
- {
- pValues->currentTrafficLightID = trafficLightID;
- //std::cout << "Detected Traffic Light: " << trafficLightID << std::endl;
- for(unsigned int i=0; i< detectedLights.size(); i++)
- {
- if(detectedLights.at(i).id == trafficLightID)
- bGreenTrafficLight = (detectedLights.at(i).lightState == GREEN_LIGHT);
- }
- }
- if(m_pCurrentBehaviorState->m_pParams->enableStopSignBehavior)
- pValues->currentStopSignID = stopSignID;
- pValues->stoppingDistances.push_back(distanceToClosestStopLine);
- //std::cout << "LP => D: " << pValues->distanceToStop() << ", PrevSignID: " << pValues->prevTrafficLightID << ", CurrSignID: " << pValues->currentTrafficLightID << ", Green: " << bGreenTrafficLight << endl;
- }
- //std::cout << "Distance To Closest: " << distanceToClosestStopLine << ", Stop LineID: " << stopLineID << ", Stop SignID: " << stopSignID << ", TFID: " << trafficLightID << std::endl;
- pValues->bTrafficIsRed = !bGreenTrafficLight;
- if(bEmergencyStop)
- {
- pValues->bFullyBlock = true;
- pValues->distanceToNext = 1;
- pValues->velocityOfNext = 0;
- }
- //cout << "Distances: " << pValues->stoppingDistances.size() << ", Distance To Stop : " << pValues->distanceToStop << endl;
- }
- void DecisionMaker::UpdateCurrentLane(const double& search_distance)
- {
- PlannerHNS::Lane* pMapLane = 0;
- PlannerHNS::Lane* pPathLane = 0;
- pPathLane = MappingHelpers::GetLaneFromPath(state, m_TotalPath.at(m_iCurrentTotalPathId));
- if(!pPathLane)
- {
- std::cout << "Performance Alert: Can't Find Lane Information in Global Path, Searching the Map :( " << std::endl;
- pMapLane = MappingHelpers::GetClosestLaneFromMap(state, m_Map, search_distance);
- }
- if(pPathLane)
- pLane = pPathLane;
- else if(pMapLane)
- pLane = pMapLane;
- else
- pLane = 0;
- }
- bool DecisionMaker::ReachEndOfGlobalPath(const double& min_distance, const int& iGlobalPathIndex)
- {
- if(m_TotalPath.size()==0) return false;
- PlannerHNS::RelativeInfo info;
- PlanningHelpers::GetRelativeInfo(m_TotalPath.at(iGlobalPathIndex), state, info);
- double d = 0;
- for(unsigned int i = info.iFront; i < m_TotalPath.at(iGlobalPathIndex).size()-1; i++)
- {
- d+= hypot(m_TotalPath.at(iGlobalPathIndex).at(i+1).pos.y - m_TotalPath.at(iGlobalPathIndex).at(i).pos.y, m_TotalPath.at(iGlobalPathIndex).at(i+1).pos.x - m_TotalPath.at(iGlobalPathIndex).at(i).pos.x);
- if(d > min_distance)
- return false;
- }
- return true;
- }
- void DecisionMaker::SetNewGlobalPath(const std::vector<std::vector<WayPoint> >& globalPath)
- {
- if(m_pCurrentBehaviorState)
- {
- m_pCurrentBehaviorState->GetCalcParams()->bNewGlobalPath = true;
- m_TotalOriginalPath = globalPath;
- }
- }
- bool DecisionMaker::SelectSafeTrajectory()
- {
- bool bNewTrajectory = false;
- PlannerHNS::PreCalculatedConditions *preCalcPrams = m_pCurrentBehaviorState->GetCalcParams();
- if(!preCalcPrams || m_RollOuts.size() == 0) return bNewTrajectory;
- int currIndex = PlannerHNS::PlanningHelpers::GetClosestNextPointIndexFast(m_Path, state);
- int index_limit = 0;
- if(index_limit<=0)
- index_limit = m_Path.size()/2.0;
- if(currIndex > index_limit
- || preCalcPrams->bRePlan
- || preCalcPrams->bNewGlobalPath)
- {
- std::cout << "New Local Plan !! " << currIndex << ", "<< preCalcPrams->bRePlan << ", " << preCalcPrams->bNewGlobalPath << ", " << m_TotalOriginalPath.at(0).size() << ", PrevLocal: " << m_Path.size();
- m_Path = m_RollOuts.at(preCalcPrams->iCurrSafeTrajectory);
- std::cout << ", NewLocal: " << m_Path.size() << std::endl;
- preCalcPrams->bNewGlobalPath = false;
- preCalcPrams->bRePlan = false;
- bNewTrajectory = true;
- }
- return bNewTrajectory;
- }
- PlannerHNS::BehaviorState DecisionMaker::GenerateBehaviorState(const PlannerHNS::VehicleState& vehicleState)
- {
- PlannerHNS::PreCalculatedConditions *preCalcPrams = m_pCurrentBehaviorState->GetCalcParams();
- m_pCurrentBehaviorState = m_pCurrentBehaviorState->GetNextState();
- if(m_pCurrentBehaviorState==0)
- m_pCurrentBehaviorState = m_pInitState;
- PlannerHNS::BehaviorState currentBehavior;
- currentBehavior.state = m_pCurrentBehaviorState->m_Behavior;
- currentBehavior.followDistance = preCalcPrams->distanceToNext;
- currentBehavior.minVelocity = 0;
- currentBehavior.stopDistance = preCalcPrams->distanceToStop();
- currentBehavior.followVelocity = preCalcPrams->velocityOfNext;
- if(preCalcPrams->iPrevSafeTrajectory<0 || preCalcPrams->iPrevSafeTrajectory >= m_RollOuts.size())
- currentBehavior.iTrajectory = preCalcPrams->iCurrSafeTrajectory;
- else
- currentBehavior.iTrajectory = preCalcPrams->iPrevSafeTrajectory;
- double average_braking_distance = -pow(vehicleState.speed, 2)/(m_CarInfo.max_deceleration) + m_params.additionalBrakingDistance;
- if(average_braking_distance < m_params.minIndicationDistance)
- average_braking_distance = m_params.minIndicationDistance;
- currentBehavior.indicator = PlanningHelpers::GetIndicatorsFromPath(m_Path, state, average_braking_distance );
- return currentBehavior;
- }
- double DecisionMaker::UpdateVelocityDirectlyToTrajectory(const BehaviorState& beh, const VehicleState& CurrStatus, const double& dt)
- {
- if(m_TotalOriginalPath.size() ==0 ) return 0;
- RelativeInfo info, total_info;
- PlanningHelpers::GetRelativeInfo(m_TotalOriginalPath.at(m_iCurrentTotalPathId), state, total_info);
- PlanningHelpers::GetRelativeInfo(m_Path, state, info);
- double average_braking_distance = -pow(CurrStatus.speed, 2)/(m_CarInfo.max_deceleration) + m_params.additionalBrakingDistance;
- double max_velocity = PlannerHNS::PlanningHelpers::GetVelocityAhead(m_TotalOriginalPath.at(m_iCurrentTotalPathId), total_info, total_info.iBack, average_braking_distance);
- unsigned int point_index = 0;
- double critical_long_front_distance = m_CarInfo.length/2.0;
- if(beh.state == TRAFFIC_LIGHT_STOP_STATE || beh.state == STOP_SIGN_STOP_STATE)
- {
- PlanningHelpers::GetFollowPointOnTrajectory(m_Path, info, beh.stopDistance - critical_long_front_distance, point_index);
- double e = -beh.stopDistance;
- double desiredVelocity = m_pidStopping.getPID(e);
- // std::cout << "Stopping : e=" << e << ", desiredPID=" << desiredVelocity << ", PID: " << m_pidStopping.ToString() << std::endl;
- if(desiredVelocity > max_velocity)
- desiredVelocity = max_velocity;
- else if(desiredVelocity < m_params.minSpeed)
- desiredVelocity = 0;
- for(unsigned int i = 0; i < m_Path.size(); i++)
- m_Path.at(i).v = desiredVelocity;
- return desiredVelocity;
- }
- else if(beh.state == FOLLOW_STATE)
- {
- double deceleration_critical = 0;
- double inv_time = 2.0*((beh.followDistance- (critical_long_front_distance+m_params.additionalBrakingDistance))-CurrStatus.speed);
- if(inv_time <= 0)
- deceleration_critical = m_CarInfo.max_deceleration;
- else
- deceleration_critical = CurrStatus.speed*CurrStatus.speed/inv_time;
- if(deceleration_critical > 0) deceleration_critical = -deceleration_critical;
- if(deceleration_critical < - m_CarInfo.max_acceleration) deceleration_critical = - m_CarInfo.max_acceleration;
- double desiredVelocity = (deceleration_critical * dt) + CurrStatus.speed;
- if(desiredVelocity > m_params.maxSpeed)
- desiredVelocity = m_params.maxSpeed;
- if((desiredVelocity < 0.1 && desiredVelocity > -0.1) || beh.followDistance <= 0) //use only effective velocities
- desiredVelocity = 0;
- //std::cout << "Acc: V: " << desiredVelocity << ", Accel: " << deceleration_critical<< std::endl;
- for(unsigned int i = 0; i < m_Path.size(); i++)
- m_Path.at(i).v = desiredVelocity;
- return desiredVelocity;
- }
- else if(beh.state == FORWARD_STATE || beh.state == OBSTACLE_AVOIDANCE_STATE )
- {
- double target_velocity = max_velocity;
- bool bSlowBecauseChange=false;
- if(m_pCurrentBehaviorState->GetCalcParams()->iCurrSafeTrajectory != m_pCurrentBehaviorState->GetCalcParams()->iCentralTrajectory)
- {
- target_velocity*=0.5;
- bSlowBecauseChange = true;
- }
- double e = target_velocity - CurrStatus.speed;
- double desiredVelocity = m_pidVelocity.getPID(e);
- if(desiredVelocity>max_velocity)
- desiredVelocity = max_velocity;
- else if(desiredVelocity < m_params.minSpeed)
- desiredVelocity = 0;
- for(unsigned int i = 0; i < m_Path.size(); i++)
- m_Path.at(i).v = desiredVelocity;
- //std::cout << "Target Velocity: " << desiredVelocity << ", Change Slowdown: " << bSlowBecauseChange << std::endl;
- return desiredVelocity;
- }
- else if(beh.state == STOP_SIGN_WAIT_STATE || beh.state == TRAFFIC_LIGHT_WAIT_STATE)
- {
- double target_velocity = 0;
- for(unsigned int i = 0; i < m_Path.size(); i++)
- m_Path.at(i).v = target_velocity;
- return target_velocity;
- }
- else
- {
- double target_velocity = 0;
- for(unsigned int i = 0; i < m_Path.size(); i++)
- m_Path.at(i).v = target_velocity;
- return target_velocity;
- }
- return max_velocity;
- }
- PlannerHNS::BehaviorState DecisionMaker::DoOneStep(
- const double& dt,
- const PlannerHNS::WayPoint currPose,
- const PlannerHNS::VehicleState& vehicleState,
- const int& goalID,
- const std::vector<TrafficLight>& trafficLight,
- const TrajectoryCost& tc,
- const bool& bEmergencyStop)
- {
- PlannerHNS::BehaviorState beh;
- state = currPose;
- m_TotalPath.clear();
- for(unsigned int i = 0; i < m_TotalOriginalPath.size(); i++)
- {
- t_centerTrajectorySmoothed.clear();
- PlannerHNS::PlanningHelpers::ExtractPartFromPointToDistanceDirectionFast(m_TotalOriginalPath.at(i), state, m_params.horizonDistance , m_params.pathDensity , t_centerTrajectorySmoothed);
- m_TotalPath.push_back(t_centerTrajectorySmoothed);
- }
- if(m_TotalPath.size()==0) return beh;
- UpdateCurrentLane(m_MaxLaneSearchDistance);
- CalculateImportantParameterForDecisionMaking(vehicleState, goalID, bEmergencyStop, trafficLight, tc);
- beh = GenerateBehaviorState(vehicleState);
- beh.bNewPlan = SelectSafeTrajectory();
- beh.maxVelocity = UpdateVelocityDirectlyToTrajectory(beh, vehicleState, dt);
- //std::cout << "Eval_i: " << tc.index << ", Curr_i: " << m_pCurrentBehaviorState->GetCalcParams()->iCurrSafeTrajectory << ", Prev_i: " << m_pCurrentBehaviorState->GetCalcParams()->iPrevSafeTrajectory << std::endl;
- return beh;
- }
- } /* namespace PlannerHNS */
|