// // Created by zx on 2020/7/7. // #include #include #include "dispatch_communicator.h" #include "StoreProcessTask.h" #include "process_message.pb.h" #include "command_manager.h" #include "system_communicator.h" StoreProcessTask::StoreProcessTask(unsigned int terminor_id) :m_publish_statu_thread(nullptr) { m_command_id=-1; m_terminor_id=terminor_id; message::Base_info base_info; base_info.set_msg_type(message::eStoring_process_statu_msg); base_info.set_sender(message::eMain); base_info.set_receiver(message::eEmpty); m_storing_process_statu_msg.mutable_base_info()->CopyFrom(base_info); m_storing_process_statu_msg.set_terminal_id(terminor_id); reset_process_statu(); } StoreProcessTask::~StoreProcessTask() { //退出线程 m_publish_exit_condition.set_pass_ever(true); if(m_publish_statu_thread!= nullptr) { if(m_publish_statu_thread->joinable()) { m_publish_statu_thread->join(); } delete m_publish_statu_thread; m_publish_statu_thread=nullptr; } } Error_manager StoreProcessTask::init_task( unsigned int command_id, message::Locate_information locate_info,message::Car_info car_info) { m_command_id=command_id; m_car_info=car_info; m_locate_info=locate_info; ///创建状态发布线程 if(m_publish_statu_thread== nullptr) { m_publish_exit_condition.reset(false, false, false); m_publish_statu_thread=new std::thread(publish_thread_func,this); } if(is_ready()) { return SUCCESS; } else { return Error_manager(ERROR,MINOR_ERROR,"终端未准备!!!"); } } Error_manager StoreProcessTask::locate_step() { Error_manager code; //检查测量模块状态 code=Locate_communicator::get_instance_pointer()->check_statu(); if(code!=SUCCESS) return code; message::Measure_request_msg request; message::Base_info base_info; base_info.set_msg_type(message::eLocate_request_msg); base_info.set_sender(message::eMain); base_info.set_receiver(message::eMeasurer); base_info.set_timeout_ms(20000); //测量超时5s request.mutable_base_info()->CopyFrom(base_info); request.set_command_id(m_command_id); request.set_terminal_id(m_terminor_id); code=Locate_communicator::get_instance_pointer()->locate_request(request,m_measure_response_msg); if(code!=SUCCESS) return code; if(m_measure_response_msg.error_manager().error_code()==0) { return SUCCESS; } else return Error_manager(FAILED,MINOR_ERROR,m_measure_response_msg.error_manager().error_description().c_str()); } /* * 调度 */ Error_manager StoreProcessTask::dispatch_step() { Error_manager code; /* * 判断调度所需的数据是否都正常 */ //1,测量信息是否存在 if(m_measure_response_msg.has_base_info()== false ||m_measure_response_msg.has_locate_information()==false ||m_parcspace_alloc_response_msg.has_base_info()== false ||m_parcspace_alloc_response_msg.has_allocated_space_info()==false) { return Error_manager(ERROR,MAJOR_ERROR,"调度所需的前置数据(测量,车位)不存在"); } //2,判断调度节点状态 code=Dispatch_communicator::get_instance_pointer()->check_statu(); if(code!=SUCCESS) return code; message::Dispatch_request_msg request; message::Base_info base_info; base_info.set_msg_type(message::eDispatch_request_msg); base_info.set_sender(message::eMain); base_info.set_receiver(message::eDispatch); base_info.set_timeout_ms(1000*15); //测量超时15s request.mutable_base_info()->CopyFrom(base_info); request.set_command_id(m_command_id); request.set_terminal_id(m_terminor_id); request.set_dispatch_motion_direction(message::E_STORE_CAR); request.set_parkspace_id(m_parcspace_alloc_response_msg.allocated_space_info().parkspace_id()); code=Dispatch_communicator::get_instance_pointer()->dispatch_request(request,m_dispatch_response_msg); if(code!=SUCCESS) return code; if(m_dispatch_response_msg.error_manager().error_code()==0) { return SUCCESS; } else return Error_manager(FAILED,MINOR_ERROR,"dispatch response error_code error"); } /* * reset 进度信息 */ void StoreProcessTask::reset_process_statu() { message::Alloc_space_step_statu alloc_step; alloc_step.set_step_statu(message::eWaiting); message::Measure_step_statu measure_step; measure_step.set_step_statu(message::eWaiting); message::Dispatch_store_step_statu store_step; store_step.set_step_statu(message::eWaiting); message::Confirm_space_step_statu confirm_step; confirm_step.set_step_statu(message::eWaiting); message::Release_space_step_statu release_step; release_step.set_step_statu(message::eWaiting); m_storing_process_statu_msg.mutable_alloc_space_step()->CopyFrom(alloc_step); m_storing_process_statu_msg.mutable_measure_step()->CopyFrom(measure_step); m_storing_process_statu_msg.mutable_dispatch_step()->CopyFrom(store_step); m_storing_process_statu_msg.mutable_confirm_space_step()->CopyFrom(confirm_step); m_storing_process_statu_msg.mutable_failed_release_space_step()->CopyFrom(release_step); } /* * 检查当前任务是否处于空闲准备状态 */ bool StoreProcessTask::is_ready() { bool cond_alloc_space = m_storing_process_statu_msg.alloc_space_step().step_statu()==message::eWaiting ||m_storing_process_statu_msg.alloc_space_step().step_statu()==message::eComplete; bool cond_measure = m_storing_process_statu_msg.measure_step().step_statu()==message::eWaiting ||m_storing_process_statu_msg.measure_step().step_statu()==message::eComplete; bool cond_dispatch = m_storing_process_statu_msg.dispatch_step().step_statu()==message::eWaiting ||m_storing_process_statu_msg.dispatch_step().step_statu()==message::eComplete; bool cond_confirm_space = m_storing_process_statu_msg.confirm_space_step().step_statu()==message::eWaiting ||m_storing_process_statu_msg.confirm_space_step().step_statu()==message::eComplete; bool cond_release_space = m_storing_process_statu_msg.failed_release_space_step().step_statu()==message::eWaiting ||m_storing_process_statu_msg.failed_release_space_step().step_statu()==message::eComplete; return cond_alloc_space && cond_measure && cond_dispatch && cond_confirm_space && cond_release_space; } /* * 分配车位 */ Error_manager StoreProcessTask::alloc_space() { //更新车位分配步骤状态 m_storing_process_statu_msg.mutable_alloc_space_step()->mutable_car_info()->CopyFrom(m_locate_info); m_storing_process_statu_msg.mutable_alloc_space_step()->set_step_statu(message::eWorking); /* * 检查是否有测量数据 */ if(m_locate_info.has_locate_height()==false||m_locate_info.has_locate_width()==false) { m_storing_process_statu_msg.mutable_alloc_space_step()->set_step_statu(message::eError); m_storing_process_statu_msg.mutable_alloc_space_step()->set_description("停车请求缺少车辆高度和宽度信息"); return Error_manager(FAILED,MINOR_ERROR,"停车请求缺少车辆高度和宽度信息"); } /* * 检查车位管理模块是否正常 */ Error_manager code=Parkspace_communicator::get_instance_pointer()->check_statu(); if(code!=SUCCESS) { m_storing_process_statu_msg.mutable_alloc_space_step()->set_step_statu(message::eError); m_storing_process_statu_msg.mutable_alloc_space_step()->set_description(code.get_error_description()); return code; } //发送分配请求 message::Parkspace_allocation_request_msg request; message::Base_info base_info; base_info.set_msg_type(message::eParkspace_allocation_request_msg); base_info.set_sender(message::eMain); base_info.set_receiver(message::eParkspace); base_info.set_timeout_ms(1000); //测量超时1s request.mutable_base_info()->CopyFrom(base_info); request.mutable_car_info()->CopyFrom(m_car_info); request.set_command_id(m_command_id); request.set_terminal_id(m_terminor_id); code=Parkspace_communicator::get_instance_pointer()->alloc_request(request,m_parcspace_alloc_response_msg); if(code!=SUCCESS) { m_storing_process_statu_msg.mutable_alloc_space_step()->set_step_statu(message::eError); m_storing_process_statu_msg.mutable_alloc_space_step()->set_description(code.get_error_description()); return code; } if(m_parcspace_alloc_response_msg.error_manager().error_code()==0) { m_storing_process_statu_msg.mutable_alloc_space_step()->set_step_statu(message::eComplete); return SUCCESS; } else { m_storing_process_statu_msg.mutable_alloc_space_step()->set_step_statu(message::eError); m_storing_process_statu_msg.mutable_alloc_space_step()->set_description("分配车位反馈结果错误"); return Error_manager(FAILED,MINOR_ERROR,"分配车位反馈结果错误"); } } /* * 车位占用确认 */ Error_manager StoreProcessTask::confirm_space_step() { /* * 检查是否曾经分配过车位 */ if(m_parcspace_alloc_response_msg.has_allocated_space_info()==false) { return Error_manager(FAILED,MINOR_ERROR," parkspace confirm request without space info"); } /* * 检查车位管理模块是否正常 */ Error_manager code=Parkspace_communicator::get_instance_pointer()->check_statu(); if(code!=SUCCESS) return code; message::Parkspace_confirm_alloc_request_msg request; message::Base_info base_info; base_info.set_msg_type(message::eParkspace_confirm_alloc_request_msg); base_info.set_sender(message::eMain); base_info.set_receiver(message::eParkspace); base_info.set_timeout_ms(1000); //测量超时1s request.mutable_base_info()->CopyFrom(base_info); message::Parkspace_info space_info=m_parcspace_alloc_response_msg.allocated_space_info(); request.mutable_confirm_space_info()->CopyFrom(space_info); request.set_command_id(m_command_id); message::Parkspace_confirm_alloc_response_msg confirm_response; code=Parkspace_communicator::get_instance_pointer()->confirm_request(request,confirm_response); if(code!=SUCCESS) return code; if(m_parcspace_alloc_response_msg.allocated_space_info().parkspace_id()!= confirm_response.confirm_alloc_space_info().parkspace_id()) { return Error_manager(ERROR,MINOR_ERROR,"占用车位与分配车位不一致"); } if(confirm_response.error_manager().error_code()==0) { LOG(INFO)<<"停车流程正常,确认占用车位成功,停车终端:"<check_statu(); if(code!=SUCCESS) return code; message::Parkspace_release_request_msg request; message::Base_info base_info; base_info.set_msg_type(message::eParkspace_release_request_msg); base_info.set_sender(message::eMain); base_info.set_receiver(message::eParkspace); base_info.set_timeout_ms(1000); //测量超时1s request.mutable_base_info()->CopyFrom(base_info); message::Parkspace_info space_info=m_parcspace_alloc_response_msg.allocated_space_info(); request.mutable_release_space_info()->CopyFrom(space_info); request.set_command_id(m_command_id); message::Parkspace_release_response_msg release_response; code=Parkspace_communicator::get_instance_pointer()->release_request(request,release_response); if(code!=SUCCESS) return code; if(release_response.error_manager().error_code()==0) { LOG(WARNING)<<"停车流程异常,释放车位成功,停车终端:"<set_step_statu(message::eWorking); //开始定位 code=locate_step(); if(code!=SUCCESS) { m_storing_process_statu_msg.mutable_measure_step()->set_step_statu(message::eError); m_storing_process_statu_msg.mutable_measure_step()->set_description(code.get_error_description()); LOG(ERROR)<<"测量失败:"<mutable_locate_info()->CopyFrom(m_measure_response_msg.locate_information()); m_storing_process_statu_msg.mutable_measure_step()->set_step_statu(message::eComplete); } //第二步,调度 case 1: { //更新状态信息 m_storing_process_statu_msg.mutable_dispatch_step()->set_step_statu(message::eWorking); m_storing_process_statu_msg.mutable_dispatch_step()->mutable_locate_info()->CopyFrom(m_measure_response_msg.locate_information()); m_storing_process_statu_msg.mutable_dispatch_step()->mutable_space_info()->CopyFrom(m_parcspace_alloc_response_msg.allocated_space_info()); //开始调度 code=dispatch_step(); if(code!=SUCCESS) { m_storing_process_statu_msg.mutable_dispatch_step()->set_step_statu(message::eError); m_storing_process_statu_msg.mutable_dispatch_step()->set_description(code.get_error_description()); LOG(ERROR)<<"调度失败:"<set_step_statu(message::eComplete); } //第三步,占据车位 case 2: { //更新状态信息 m_storing_process_statu_msg.mutable_confirm_space_step()->set_step_statu(message::eWorking); m_storing_process_statu_msg.mutable_confirm_space_step()->mutable_space_info()->CopyFrom(m_parcspace_alloc_response_msg.allocated_space_info()); //开始工作 code=confirm_space_step(); if(code!=SUCCESS) { m_storing_process_statu_msg.mutable_confirm_space_step()->set_step_statu(message::eError); m_storing_process_statu_msg.mutable_confirm_space_step()->set_description(code.get_error_description()); LOG(ERROR)<<"停车流程:"<set_step_statu(message::eComplete); } //第四步,打印... 日志 .... 记录..... case 3: { LOG(INFO)<<"停车成功,停车终端:"<set_step_statu(message::eWorking); code=release_space_step(); if(code!=SUCCESS) { m_storing_process_statu_msg.mutable_failed_release_space_step()->set_step_statu(message::eError); m_storing_process_statu_msg.mutable_failed_release_space_step()->set_description(code.get_error_description()); LOG(ERROR)<<"致命故障,停车失败,清理车位故障:"<set_step_statu(message::eComplete); } /* * 流程异常,此处应暂停系统,待管理员介入 */ } /* * 发布状态线程 */ void StoreProcessTask::publish_thread_func(StoreProcessTask* ptask) { if(ptask) { ptask->publish_step_status(); } } void StoreProcessTask::publish_step_status() { //未收到退出信号 while(false==m_publish_exit_condition.wait_for_ex(std::chrono::milliseconds(200))) { /* * 通过communicator 发布状态 */ if(System_communicator::get_instance_pointer()) { if(m_storing_process_statu_msg.has_base_info()==true) { System_communicator::get_instance_pointer()->post_entrance_statu(m_storing_process_statu_msg); } } } }