一种Switch……case……优化方法

面对Switch...case...语句中大量复杂操作导致的代码臃肿问题,一种解决方案是将每个case转化为独立的函数。将这些函数与case对应,存入map中,通过调用map中的函数执行相应步骤,提高代码可读性和维护性。如此,添加新状态只需增加新函数并注册到map,使代码更加整洁易懂。

在我们编程写代码过程中,不免遇到Switch,case语句,针对短小精悍的处理,毫无问题,直接用就是了,但是遇到每个case都需要处理大量操作,那所在函数将会被塞的又臭又长,极其不利于阅读与维护,就像下面的例子:

void Inspection_Task_Manager::inspection_task_handler(void)
{

    switch (m_curr_task_node->state)
    {
    case Inspection_Task_Node_t::Init:
    {
        m_mach->m_led.led_set_state(LED_STATE_INSPECT, 1);
        if (m_curr_task_node == m_head)
        {
            //m_mach->push_ptz_status();
            m_mach->m_ptz.focus_auto(true);
            std::this_thread::sleep_for(std::chrono::milliseconds(30));

            set_light(default_light_mode);
        }

        LOG_INFO("Inspection Task [task_id:%d,point_id:%d] \r\n", m_task_id,
                 m_curr_task_node->point_id);
        if ((fabs(m_curr_task_node->position_x - m_mach->m_robot_position_x) < POSITION_MAX_DIFF) &&
            (fabs(m_curr_task_node->position_y - m_mach->m_robot_position_y) < POSITION_MAX_DIFF) &&
            (fabs(m_curr_task_node->position_theta - m_mach->m_robot_position_theta) <
             POSITION_MAX_DIFF))
        {
            m_curr_task_node->state = Inspection_Task_Node_t::PtzAction;
        }
        else
        {
            m_curr_task_node->state = Inspection_Task_Node_t::PtzReset;
        }
        m_curr_task_node->collect_seq = 1;
        m_curr_task_node->_time = std::chrono::steady_clock::now();
        m_curr_task_node->is_continue_inspect = false;
    }
    break;
    case Inspection_Task_Node_t::PtzReset:
        LOG_INFO("Inspection Task : ptz reset \r\n");
        m_mach->m_ptz.setPosition(m_default_hori_angle, m_default_vert_angle, m_default_zoom,
                                  m_default_focal);
        m_curr_task_node->state = Inspection_Task_Node_t::WaitPtzReset;
        LOG_INFO("Inspection Task : wait ptz reset finish \r\n");

        m_ptz_action_time = std::chrono::steady_clock::now();
        break;
    case Inspection_Task_Node_t::WaitPtzReset:
    {
        float horiz_angle = m_mach->m_ptz.getHorizAngle();
        float vert_angle = m_mach->m_ptz.getVertAngle();
        int zoom = m_mach->m_ptz.getCameraZoom();

        if (PtzDeamon::angle_diff(horiz_angle, m_default_hori_angle) < 0.5f &&
            PtzDeamon::angle_diff(vert_angle, m_default_vert_angle) < 0.5f &&
            abs(zoom - m_default_zoom) < 10)
        {
            m_curr_task_node->state = Inspection_Task_Node_t::Move;
            LOG_INFO("Inspection Task : ptz reset finish , ready to move \r\n");
        }
        {
            std::chrono::steady_clock::time_point curr_time = std::chrono::steady_clock::now();
            auto diff =
                std::chrono::duration_cast<std::chrono::seconds>(curr_time - m_ptz_action_time)
                    .count();
            if (diff > 30) //���������������Ȼû����������·���ָ��
            {
                m_curr_task_node->state = Inspection_Task_Node_t::PtzReset;
                LOG_INFO("Inspection Task : ptz reset action timeout , redo \r\n");
            }
        }
    }
    break;

    case Inspection_Task_Node_t::Move:
    {
        if ((fabs(m_curr_task_node->position_x - m_mach->m_robot_position_x) < POSITION_MAX_DIFF) &&
            (fabs(m_curr_task_node->position_y - m_mach->m_robot_position_y) < POSITION_MAX_DIFF) &&
            (fabs(m_curr_task_node->position_theta - m_mach->m_robot_position_theta) <
             POSITION_MAX_DIFF))
        {
            m_curr_task_node->state = Inspection_Task_Node_t::WaitArrive;
        }
        else
        {

            LOG_INFO("Inspection Task : move to position (%.3f,%.3f,%.3f), speed : %f \r\n",
                     m_curr_task_node->position_x, m_curr_task_node->position_y,
                     m_curr_task_node->position_theta, m_robot_speed);
            m_mach->slam_move_to_position(
                m_curr_task_node->point_id, m_curr_task_node->floor_location,
                m_curr_task_node->position_x, m_curr_task_node->position_y,
                m_curr_task_node->position_theta);
            //std::this_thread::sleep_for(std::chrono::milliseconds(200));
            m_curr_task_node->state = Inspection_Task_Node_t::WaitMove;
            log_timer = 0;
            LOG_INFO("Inspection Task : wait robot moving ,lifter status:%d\r\n", m_lifter_status);
        }
    }
    break;

    case Inspection_Task_Node_t::WaitMove:
        if (m_mach->m_slam_staus == NAVIGATE_TO_POSITION)
        {
            LOG_INFO("Inspection Task : robot moving,slam switch status to  NAVIGATE_TO_POSITION, "
                     "wait arrive.\r\n");
            m_curr_task_node->state = Inspection_Task_Node_t::WaitArrive;
        }

        if ((fabs(m_curr_task_node->position_x - m_mach->m_robot_position_x) < POSITION_MAX_DIFF) &&
            (fabs(m_curr_task_node->position_y - m_mach->m_robot_position_y) < POSITION_MAX_DIFF) &&
            (fabs(m_curr_task_node->position_theta - m_mach->m_robot_position_theta) <
             POSITION_MAX_DIFF))
        {
            m_curr_task_node->state = Inspection_Task_Node_t::WaitArrive;
        }

        if (log_timer > 50)
        {
            log_timer = 0;
            LOG_INFO("Inspection Task : wait robot moving time out,now wait robot arrive.\r\n");
            m_curr_task_node->state = Inspection_Task_Node_t::WaitArrive;
        }

        break;

    case Inspection_Task_Node_t::WaitArrive:
    {
        if (m_mach->m_slam_staus == ARRIVED_POSITION)
        {

#if 0			
			if((fabs(m_curr_task_node->position_x - m_mach->m_robot_position_x) > POSITION_MAX_DIFF)  ||
				(fabs(m_curr_task_node->position_y - m_mach->m_robot_position_y) > POSITION_MAX_DIFF) ||
				(fabs(m_curr_task_node->position_theta - m_mach->m_robot_position_theta) > POSITION_MAX_DIFF) 			
			)
			{
				LOG_INFO("Inspection Task : robot has not arrived ,move again!  diff: x_diff = %.3f, y_diff = %.3f, theta_diff = %.3f \r\n",		  
						m_mach->m_robot_position_x - m_curr_task_node->position_x,
						m_mach->m_robot_position_y -  m_curr_task_node->position_y,
						m_mach->m_robot_position_theta - m_curr_task_node->position_theta);

				m_curr_task_node->state = Inspection_Task_Node_t::WaitMove;	
				m_mach->slam_move_to_position(m_curr_task_node->point_id,m_curr_task_node->position_x,m_curr_task_node->position_y,m_curr_task_node->position_theta);
		
			}
			else
#endif
            {
                LOG_INFO("Inspection Task : robot arrived,current position : x = %.3f,y = "
                         "%.3f,theta = "
                         "%.3f  point set position: x = %.3f,y = %.3f,theta = %.3f\r\n",
                         m_mach->m_robot_position_x, m_mach->m_robot_position_y,
                         m_mach->m_robot_position_theta, m_curr_task_node->position_x,
                         m_curr_task_node->position_y, m_curr_task_node->position_theta);

                LOG_INFO("Inspection Task : robot position diff: x_diff = %.3f, y_diff = %.3f, "
                         "theta_diff = %.3f \r\n",
                         m_mach->m_robot_position_x - m_curr_task_node->position_x,
                         m_mach->m_robot_position_y - m_curr_task_node->position_y,
                         m_mach->m_robot_position_theta - m_curr_task_node->position_theta);
                m_curr_task_node->state = Inspection_Task_Node_t::Arrived;
            }
        }
    }
    break;

    case Inspection_Task_Node_t::Arrived:
    {
        //LOG_INFO("Inspection Task : robot arrived\r\n");
        if (m_curr_task_node->inspect_mode == 2) //段巡模式
        {
            m_curr_task_node->state = Inspection_Task_Node_t::PtzAction;
        }
        else
        {
            m_mach->getMsgHandlerHelper().inspect_arrived_point_upload(m_task_id, m_curr_task_node);
            if (m_curr_task_node->item_type == 1) //�������ݲɼ�����Ҫת����̨
                m_curr_task_node->state = Inspection_Task_Node_t::Aquire;
            else
                m_curr_task_node->state = Inspection_Task_Node_t::PtzAction;
        }
        set_light(m_curr_task_node->light_mode);
    }
    break;

    case Inspection_Task_Node_t::PtzAction:
    {
        LOG_INFO("Inspection Task : ptz action , h:%3.2f,v:%3.2f \r\n",
                 m_curr_task_node->ptz_hori_angle, m_curr_task_node->ptz_vert_angle);

        m_mach->m_ptz.focus_auto(false);
        std::this_thread::sleep_for(std::chrono::milliseconds(50));

        m_mach->m_motor.set_lifter_position(m_curr_task_node->robot_body_lifting_position);
        LOG_INFO("Inspection Task : lifter action:%dmm",
                 m_curr_task_node->robot_body_lifting_position);

        m_mach->m_ptz.setPosition(m_curr_task_node->ptz_hori_angle,
                                  m_curr_task_node->ptz_vert_angle,
                                  1 /*m_curr_task_node->ptz_zoom*/, m_curr_task_node->ptz_focal);

        m_curr_task_node->state = Inspection_Task_Node_t::WaitPtz;
        LOG_INFO("Inspection Task : wait ptz action finish \r\n");
        m_curr_task_node->_time = std::chrono::steady_clock::time_point(std::chrono::seconds(0));

        m_ptz_action_time = std::chrono::steady_clock::now();
    }
    break;

    case Inspection_Task_Node_t::WaitPtz:
    {
        float horiz_angle = m_mach->m_ptz.getHorizAngle();
        float vert_angle = m_mach->m_ptz.getVertAngle();
        int zoom = m_mach->m_ptz.getCameraZoom();
        int focus = m_mach->m_ptz.getCameraFocus();

        bool lifter_ok = true;

        lifter_ok = abs(m_mach->m_robot_body_lifting_position -
                        m_curr_task_node->robot_body_lifting_position) < 2;

        bool focus_ok = abs(focus - m_curr_task_node->ptz_focal) < 500;
        if (m_mach->m_ptz.is_focus_auto())
            focus_ok = true; //�Զ��۽�ʱ����ȥ���

        if (PtzDeamon::angle_diff(horiz_angle, m_curr_task_node->ptz_hori_angle) < 0.15f &&
            PtzDeamon::angle_diff(vert_angle, m_curr_task_node->ptz_vert_angle) < 0.15f &&
            lifter_ok)
        {
            std::chrono::steady_clock::time_point curr_time = std::chrono::steady_clock::now();
            if (m_curr_task_node->_time ==
                std::chrono::steady_clock::time_point(std::chrono::seconds(0)))
            {
                m_mach->m_ptz.stop();
                LOG_INFO("Inspection Task : ptz action finish , wait 5 sec\r\n");
                m_curr_task_node->_time = curr_time;

                //执行变倍操作
                m_mach->m_ptz.setPosition(
                    m_curr_task_node->ptz_hori_angle, m_curr_task_node->ptz_vert_angle,
                    (int)(m_curr_task_node->ptz_zoom), m_curr_task_node->ptz_focal);
            }
            auto diff = std::chrono::duration_cast<std::chrono::seconds>(curr_time -
                                                                         m_curr_task_node->_time)
                            .count();

            int wait_timer = (int)(m_curr_task_node->ptz_zoom) / 2; //根据变倍需求决定等待时间
            wait_timer = (wait_timer > 7) ? wait_timer : 7;

            if ((diff > wait_timer) && (zoom == (int)(m_curr_task_node->ptz_zoom)))
            {
                if (m_mach->m_camera_focus_state)
                {
                    if (m_curr_task_node->inspect_mode == 2) //��Ѳģʽ
                    {
                        if (m_curr_task_node->is_continue_inspect)
                        {
                            m_mach->getMsgHandlerHelper().area_inspect_continue_request(
                                m_task_id, m_curr_task_node); //������Ѳ����
                            LOG_INFO("Inspection Task : send area inspect continue request.\r\n");
                        }
                        else
                        {
                            m_mach->getMsgHandlerHelper().inspect_arrived_point_upload(
                                m_task_id, m_curr_task_node);
                            LOG_INFO("Inspection Task :send area inspect arrived point.\r\n");
                        }
                        m_curr_task_node->_time =
                            std::chrono::steady_clock::time_point(std::chrono::seconds(0));
                        m_curr_task_node->state = Inspection_Task_Node_t::WaitAreaInspectStart;
                    }
                    else
                    {
                        m_curr_task_node->state = Inspection_Task_Node_t::LifterCheck;
                        LOG_INFO("Inspection Task : ptz action finish, check lifter,if need,check "
                                 "lifter empty.\r\n");
                    }
                }
                else
                {
                    if ((diff % 6) == 0)
                        LOG_INFO("Inspection Task : wait camera focusing done. diff = %ld", diff);
                }
            }
            else
            {
                if (log_timer > 10)
                {
                    log_timer = 0;
                    LOG_INFO("Inspection Task : wait ptz zoom and focus done,zoom_set = "
                             "%d,zoom_need :%d time elapsed:%ld \r\n",
                             zoom, (int)m_curr_task_node->ptz_zoom, diff);
                }
            }
        }
        else
        {
            if (log_timer > 100)
            {
                log_timer = 0;
                m_mach->m_ptz.setPosition(
                    m_curr_task_node->ptz_hori_angle, m_curr_task_node->ptz_vert_angle,
                    1 /*m_curr_task_node->ptz_zoom*/, m_curr_task_node->ptz_focal);
                LOG_INFO("Inspection Task : wait ptz action done.. \r\n");
            }
        }

        {
            std::chrono::steady_clock::time_point curr_time = std::chrono::steady_clock::now();
            auto diff =
                std::chrono::duration_cast<std::chrono::seconds>(curr_time - m_ptz_action_time)
                    .count();
            if (diff > 120) //���������������Ȼû����������·���ָ��
            {
                m_curr_task_node->state =
                    Inspection_Task_Node_t::PtzResetRedo; //Inspection_Task_Node_t::PtzAction;
                LOG_INFO("Inspection Task : ptz action timeout , redo \r\n");
            }
        }
    }
    break;

    case Inspection_Task_Node_t::LifterCheck: //是否电梯乘梯检测
    {
        m_lifter_status =
            Singleton<lifter_client>::instance().lifter_control_loop(m_curr_task_node);

        if ((m_lifter_status == LifterIdle) || (m_lifter_status == LifterCheckLifterEmpty) ||
            (m_lifter_status == LifterFinish))
        { //当前设定的识别目标距离大于5m,才启动单次找表
            if (m_curr_task_node->distance > 5000.0)
            {
                m_curr_task_node->state = Inspection_Task_Node_t::SearchMeter;
                m_search_meter_task_time = std::chrono::steady_clock::now();
            }
            else
            {
                m_curr_task_node->state = Inspection_Task_Node_t::Aquire;
            }

            LOG_INFO("Inspection Task : ptz action finish, ready to send aquire command\r\n");
        }
        else
        {
            if ((log_timer % 20) == 0)
            {
                LOG_INFO("Inspection Task : Wait Lifter action,lifter_status = %d...\r\n",
                         m_lifter_status);
            }
        }
    }
    break;

    case Inspection_Task_Node_t::SearchMeter: //单次找表
    {
        LOG_INFO("Inspection_Task_Node_t::SearchMeter\r\n");

        Err_t ret;
        ret = m_mach->getMsgHandlerHelper().search_meter_request(m_task_id, m_curr_task_node);
        if (ret != NoErr)
        {
            LOG_ERR("request collent request error : %d", ret);
        }

        LOG_INFO("Inspection Task : search meter request , collect seq : %d\r\n",
                 m_curr_task_node->collect_seq);

        m_curr_task_node->state = Inspection_Task_Node_t::WaitSearchMeterResult;
        m_search_meter_time = std::chrono::steady_clock::now();
    }
    break;

    case Inspection_Task_Node_t::WaitSearchMeterResult:
    {
        LOG_INFO("Inspection_Task_Node_t::WaitSearchMeterResult\r\n");

        SearchMeterResult_t result;

        if (nn_recv(m_pull_fd, &result, sizeof(SearchMeterResult_t), NN_DONTWAIT) < 0)
        {
            LOG_ERR("Inspection_Task_Node_t::WaitSearchMeterResult nn_recv null ERR!\\r\n");

            std::chrono::steady_clock::time_point curr_time = std::chrono::steady_clock::now();
            auto diffToSearch =
                std::chrono::duration_cast<std::chrono::seconds>(curr_time - m_search_meter_time)
                    .count();
            auto diffToSearchTask = std::chrono::duration_cast<std::chrono::seconds>(
                                        curr_time - m_search_meter_task_time)
                                        .count();

            if (diffToSearchTask > 10)
            { //如果超过60s还没收到单次找表请求回复, 则进入下一步请求表计识别
                m_curr_task_node->state = Inspection_Task_Node_t::Aquire;

                LOG_ERR("WaitSearchMeterResult  timeOut!!\r\n");
            }
            else if (diffToSearch > 2)
            { //如果离上次发送单次找表请求超过10s还没收到回复,则再发一次,防止服务器没收到
                m_curr_task_node->state = Inspection_Task_Node_t::SearchMeter;

                LOG_ERR("WaitSearchMeterResult  don`t recieve RSP  reREQ SearchMeter!!\r\n");
            }
            else
            {
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
            }
            break;
        }

        if (result.task_id != m_task_id || result.point_id != m_curr_task_node->point_id)
        {
            LOG_ERR("Inspection_Task_Node_t::WaitSearchMeterResult result.task_id != m_task_id || "
                    "result.point_id != m_curr_task_node->point_id ERR!\\r\n");
            break;
        }

        LOG_INFO("Inspection Task : Search Meter Result , collect seq %d , result : %d \r\n",
                 result.collect_seq, result.errnbr);

        if (result.errnbr != 0)
        {
            LOG_INFO("SEARCH METER fail redo \r\n");
        }
        else
        {
            double posX = 1920 * result.position_x / 10000.0;
            double posY = 1080 * result.position_y / 10000.0;
            double width = 1920 * result.percentage_x / 10000.0;
            double height = 1080 * result.percentage_y / 10000.0;

            rectZoomIn_t rect;
            rect.xTop = posX - width / 2.0;
            rect.yTop = posY - width / 2.0;
            rect.xBottom = posX + width / 2.0;
            rect.yBottom = posY + height / 2.0;

            LOG_INFO("SEARCH METER ok! 1920x1080 posX: %f  posY: %f  width : %f height: %f\r\n",
                     posX, posY, width, height);

            if (m_mach->m_ptz.ptz3DposFunction(rect, 1920, 1080))
            {

                int32_t sleepTime = m_curr_task_node->distance;
                LOG_INFO("m_mach->m_ptz.ptz3DposFunction OK! Aquire sleepTime: %d;\r\n", sleepTime);

                std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
            }
            else
            {
                LOG_ERR("m_mach->m_ptz.ptz3DposFunction FAIL! PtzResetRedo;\r\n");
            }
        }
        //不管最后找表是否成功,都进入下一步
        m_curr_task_node->state = Inspection_Task_Node_t::Aquire;
    }
    break;

    case Inspection_Task_Node_t::PtzResetRedo:
        LOG_INFO("Inspection Task : ptz reset redo \r\n");

        m_mach->m_ptz.focus_auto(true);
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
        m_mach->m_ptz.setPosition(m_default_hori_angle, m_default_vert_angle, m_default_zoom,
                                  m_default_focal);

        m_curr_task_node->state = Inspection_Task_Node_t::WaitPtzResetRedo;
        LOG_INFO("Inspection Task : wait ptz reset redo finish \r\n");

        m_ptz_action_time = std::chrono::steady_clock::now();
        break;
    case Inspection_Task_Node_t::WaitPtzResetRedo:
    {
        float horiz_angle = m_mach->m_ptz.getHorizAngle();
        float vert_angle = m_mach->m_ptz.getVertAngle();
        int zoom = m_mach->m_ptz.getCameraZoom();

        if (PtzDeamon::angle_diff(horiz_angle, m_default_hori_angle) < 0.5f &&
            PtzDeamon::angle_diff(vert_angle, m_default_vert_angle) < 0.5f &&
            abs(zoom - m_default_zoom) < 10)
        {
            m_curr_task_node->state = Inspection_Task_Node_t::PtzAction;
            LOG_INFO("Inspection Task : ptz reset finish , ready to move \r\n");
        }

        std::chrono::steady_clock::time_point curr_time = std::chrono::steady_clock::now();
        auto diff =
            std::chrono::duration_cast<std::chrono::seconds>(curr_time - m_ptz_action_time).count();
        if (diff > 30) //���������������Ȼû����������·���ָ��
        {
            m_curr_task_node->state = Inspection_Task_Node_t::PtzResetRedo;
            LOG_INFO("Inspection Task : ptz reset action timeout , redo \r\n");
        }
    }
    break;

    case Inspection_Task_Node_t::WaitAreaInspectStart:
    {
        std::chrono::steady_clock::time_point curr_time = std::chrono::steady_clock::now();
        if (m_curr_task_node->_time ==
            std::chrono::steady_clock::time_point(std::chrono::seconds(0)))
        {
            LOG_INFO("Inspection Task : wait area inspect start command...\r\n");
            m_curr_task_node->_time = curr_time;
        }
    }
    break;

    case Inspection_Task_Node_t::AreaInspecting:
    {
        if (m_curr_task_node->_time ==
            std::chrono::steady_clock::time_point(std::chrono::seconds(0)))
        {
            std::chrono::steady_clock::time_point curr_time = std::chrono::steady_clock::now();
            LOG_INFO("Inspection Task : area inspect started.\r\n");
            m_curr_task_node->_time = curr_time;
            //todo: 段巡结束点位后台没有巡ID,约定默认加上10000固定值
            m_mach->slam_move_to_position(
                10000UL + m_curr_task_node->point_id, m_curr_task_node->floor_location,
                m_curr_task_node->inspect_end_position_x, m_curr_task_node->inspect_end_position_y,
                m_curr_task_node->position_theta);
            std::this_thread::sleep_for(std::chrono::milliseconds(500)); ///等待导航模块切换状态
        }
        else
        {
            if (m_mach->m_slam_staus ==
                ARRIVED_POSITION) //(motor_reached_target_position()) //��Ѳ�����յ�λ��
            {
                LOG_INFO("Inspection Task : area inspect reached end position.\r\n");
                m_mach->getMsgHandlerHelper().inspect_leave_point_upload(m_task_id,
                                                                         m_curr_task_node);
                m_curr_task_node->state = Inspection_Task_Node_t::Finish;
            }
            else
            {
                ;
            }
        }
    }
    break;

    case Inspection_Task_Node_t::AreaInspecExp:
    {
        std::chrono::steady_clock::time_point curr_time = std::chrono::steady_clock::now();
        if (m_curr_task_node->_time ==
            std::chrono::steady_clock::time_point(std::chrono::seconds(0)))
        {
            LOG_INFO("Inspection Task : area inspect exp found.\r\n");
            m_curr_task_node->_time = curr_time;
            m_mach->slam_remote_control("ROBOT_CTRL_STOP");
        }
        else
        {
            float speed = 0;
            m_mach->m_motor.get_speed(&speed);
            if (fabs(speed) < 0.01f) //��Ѳ�쳣,������ͣ����
            {
                Err_t ret;
                LOG_INFO("Inspection Task : area inspect exp and motor stopped.\r\n");

                ret = m_mach->getMsgHandlerHelper().area_inspect_manual_review_request(
                    m_task_id, m_curr_task_node);
                if (ret != NoErr)
                {
                    LOG_ERR("area_inspect_manual_review_request error : %d", ret);
                }
                else
                {
                    m_curr_task_node->state = Inspection_Task_Node_t::WaitAreaInspectStart;
                }
            }
        }
    }
    break;

    case Inspection_Task_Node_t::Aquire:
    {
        Err_t ret =
            m_mach->getMsgHandlerHelper().result_collect_request(m_task_id, m_curr_task_node);
        if (ret != NoErr)
        {
            LOG_ERR("request collent request error : %d", ret);
        }

        LOG_INFO("Inspection Task : result collect request , collect seq : %d\r\n",
                 m_curr_task_node->collect_seq);

        m_inspection_context.last_collect_time = std::chrono::steady_clock::now();
        m_curr_task_node->state = Inspection_Task_Node_t::WaitAquireResult;
    }
    break;
    case Inspection_Task_Node_t::NextAquire:
    {
        std::chrono::steady_clock::time_point curr_time = std::chrono::steady_clock::now();
        auto diff = std::chrono::duration_cast<std::chrono::seconds>(
                        curr_time - m_inspection_context.last_collect_time).count();
        if (diff > m_curr_task_node->collect_interval)
        {
            LOG_INFO("time to aquire,continue\r\n");
            m_curr_task_node->state = Inspection_Task_Node_t::Aquire;
        }
    }
    break;
    case Inspection_Task_Node_t::WaitAquireResult:
    {
        CollectResult_t result;
        int ret = nn_recv(m_pull_fd, &result, sizeof(CollectResult_t), NN_DONTWAIT);
        if (ret < 0)
            break;
        if (result.task_id != m_task_id || result.point_id != m_curr_task_node->point_id)
        {
            break;
        }

        LOG_INFO("Inspection Task : result collect finish , collect seq %d , result : %d , total "
                 "times : %d\r\n",
                 result.collect_seq, result.result, m_curr_task_node->collect_times);
        //		if(result->result==0)
        {
            m_curr_task_node->collect_seq = result.collect_seq;
        }

        if (result.result == -2) //-2,Ѳ�����ɼ�ʧ�ܣ���Ѳ�����Ҫ����ִ�У���̨��λ�����¶�λ���ٴβɼ���
        {
            LOG_INFO("collect fail redo \r\n");
            m_curr_task_node->state = Inspection_Task_Node_t::PtzResetRedo;
        }
        else if (result.collect_seq < m_curr_task_node->collect_times) //��Ҫ�����ɼ�
        {
            LOG_INFO("next result collect\r\n");
            m_curr_task_node->collect_seq = result.collect_seq + 1;
            m_curr_task_node->state = Inspection_Task_Node_t::NextAquire;
        }
        else
        {
            if (m_lifter_status == LifterCheckLifterEmpty)
            {
                if (((m_curr_task_node->item_type == 30) &&
                     (result.lifter_empty > 0)) //视觉检测到电梯不为空
                    || (Machine::Instance().m_lifter_empty_sim > 10) //激光检测到电梯不为空
                    || (Machine::Instance().m_lifter_empty_sim < 0)  //激光检测到电梯失败
                )
                {
                    LOG_INFO("Inspection Task : Lifter is not empty[item_type: %d , lifter_empty "
                             ":%d, m_lifter_empty_sim:%.1f ], realse and wait next turn\r\n",
                             m_curr_task_node->item_type, result.lifter_empty,
                             Machine::Instance().m_lifter_empty_sim);
                    Singleton<lifter_client>::instance().lifter_realse_wait();
                    m_curr_task_node->state = Inspection_Task_Node_t::LifterCheck;
                }
                else
                {
                    LOG_INFO("Inspection Task : Lifter is  empty,wait robot move in...\r\n");
                    Singleton<lifter_client>::instance().lifter_move_in();
                    m_curr_task_node->state = Inspection_Task_Node_t::LifterCheck;
                }
            }
            else if (m_lifter_status == LifterFinish)
            {
                Singleton<lifter_client>::instance().reset();
                m_curr_task_node->state = Inspection_Task_Node_t::FireDoorCheck;
            }
            else
            {
                m_curr_task_node->state = Inspection_Task_Node_t::FireDoorCheck;
            }
        }
    }
    break;

    case Inspection_Task_Node_t::FireDoorCheck: //是否通过防火门检测
    {

        int firedoor_status =
            Singleton<firedoor_control>::instance().firedoor_control_loop(m_curr_task_node);

        if ((firedoor_status == FireDoorIdle) || (firedoor_status == FireDoorWaitRobotMoving))
        {
            if ((firedoor_status == FireDoorWaitRobotMoving) &&
                (Singleton<firedoor_control>::instance().firedoor_is_finish_point(
                    m_curr_task_node)))
            {
                LOG_INFO("Inspection Task : FireDoor Control reach end point.\r\n");
            }

            LOG_INFO("Inspection Task : result collect finish \r\n");
            m_mach->getMsgHandlerHelper().inspect_leave_point_upload(m_task_id, m_curr_task_node);
            m_curr_task_node->state = Inspection_Task_Node_t::Finish;
        }
        else 
        {
            if ((log_timer % 20) == 0)
            {
                LOG_INFO("Inspection Task : Wait firedoor action,firedoor_status = %d...\r\n",
                         firedoor_status);
            }
        }
    }
    break;

    case Inspection_Task_Node_t::Abort:
    {
        LOG_INFO("Inspection Task Abort\r\n");
        abort_task(m_task_id, TASK_OTHER_ABORT);

        LOG_INFO("back home\r\n");
        m_mach->back_home();
        m_mach->m_motor.set_lifter_position(0);
        Singleton<lifter_client>::instance().abort();
        Singleton<firedoor_control>::instance().finish();
    }
    break;
    case Inspection_Task_Node_t::Finish:
    {
        m_curr_task_node = m_curr_task_node->next;
        LOG_INFO("Inspection Task : inspect result upload\r\n");
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
        m_mach->m_ptz.focus_auto(true);
        m_mach->m_motor.set_lifter_position(0);
        std::this_thread::sleep_for(std::chrono::milliseconds(50));

        if (m_curr_task_node)
        {
            LOG_INFO("Inspection Task : goto next node\r\n");
            m_curr_task_node->state = Inspection_Task_Node_t::Init;
        }
        else
        {
            LOG_INFO("Inspection Task Finish\r\n");
            finish_task();

            LOG_INFO("back home\r\n");
            m_mach->back_home();

            m_mach->update_operating_time(); //fixme
        }

    }
    break;
    default:
        break;
    }

看了上面这段代码,你是不是立马崩溃………………这是弄啥勒…………

 于是决定我不要这样,我要简约,要一目了然……于是,我将每个CASE都写成一个函数,像下面这样:

    void inspectionTaskInit();

    void inspectionTaskPtzReset();

    void inspectionTaskMove();

    void inspectionTaskArrived();

    void inspectionTaskPtzAction();

    void inspectionTaskWaitPtz();

    void inspectionTaskLifterCheck();

    void inspectionTaskSearchMeter();

    void inspectionTaskWaitSearchMeterResult();

    void inspectionTaskPreReviewConfirmOp();

    void inspectionTaskReviewConfirm();

    void inspectionTaskWaitConfirmReviewResult();

    void inspectionTaskOperation();

    void inspectionTaskPtzResetRedo();

    void inspectionTaskWaitAreaInspectStart();

    void inspectionTaskAreaInspecting();

    void inspectionTaskAreaInspecExp();

    void inspectionTaskAquire();

    void inspectionTaskNextAquire();

    void inspectionTaskWaitAquireResult();

    void inspectionTaskFireDoorCheck();

    void inspectionTaskFinish();

然后将所有函数与case步骤组成一对,并插入到map中,像下面:

 inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::Init, std::bind(&Inspection_Task_Manager::inspectionTaskInit, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::PtzReset, std::bind(&Inspection_Task_Manager::inspectionTaskPtzReset, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::Move, std::bind(&Inspection_Task_Manager::inspectionTaskMove, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::Arrived, std::bind(&Inspection_Task_Manager::inspectionTaskArrived, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::PtzAction, std::bind(&Inspection_Task_Manager::inspectionTaskPtzAction, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::WaitPtz, std::bind(&Inspection_Task_Manager::inspectionTaskWaitPtz, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::LifterCheck, std::bind(&Inspection_Task_Manager::inspectionTaskLifterCheck, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::SearchMeter, std::bind(&Inspection_Task_Manager::inspectionTaskSearchMeter, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::WaitSearchMeterResult, std::bind(&Inspection_Task_Manager::inspectionTaskWaitSearchMeterResult, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::PreReviewConfirmOp, std::bind(&Inspection_Task_Manager::inspectionTaskPreReviewConfirmOp, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::ReviewConfirm, std::bind(&Inspection_Task_Manager::inspectionTaskReviewConfirm, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::WaitConfirmReviewResult, std::bind(&Inspection_Task_Manager::inspectionTaskWaitConfirmReviewResult, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::Operation, std::bind(&Inspection_Task_Manager::inspectionTaskOperation, this)));    

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::PtzResetRedo, std::bind(&Inspection_Task_Manager::inspectionTaskPtzResetRedo, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::WaitAreaInspectStart, std::bind(&Inspection_Task_Manager::inspectionTaskWaitAreaInspectStart, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::AreaInspecting, std::bind(&Inspection_Task_Manager::inspectionTaskAreaInspecting, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::AreaInspecExp, std::bind(&Inspection_Task_Manager::inspectionTaskAreaInspecExp, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::Aquire, std::bind(&Inspection_Task_Manager::inspectionTaskAquire, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::NextAquire, std::bind(&Inspection_Task_Manager::inspectionTaskNextAquire, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::WaitAquireResult, std::bind(&Inspection_Task_Manager::inspectionTaskWaitAquireResult, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::FireDoorCheck, std::bind(&Inspection_Task_Manager::inspectionTaskFireDoorCheck, this)));

    inspectionTaskOpFunMap.insert(std::pair<Inspection_Task_Node_t::State_t, inspectionTaskOp>(

                                  Inspection_Task_Node_t::Finish, std::bind(&Inspection_Task_Manager::inspectionTaskFinish, this)));

最后我要执行不同步骤的时候,就像下面这样:

	auto iter = inspectionTaskOpFunMap.find(m_curr_task_node->state);
	if(iter != inspectionTaskOpFunMap.end())
	{
		auto functor = iter->second;
		functor();
	}

经过这么一改造,是不是清晰多了,当我要添加新状态的时候,直接写对应函数,插入map即可,对的这就是我想要的,是不是你想要的呢?

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值