<commit_before>#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE "test_optimizers"

#include <boost/test/unit_test.hpp>
#include "math/abs.hpp"
#include "core/logger.h"
#include "core/minimize.h"
#include "math/random.hpp"
#include "math/numeric.hpp"
#include "math/epsilon.hpp"
#include "text/to_string.hpp"

#include "func/function_trid.h"
#include "func/function_beale.h"
#include "func/function_booth.h"
#include "func/function_sphere.h"
#include "func/function_matyas.h"
#include "func/function_powell.h"
#include "func/function_mccormick.h"
#include "func/function_himmelblau.h"
#include "func/function_rosenbrock.h"
#include "func/function_3hump_camel.h"
#include "func/function_sum_squares.h"
#include "func/function_dixon_price.h"
#include "func/function_goldstein_price.h"
#include "func/function_rotated_ellipsoid.h"

namespace test
{
        using namespace ncv;

        static void check_solution(const string_t& problem, const string_t& optimizer,
                const vector_t& x0, const opt_state_t& state, const std::vector<std::pair<vector_t, scalar_t>>& solutions)
        {
                // check convergence
                const scalar_t dg = state.g.lpNorm<Eigen::Infinity>();
                BOOST_CHECK_LE(dg, math::epsilon3<scalar_t>());

                // find the closest solution
                size_t best_index = std::string::npos;
                scalar_t best_distance = std::numeric_limits<scalar_t>::max();

                for (size_t index = 0; index < solutions.size(); index ++)
                {
                        const scalar_t distance = (state.x - solutions[index].first).lpNorm<Eigen::Infinity>();
                        if (distance < best_distance)
                        {
                                best_distance = distance;
                                best_index = index;
                        }
                }

                // check accuracy
                BOOST_REQUIRE_LT(best_index, solutions.size());

                const scalar_t df = math::abs(state.f - solutions[best_index].second);
                const scalar_t dx = (state.x - solutions[best_index].first).lpNorm<Eigen::Infinity>();

                BOOST_CHECK_LE(df, math::epsilon3<scalar_t>());
                BOOST_CHECK_LE(dx, math::epsilon3<scalar_t>());

                // debugging
                BOOST_CHECK_MESSAGE(
                        dx < math::epsilon3<scalar_t>(),
                        "failed (x) for <" << problem << ">, <" << optimizer << "> and <" << x0.transpose() << ">!");
                BOOST_CHECK_MESSAGE(
                        df < math::epsilon3<scalar_t>(),
                        "failed (f) for <" << problem << ">, <" << optimizer << "> and <" << x0.transpose() << ">!");
                BOOST_CHECK_MESSAGE(
                        dg < math::epsilon3<scalar_t>(),
                        "failed (g) for <" << problem << ">, <" << optimizer << "> and <" << x0.transpose() << ">!");
        }

        static void check_problem(
                const string_t& problem_name,
                const opt_opsize_t& fn_size, const opt_opfval_t& fn_fval, const opt_opgrad_t& fn_grad,
                const std::vector<std::pair<vector_t, scalar_t>>& solutions)
        {
                const size_t iterations = 1024;
                const scalar_t epsilon = 1e-6;
                const size_t trials = 16 * 1024;

                const size_t dims = fn_size();

                random_t<scalar_t> rgen(-1.0, +1.0);

                // generate fixed random trials
                vectors_t x0s;
                for (size_t t = 0; t < trials; t ++)
                {
                        vector_t x0(dims);
                        rgen(x0.data(), x0.data() + x0.size());

                        x0s.push_back(x0);
                }

                // optimizers to try
                const auto optimizers =
                {
                        min::batch_optimizer::GD,

                        min::batch_optimizer::CGD,
//                        min::batch_optimizer::CGD_CD,
//                        min::batch_optimizer::CGD_DY,
//                        min::batch_optimizer::CGD_FR,
//                        min::batch_optimizer::CGD_HS,
//                        min::batch_optimizer::CGD_LS,
                        min::batch_optimizer::CGD_N,
                        min::batch_optimizer::CGD_PRP,
//                        min::batch_optimizer::CGD_DYCD,
                        min::batch_optimizer::CGD_DYHS,

                        min::batch_optimizer::LBFGS
                };

                for (min::batch_optimizer optimizer : optimizers)
                {
                        for (size_t t = 0; t < trials; t ++)
                        {
                                const vector_t& x0 = x0s[t];

                                // optimize
                                const opt_state_t state = ncv::minimize(
                                        fn_size, fn_fval, fn_grad, nullptr, nullptr, nullptr,
                                        x0, optimizer, iterations, epsilon);

                                // check solution
                                check_solution(problem_name, text::to_string(optimizer), x0, state, solutions);
                        }
                }
        }

        static void check_problems(const std::vector<test::function_t>& funcs)
        {
                for (const test::function_t& func : funcs)
                {
                        test::check_problem(func.m_name, func.m_opsize, func.m_opfval, func.m_opgrad, func.m_solutions);
                }
        }
}

BOOST_AUTO_TEST_CASE(test_optimizers)
{
        using namespace ncv;

//        test::check_problems(ncv::make_beale_funcs());
        test::check_problems(ncv::make_booth_funcs());
        test::check_problems(ncv::make_matyas_funcs());
//        test::check_problems(ncv::make_trid_funcs(8));
        test::check_problems(ncv::make_sphere_funcs(8));
//        test::check_problems(ncv::make_powell_funcs(8));
//        test::check_problems(ncv::make_mccormick_funcs());
        test::check_problems(ncv::make_himmelblau_funcs());
//        test::check_problems(ncv::make_rosenbrock_funcs(7));
//        test::check_problems(ncv::make_3hump_camel_funcs());
//        test::check_problems(ncv::make_dixon_price_funcs(8));
        test::check_problems(ncv::make_sum_squares_funcs(8));
//        test::check_problems(ncv::make_goldstein_price_funcs());
        test::check_problems(ncv::make_rotated_ellipsoid_funcs(8));
}

<commit_msg>exhaustively testing the optimizers (to polish & make it faster)<commit_after>#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE "test_optimizers"

#include <boost/test/unit_test.hpp>
#include "math/abs.hpp"
#include "core/logger.h"
#include "core/minimize.h"
#include "math/random.hpp"
#include "math/numeric.hpp"
#include "math/epsilon.hpp"
#include "text/to_string.hpp"

#include "func/function_trid.h"
#include "func/function_beale.h"
#include "func/function_booth.h"
#include "func/function_sphere.h"
#include "func/function_matyas.h"
#include "func/function_powell.h"
#include "func/function_mccormick.h"
#include "func/function_himmelblau.h"
#include "func/function_rosenbrock.h"
#include "func/function_3hump_camel.h"
#include "func/function_sum_squares.h"
#include "func/function_dixon_price.h"
#include "func/function_goldstein_price.h"
#include "func/function_rotated_ellipsoid.h"

namespace test
{
        using namespace ncv;

        static void check_solution(const string_t& problem, const string_t& optimizer,
                const vector_t& x0, const opt_state_t& state, const std::vector<std::pair<vector_t, scalar_t>>& solutions)
        {
//                // find the closest solution
//                size_t best_index = std::string::npos;
//                scalar_t best_distance = std::numeric_limits<scalar_t>::max();

//                for (size_t index = 0; index < solutions.size(); index ++)
//                {
//                        const scalar_t distance = (state.x - solutions[index].first).lpNorm<Eigen::Infinity>();
//                        if (distance < best_distance)
//                        {
//                                best_distance = distance;
//                                best_index = index;
//                        }
//                }

//                // check accuracy
//                BOOST_REQUIRE_LT(best_index, solutions.size());

//                const scalar_t df = math::abs(state.f - solutions[best_index].second);
//                const scalar_t dx = (state.x - solutions[best_index].first).lpNorm<Eigen::Infinity>();

//                BOOST_CHECK_LE(df, math::epsilon3<scalar_t>());
//                BOOST_CHECK_LE(dx, math::epsilon3<scalar_t>());

//                // debugging
//                BOOST_CHECK_MESSAGE(
//                        dx < math::epsilon3<scalar_t>(),
//                        "failed (x) after " << state.n_iterations() <<
//                        " iterations for <" << problem << ">, <" << optimizer << "> and <" << x0.transpose() << ">!");
//                BOOST_CHECK_MESSAGE(
//                        df < math::epsilon3<scalar_t>(),
//                        "failed (f) after " << state.n_iterations() <<
//                        " iterations for <" << problem << ">, <" << optimizer << "> and <" << x0.transpose() << ">!");
        }

        static void check_convergence(const string_t& problem, const string_t& optimizer,
                const vector_t& x0, const scalar_t epsilon, const opt_state_t& state)
        {
                // check convergence
                const scalar_t dg = state.convergence_criteria();
                BOOST_CHECK_LE(dg, epsilon);

                // debugging
                BOOST_CHECK_MESSAGE(
                        dg < epsilon,
                        "failed (g) for <" << problem << ", " << optimizer <<
                        ">: x0 = " << x0.transpose() << ", iters = " << state.n_iterations() << "!");
        }

        static void check_problem(
                const string_t& problem_name,
                const opt_opsize_t& fn_size, const opt_opfval_t& fn_fval, const opt_opgrad_t& fn_grad,
                const std::vector<std::pair<vector_t, scalar_t>>& solutions)
        {
                const size_t iterations = 1024 * 1024;
                const scalar_t epsilon = 1e-6;
                const size_t trials = 16 * 1024;

                const size_t dims = fn_size();

                random_t<scalar_t> rgen(-1.0, +1.0);

                // generate fixed random trials
                vectors_t x0s;
                for (size_t t = 0; t < trials; t ++)
                {
                        vector_t x0(dims);
                        rgen(x0.data(), x0.data() + x0.size());

                        x0s.push_back(x0);
                }

                // optimizers to try
                const auto optimizers =
                {
                        min::batch_optimizer::GD,

                        min::batch_optimizer::CGD,
                        min::batch_optimizer::CGD_CD,
                        min::batch_optimizer::CGD_DY,
                        min::batch_optimizer::CGD_FR,
                        min::batch_optimizer::CGD_HS,
                        min::batch_optimizer::CGD_LS,
                        min::batch_optimizer::CGD_N,
                        min::batch_optimizer::CGD_PRP,
                        min::batch_optimizer::CGD_DYCD,
                        min::batch_optimizer::CGD_DYHS,

                        min::batch_optimizer::LBFGS
                };

                for (min::batch_optimizer optimizer : optimizers)
                {
                        for (size_t t = 0; t < trials; t ++)
                        {
                                const vector_t& x0 = x0s[t];

                                // optimize
                                const opt_state_t state = ncv::minimize(
                                        fn_size, fn_fval, fn_grad, nullptr, nullptr, nullptr,
                                        x0, optimizer, iterations, epsilon);

                                // check result
                                check_convergence(problem_name, text::to_string(optimizer), x0, epsilon, state);
                                check_solution(problem_name, text::to_string(optimizer), x0, state, solutions);
                        }
                }
        }

        static void check_problems(const std::vector<test::function_t>& funcs)
        {
                for (const test::function_t& func : funcs)
                {
                        test::check_problem(func.m_name, func.m_opsize, func.m_opfval, func.m_opgrad, func.m_solutions);
                }
        }
}

BOOST_AUTO_TEST_CASE(test_optimizers)
{
        using namespace ncv;

        test::check_problems(ncv::make_beale_funcs());
        test::check_problems(ncv::make_booth_funcs());
        test::check_problems(ncv::make_matyas_funcs());
        test::check_problems(ncv::make_trid_funcs(8));
        test::check_problems(ncv::make_sphere_funcs(8));
        test::check_problems(ncv::make_powell_funcs(8));
        test::check_problems(ncv::make_mccormick_funcs());
        test::check_problems(ncv::make_himmelblau_funcs());
        test::check_problems(ncv::make_rosenbrock_funcs(7));
        test::check_problems(ncv::make_3hump_camel_funcs());
        test::check_problems(ncv::make_dixon_price_funcs(8));
        test::check_problems(ncv::make_sum_squares_funcs(8));
        test::check_problems(ncv::make_goldstein_price_funcs());
        test::check_problems(ncv::make_rotated_ellipsoid_funcs(8));
}

<|endoftext|>


<commit_before>#include "../Outer_Parameters.hxx"
#include "setup_constraints.hxx"

#include "../../ostream_set.hxx"
#include "../../ostream_map.hxx"
#include "../../ostream_vector.hxx"
#include "../../set_stream_precision.hxx"

namespace
{
  void copy_matrix(const El::Matrix<El::BigFloat> &source,
                   El::DistMatrix<El::BigFloat> &destination)
  {
    for(int64_t row(0); row < destination.LocalHeight(); ++row)
      {
        int64_t global_row(destination.GlobalRow(row));
        for(int64_t column(0); column < destination.LocalWidth(); ++column)
          {
            int64_t global_column(destination.GlobalCol(column));
            destination.SetLocal(row, column,
                                 source(global_row, global_column));
          }
      }
  }

  void
  copy_matrix(const El::DistMatrix<El::BigFloat, El::STAR, El::STAR> &source,
              El::Matrix<El::BigFloat> &destination)
  {
    destination.Resize(source.LocalHeight(), source.LocalWidth());
    for(int64_t row(0); row < source.LocalHeight(); ++row)
      {
        for(int64_t column(0); column < source.LocalWidth(); ++column)
          {
            destination(row, column) = source.GetLocal(row, column);
          }
      }
  }

  void fill_weights(const El::Matrix<El::BigFloat> &y, const size_t &max_index,
                    const std::vector<El::BigFloat> &normalization,
                    std::vector<El::BigFloat> &weights)
  {
    weights.at(max_index) = 1;
    for(size_t block_row(0); block_row != size_t(y.Height()); ++block_row)
      {
        const size_t index(block_row + (block_row < max_index ? 0 : 1));
        weights.at(index) = y(block_row, 0);
        weights.at(max_index) -= weights.at(index) * normalization.at(index);
      }
    weights.at(max_index) /= normalization.at(max_index);
  }
}

void compute_y_transform(
  const std::vector<std::vector<std::vector<std::vector<Function>>>>
    &function_blocks,
  const std::vector<std::set<El::BigFloat>> &points,
  const std::vector<El::BigFloat> &objectives,
  const std::vector<El::BigFloat> &normalization,
  const Outer_Parameters &parameters, const size_t &max_index,
  const El::Grid &global_grid,
  El::DistMatrix<El::BigFloat, El::STAR, El::STAR> &yp_to_y,
  El::DistMatrix<El::BigFloat, El::STAR, El::STAR> &dual_objective_b_star,
  El::BigFloat &primal_c_scale);

boost::optional<int64_t> load_checkpoint(
  const boost::filesystem::path &checkpoint_directory,
  boost::optional<int64_t> &backup_generation, int64_t &current_generation,
  El::DistMatrix<El::BigFloat, El::STAR, El::STAR> &yp_to_y_star,
  El::DistMatrix<El::BigFloat, El::STAR, El::STAR> &dual_objective_b_star,
  El::Matrix<El::BigFloat> &y, std::vector<std::set<El::BigFloat>> &points,
  El::BigFloat &threshold, El::BigFloat &primal_c_scale);

void find_new_points(
  const size_t &num_blocks, const size_t &rank, const size_t &num_procs,
  const El::BigFloat &infinity,
  const std::vector<std::vector<std::vector<std::vector<Function>>>>
    &function_blocks,
  const std::vector<El::BigFloat> &weights,
  const std::vector<std::set<El::BigFloat>> &points,
  std::vector<std::vector<El::BigFloat>> &new_points, bool &has_new_points);

void save_checkpoint(
  const boost::filesystem::path &checkpoint_directory,
  const Verbosity &verbosity,
  const El::DistMatrix<El::BigFloat, El::STAR, El::STAR> &yp_to_y_star,
  const El::DistMatrix<El::BigFloat, El::STAR, El::STAR> &dual_objective_b_star,
  const El::Matrix<El::BigFloat> &y,
  const std::vector<std::set<El::BigFloat>> &points,
  const El::BigFloat &infinity, const El::BigFloat &threshold,
  const El::BigFloat &primal_c_scale,
  boost::optional<int64_t> &backup_generation, int64_t &current_generation);

std::vector<El::BigFloat> compute_optimal(
  const std::vector<std::vector<std::vector<std::vector<Function>>>>
    &function_blocks,
  const std::vector<std::vector<El::BigFloat>> &initial_points,
  const std::vector<El::BigFloat> &objectives,
  const std::vector<El::BigFloat> &normalization,
  const Outer_Parameters &parameters_in)
{
  if(initial_points.size() != function_blocks.size())
    {
      throw std::runtime_error(
        "Size are different: Positive_Matrix_With_Prefactor: "
        + std::to_string(function_blocks.size())
        + ", initial points: " + std::to_string(initial_points.size()));
    }
  Outer_Parameters parameters(parameters_in);

  const size_t rank(El::mpi::Rank()), num_procs(El::mpi::Size()),
    num_weights(normalization.size());

  const size_t num_blocks(initial_points.size());
  std::vector<El::BigFloat> weights(num_weights, 0);
  std::vector<std::set<El::BigFloat>> points(num_blocks);
  std::vector<std::vector<El::BigFloat>> new_points(num_blocks);

  // GMP does not have a special infinity value, so we use max double.
  const El::BigFloat infinity(std::numeric_limits<double>::max());
  // Use the input points and add inifinty
  for(size_t block(0); block < num_blocks; ++block)
    {
      for(auto &point : initial_points.at(block))
        {
          points.at(block).emplace(point);
        }
      points.at(block).emplace(infinity);
    }

  // TODO: This is duplicated from sdp2input/write_output/write_output.cxx
  size_t max_index(0);
  El::BigFloat max_normalization(0);
  for(size_t index(0); index != normalization.size(); ++index)
    {
      const El::BigFloat element(Abs(normalization[index]));
      if(element > max_normalization)
        {
          max_normalization = element;
          max_index = index;
        }
    }

  const El::Grid global_grid;
  El::DistMatrix<El::BigFloat, El::STAR, El::STAR> yp_to_y_star(global_grid),
    dual_objective_b_star(global_grid);
  El::BigFloat primal_c_scale;

  // TODO: Load checkpoint
  parameters.solver.duality_gap_threshold = 1.1;
  El::Matrix<El::BigFloat> yp_saved(yp_to_y_star.Height(), 1);
  El::Zero(yp_saved);

  int64_t current_generation(0);
  boost::optional<int64_t> backup_generation;
  load_checkpoint(parameters.solver.checkpoint_in, backup_generation,
                  current_generation, yp_to_y_star, dual_objective_b_star,
                  yp_saved, points, parameters.solver.duality_gap_threshold,
                  primal_c_scale);
  if(backup_generation)
    {
      El::Matrix<El::BigFloat> y(yp_saved.Height(), 1);

      El::Gemv(El::Orientation::NORMAL, El::BigFloat(1.0),
               yp_to_y_star.LockedMatrix(), yp_saved, El::BigFloat(0.0), y);

      if(El::mpi::Rank() == 0 && parameters.verbosity >= Verbosity::regular)
        {
          std::cout << "Loaded checkpoint " << backup_generation << "\n";
        }
      fill_weights(y, max_index, normalization, weights);
    }
  else
    {
      compute_y_transform(function_blocks, points, objectives, normalization,
                          parameters, max_index, global_grid, yp_to_y_star,
                          dual_objective_b_star, primal_c_scale);
    }

  while(parameters.solver.duality_gap_threshold
        > parameters_in.solver.duality_gap_threshold)
    {
      std::map<size_t, size_t> new_to_old;
      size_t num_constraints(0), old_index(0);
      std::vector<size_t> matrix_dimensions;
      for(size_t block(0); block != num_blocks; ++block)
        {
          for(size_t offset(0); offset != points.at(block).size(); ++offset)
            {
              new_to_old.emplace(num_constraints + offset, old_index + offset);
            }
          old_index += points.at(block).size();
          for(auto &point : new_points.at(block))
            {
              points.at(block).emplace(point);
            }
          num_constraints += points.at(block).size();
          matrix_dimensions.insert(matrix_dimensions.end(),
                                   points.at(block).size(),
                                   function_blocks[block].size());
          if(rank == 0 && parameters.verbosity >= Verbosity::debug)
            {
              std::cout << "points: " << block << " " << points.at(block)
                        << "\n";
            }
        }
      if(rank == 0 && parameters.verbosity >= Verbosity::regular)
        {
          std::cout << "num_constraints: " << num_constraints << "\n";
        }

      std::vector<std::vector<El::BigFloat>> primal_objective_c;
      primal_objective_c.reserve(num_constraints);
      std::vector<El::Matrix<El::BigFloat>> free_var_matrix;
      free_var_matrix.reserve(num_constraints);

      setup_constraints(max_index, num_blocks, infinity, function_blocks,
                        normalization, points, primal_objective_c,
                        free_var_matrix);

      const El::BigFloat objective_const(objectives.at(max_index)
                                         / normalization.at(max_index));

      Block_Info block_info(matrix_dimensions, parameters.verbosity);

      El::Grid grid(block_info.mpi_comm.value);

      SDP sdp(objective_const, primal_objective_c, free_var_matrix,
              yp_to_y_star, dual_objective_b_star, primal_c_scale, block_info,
              grid);

      SDP_Solver solver(parameters.solver, parameters.verbosity,
                        parameters.require_initial_checkpoint, block_info,
                        grid, sdp.dual_objective_b.Height());

      for(auto &y_block : solver.y.blocks)
        {
          copy_matrix(yp_saved, y_block);
        }

      boost::property_tree::ptree parameter_properties(
        to_property_tree(parameters));
      bool has_new_points(false);
      while(!has_new_points
            && parameters.solver.duality_gap_threshold
                 > parameters_in.solver.duality_gap_threshold)
        {
          if(rank == 0 && parameters.verbosity >= Verbosity::regular)
            {
              std::cout << "Threshold: "
                        << parameters.solver.duality_gap_threshold << "\n";
            }

          Timers timers(parameters.verbosity >= Verbosity::debug);
          SDP_Solver_Terminate_Reason reason
            = solver.run(parameters.solver, parameters.verbosity,
                         parameter_properties, block_info, sdp, grid, timers);

          if(rank == 0 && parameters.verbosity >= Verbosity::regular)
            {
              set_stream_precision(std::cout);
              std::cout << "-----" << reason << "-----\n"
                        << '\n'
                        << "primalObjective = " << solver.primal_objective
                        << '\n'
                        << "dualObjective   = " << solver.dual_objective
                        << '\n'
                        << "dualityGap      = " << solver.duality_gap << '\n'
                        << "primalError     = " << solver.primal_error()
                        << '\n'
                        << "dualError       = " << solver.dual_error << '\n'
                        << '\n';
            }

          if(reason == SDP_Solver_Terminate_Reason::MaxComplementarityExceeded
             || reason == SDP_Solver_Terminate_Reason::MaxIterationsExceeded
             || reason == SDP_Solver_Terminate_Reason::MaxRuntimeExceeded)
            {
              std::stringstream ss;
              ss << "Can not find solution: " << reason;
              throw std::runtime_error(ss.str());
            }

          // y is duplicated among cores, so only need to print out copy on
          // the root node.
          // THe weight at max_index is determined by the normalization
          // condition dot(norm,weights)=1
          El::DistMatrix<El::BigFloat> yp(dual_objective_b_star.Height(), 1,
                                          yp_to_y_star.Grid());
          El::Zero(yp);
          El::DistMatrix<El::BigFloat> y(yp);
          El::DistMatrix<El::BigFloat, El::STAR, El::STAR> yp_star(
            solver.y.blocks.at(0));
          for(int64_t row(0); row != yp.LocalHeight(); ++row)
            {
              int64_t global_row(yp.GlobalRow(row));
              for(int64_t column(0); column != yp.LocalWidth(); ++column)
                {
                  int64_t global_column(yp.GlobalCol(column));
                  yp.SetLocal(row, column,
                              yp_star.GetLocal(global_row, global_column));
                }
            }
          El::Gemv(El::Orientation::NORMAL, El::BigFloat(1.0), yp_to_y_star,
                   yp, El::BigFloat(0.0), y);
          El::DistMatrix<El::BigFloat, El::STAR, El::STAR> y_star(y);

          fill_weights(y_star.LockedMatrix(), max_index, normalization,
                       weights);
          if(rank == 0 && parameters.verbosity >= Verbosity::regular)
            {
              set_stream_precision(std::cout);
              std::cout << "weight: " << weights << "\n";

              El::BigFloat optimal(0);
              for(size_t index(0); index < objectives.size(); ++index)
                {
                  optimal += objectives[index] * weights[index];
                }
              std::cout << "optimal: " << optimal << "\n";
            }
          find_new_points(num_blocks, rank, num_procs, infinity,
                          function_blocks, weights, points, new_points,
                          has_new_points);
          if(!has_new_points)
            {
              parameters.solver.duality_gap_threshold
                /= parameters.duality_gap_reduction;
            }
        }
      El::DistMatrix<El::BigFloat, El::STAR, El::STAR> yp_star(
        solver.y.blocks.front());
      copy_matrix(yp_star, yp_saved);
      save_checkpoint(parameters.solver.checkpoint_out, parameters.verbosity,
                      yp_to_y_star, dual_objective_b_star, yp_saved, points,
                      infinity, parameters.solver.duality_gap_threshold,
                      primal_c_scale, backup_generation, current_generation);
    }
  return weights;
}
<commit_msg>Remove lots of redundant copies<commit_after>#include "../Outer_Parameters.hxx"
#include "setup_constraints.hxx"

#include "../../ostream_set.hxx"
#include "../../ostream_map.hxx"
#include "../../ostream_vector.hxx"
#include "../../set_stream_precision.hxx"

namespace
{
  void copy_matrix(const El::Matrix<El::BigFloat> &source,
                   El::DistMatrix<El::BigFloat> &destination)
  {
    for(int64_t row(0); row < destination.LocalHeight(); ++row)
      {
        int64_t global_row(destination.GlobalRow(row));
        for(int64_t column(0); column < destination.LocalWidth(); ++column)
          {
            int64_t global_column(destination.GlobalCol(column));
            destination.SetLocal(row, column,
                                 source(global_row, global_column));
          }
      }
  }

  void
  copy_matrix(const El::DistMatrix<El::BigFloat, El::STAR, El::STAR> &source,
              El::Matrix<El::BigFloat> &destination)
  {
    destination.Resize(source.LocalHeight(), source.LocalWidth());
    for(int64_t row(0); row < source.LocalHeight(); ++row)
      {
        for(int64_t column(0); column < source.LocalWidth(); ++column)
          {
            destination(row, column) = source.GetLocal(row, column);
          }
      }
  }

  void fill_weights(const El::Matrix<El::BigFloat> &y, const size_t &max_index,
                    const std::vector<El::BigFloat> &normalization,
                    std::vector<El::BigFloat> &weights)
  {
    // THe weight at max_index is determined by the normalization
    // condition dot(norm,weights)=1
    weights.at(max_index) = 1;
    for(size_t block_row(0); block_row != size_t(y.Height()); ++block_row)
      {
        const size_t index(block_row + (block_row < max_index ? 0 : 1));
        weights.at(index) = y(block_row, 0);
        weights.at(max_index) -= weights.at(index) * normalization.at(index);
      }
    weights.at(max_index) /= normalization.at(max_index);
  }
}

void compute_y_transform(
  const std::vector<std::vector<std::vector<std::vector<Function>>>>
    &function_blocks,
  const std::vector<std::set<El::BigFloat>> &points,
  const std::vector<El::BigFloat> &objectives,
  const std::vector<El::BigFloat> &normalization,
  const Outer_Parameters &parameters, const size_t &max_index,
  const El::Grid &global_grid,
  El::DistMatrix<El::BigFloat, El::STAR, El::STAR> &yp_to_y,
  El::DistMatrix<El::BigFloat, El::STAR, El::STAR> &dual_objective_b_star,
  El::BigFloat &primal_c_scale);

boost::optional<int64_t> load_checkpoint(
  const boost::filesystem::path &checkpoint_directory,
  boost::optional<int64_t> &backup_generation, int64_t &current_generation,
  El::DistMatrix<El::BigFloat, El::STAR, El::STAR> &yp_to_y_star,
  El::DistMatrix<El::BigFloat, El::STAR, El::STAR> &dual_objective_b_star,
  El::Matrix<El::BigFloat> &y, std::vector<std::set<El::BigFloat>> &points,
  El::BigFloat &threshold, El::BigFloat &primal_c_scale);

void find_new_points(
  const size_t &num_blocks, const size_t &rank, const size_t &num_procs,
  const El::BigFloat &infinity,
  const std::vector<std::vector<std::vector<std::vector<Function>>>>
    &function_blocks,
  const std::vector<El::BigFloat> &weights,
  const std::vector<std::set<El::BigFloat>> &points,
  std::vector<std::vector<El::BigFloat>> &new_points, bool &has_new_points);

void save_checkpoint(
  const boost::filesystem::path &checkpoint_directory,
  const Verbosity &verbosity,
  const El::DistMatrix<El::BigFloat, El::STAR, El::STAR> &yp_to_y_star,
  const El::DistMatrix<El::BigFloat, El::STAR, El::STAR> &dual_objective_b_star,
  const El::Matrix<El::BigFloat> &y,
  const std::vector<std::set<El::BigFloat>> &points,
  const El::BigFloat &infinity, const El::BigFloat &threshold,
  const El::BigFloat &primal_c_scale,
  boost::optional<int64_t> &backup_generation, int64_t &current_generation);

std::vector<El::BigFloat> compute_optimal(
  const std::vector<std::vector<std::vector<std::vector<Function>>>>
    &function_blocks,
  const std::vector<std::vector<El::BigFloat>> &initial_points,
  const std::vector<El::BigFloat> &objectives,
  const std::vector<El::BigFloat> &normalization,
  const Outer_Parameters &parameters_in)
{
  if(initial_points.size() != function_blocks.size())
    {
      throw std::runtime_error(
        "Size are different: Positive_Matrix_With_Prefactor: "
        + std::to_string(function_blocks.size())
        + ", initial points: " + std::to_string(initial_points.size()));
    }
  Outer_Parameters parameters(parameters_in);

  const size_t rank(El::mpi::Rank()), num_procs(El::mpi::Size()),
    num_weights(normalization.size());

  const size_t num_blocks(initial_points.size());
  std::vector<El::BigFloat> weights(num_weights, 0);
  std::vector<std::set<El::BigFloat>> points(num_blocks);
  std::vector<std::vector<El::BigFloat>> new_points(num_blocks);

  // GMP does not have a special infinity value, so we use max double.
  const El::BigFloat infinity(std::numeric_limits<double>::max());
  // Use the input points and add inifinty
  for(size_t block(0); block < num_blocks; ++block)
    {
      for(auto &point : initial_points.at(block))
        {
          points.at(block).emplace(point);
        }
      points.at(block).emplace(infinity);
    }

  // TODO: This is duplicated from sdp2input/write_output/write_output.cxx
  size_t max_index(0);
  El::BigFloat max_normalization(0);
  for(size_t index(0); index != normalization.size(); ++index)
    {
      const El::BigFloat element(Abs(normalization[index]));
      if(element > max_normalization)
        {
          max_normalization = element;
          max_index = index;
        }
    }

  const El::Grid global_grid;
  El::DistMatrix<El::BigFloat, El::STAR, El::STAR> yp_to_y_star(global_grid),
    dual_objective_b_star(global_grid);
  El::BigFloat primal_c_scale;

  parameters.solver.duality_gap_threshold = 1.1;
  El::Matrix<El::BigFloat> yp_saved(yp_to_y_star.Height(), 1);
  El::Zero(yp_saved);

  int64_t current_generation(0);
  boost::optional<int64_t> backup_generation;
  load_checkpoint(parameters.solver.checkpoint_in, backup_generation,
                  current_generation, yp_to_y_star, dual_objective_b_star,
                  yp_saved, points, parameters.solver.duality_gap_threshold,
                  primal_c_scale);
  if(backup_generation)
    {
      El::Matrix<El::BigFloat> y(yp_saved.Height(), 1);

      El::Gemv(El::Orientation::NORMAL, El::BigFloat(1.0),
               yp_to_y_star.LockedMatrix(), yp_saved, El::BigFloat(0.0), y);

      if(El::mpi::Rank() == 0 && parameters.verbosity >= Verbosity::regular)
        {
          std::cout << "Loaded checkpoint " << backup_generation << "\n";
        }
      fill_weights(y, max_index, normalization, weights);
    }
  else
    {
      compute_y_transform(function_blocks, points, objectives, normalization,
                          parameters, max_index, global_grid, yp_to_y_star,
                          dual_objective_b_star, primal_c_scale);
    }

  while(parameters.solver.duality_gap_threshold
        > parameters_in.solver.duality_gap_threshold)
    {
      std::map<size_t, size_t> new_to_old;
      size_t num_constraints(0), old_index(0);
      std::vector<size_t> matrix_dimensions;
      for(size_t block(0); block != num_blocks; ++block)
        {
          for(size_t offset(0); offset != points.at(block).size(); ++offset)
            {
              new_to_old.emplace(num_constraints + offset, old_index + offset);
            }
          old_index += points.at(block).size();
          for(auto &point : new_points.at(block))
            {
              points.at(block).emplace(point);
            }
          num_constraints += points.at(block).size();
          matrix_dimensions.insert(matrix_dimensions.end(),
                                   points.at(block).size(),
                                   function_blocks[block].size());
          if(rank == 0 && parameters.verbosity >= Verbosity::debug)
            {
              std::cout << "points: " << block << " " << points.at(block)
                        << "\n";
            }
        }
      if(rank == 0 && parameters.verbosity >= Verbosity::regular)
        {
          std::cout << "num_constraints: " << num_constraints << "\n";
        }

      std::vector<std::vector<El::BigFloat>> primal_objective_c;
      primal_objective_c.reserve(num_constraints);
      std::vector<El::Matrix<El::BigFloat>> free_var_matrix;
      free_var_matrix.reserve(num_constraints);

      setup_constraints(max_index, num_blocks, infinity, function_blocks,
                        normalization, points, primal_objective_c,
                        free_var_matrix);

      const El::BigFloat objective_const(objectives.at(max_index)
                                         / normalization.at(max_index));

      Block_Info block_info(matrix_dimensions, parameters.verbosity);

      El::Grid grid(block_info.mpi_comm.value);

      SDP sdp(objective_const, primal_objective_c, free_var_matrix,
              yp_to_y_star, dual_objective_b_star, primal_c_scale, block_info,
              grid);

      SDP_Solver solver(parameters.solver, parameters.verbosity,
                        parameters.require_initial_checkpoint, block_info,
                        grid, sdp.dual_objective_b.Height());

      for(auto &y_block : solver.y.blocks)
        {
          copy_matrix(yp_saved, y_block);
        }

      boost::property_tree::ptree parameter_properties(
        to_property_tree(parameters));
      bool has_new_points(false);
      while(!has_new_points
            && parameters.solver.duality_gap_threshold
                 > parameters_in.solver.duality_gap_threshold)
        {
          if(rank == 0 && parameters.verbosity >= Verbosity::regular)
            {
              std::cout << "Threshold: "
                        << parameters.solver.duality_gap_threshold << "\n";
            }

          Timers timers(parameters.verbosity >= Verbosity::debug);
          SDP_Solver_Terminate_Reason reason
            = solver.run(parameters.solver, parameters.verbosity,
                         parameter_properties, block_info, sdp, grid, timers);

          if(rank == 0 && parameters.verbosity >= Verbosity::regular)
            {
              set_stream_precision(std::cout);
              std::cout << "-----" << reason << "-----\n"
                        << '\n'
                        << "primalObjective = " << solver.primal_objective
                        << '\n'
                        << "dualObjective   = " << solver.dual_objective
                        << '\n'
                        << "dualityGap      = " << solver.duality_gap << '\n'
                        << "primalError     = " << solver.primal_error()
                        << '\n'
                        << "dualError       = " << solver.dual_error << '\n'
                        << '\n';
            }

          if(reason == SDP_Solver_Terminate_Reason::MaxComplementarityExceeded
             || reason == SDP_Solver_Terminate_Reason::MaxIterationsExceeded
             || reason == SDP_Solver_Terminate_Reason::MaxRuntimeExceeded)
            {
              std::stringstream ss;
              ss << "Can not find solution: " << reason;
              throw std::runtime_error(ss.str());
            }

          El::Matrix<El::BigFloat> y(dual_objective_b_star.Height(), 1);
          El::DistMatrix<El::BigFloat, El::STAR, El::STAR> yp_star(
            solver.y.blocks.at(0));

          El::Gemv(El::Orientation::NORMAL, El::BigFloat(1.0),
                   yp_to_y_star.LockedMatrix(), yp_star.LockedMatrix(),
                   El::BigFloat(0.0), y);

          fill_weights(y, max_index, normalization, weights);
          if(rank == 0 && parameters.verbosity >= Verbosity::regular)
            {
              set_stream_precision(std::cout);
              std::cout << "weight: " << weights << "\n";

              El::BigFloat optimal(0);
              for(size_t index(0); index < objectives.size(); ++index)
                {
                  optimal += objectives[index] * weights[index];
                }
              std::cout << "optimal: " << optimal << "\n";
            }
          find_new_points(num_blocks, rank, num_procs, infinity,
                          function_blocks, weights, points, new_points,
                          has_new_points);
          if(!has_new_points)
            {
              parameters.solver.duality_gap_threshold
                /= parameters.duality_gap_reduction;
            }
        }
      El::DistMatrix<El::BigFloat, El::STAR, El::STAR> yp_star(
        solver.y.blocks.front());
      copy_matrix(yp_star, yp_saved);
      save_checkpoint(parameters.solver.checkpoint_out, parameters.verbosity,
                      yp_to_y_star, dual_objective_b_star, yp_saved, points,
                      infinity, parameters.solver.duality_gap_threshold,
                      primal_c_scale, backup_generation, current_generation);
    }
  return weights;
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file frame.cc
 **/
#include "modules/planning/common/frame.h"

#include <cmath>
#include <list>
#include <string>
#include <utility>

#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/configs/vehicle_config_helper.h"
#include "modules/common/log.h"
#include "modules/common/math/vec2d.h"
#include "modules/common/vehicle_state/vehicle_state.h"
#include "modules/map/pnc_map/pnc_map.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/reference_line/reference_line_smoother.h"

namespace apollo {
namespace planning {

using apollo::common::adapter::AdapterManager;

const hdmap::PncMap *Frame::pnc_map_ = nullptr;

void Frame::SetMap(hdmap::PncMap *pnc_map) { pnc_map_ = pnc_map; }

FrameHistory::FrameHistory()
    : IndexedQueue<uint32_t, Frame>(FLAGS_max_history_frame_num) {}

Frame::Frame(const uint32_t sequence_num) : sequence_num_(sequence_num) {}

void Frame::SetVehicleInitPose(const localization::Pose &pose) {
  init_pose_ = pose;
}

const localization::Pose &Frame::VehicleInitPose() const { return init_pose_; }

void Frame::SetRoutingResponse(const routing::RoutingResponse &routing) {
  routing_response_ = routing;
}

void Frame::SetPlanningStartPoint(const common::TrajectoryPoint &start_point) {
  planning_start_point_ = start_point;
}

const hdmap::PncMap *Frame::PncMap() {
  DCHECK(pnc_map_) << "map is not setup in frame";
  return pnc_map_;
}

const common::TrajectoryPoint &Frame::PlanningStartPoint() const {
  return planning_start_point_;
}

void Frame::SetPrediction(const prediction::PredictionObstacles &prediction) {
  prediction_ = prediction;
}

void Frame::CreatePredictionObstacles(
    const prediction::PredictionObstacles &prediction) {
  std::list<std::unique_ptr<Obstacle> > obstacles;
  Obstacle::CreateObstacles(prediction, &obstacles);
  for (auto &ptr : obstacles) {
    auto id(ptr->Id());
    obstacles_.Add(id, std::move(ptr));
  }
}

bool Frame::CreateDestinationObstacle() {
  // set destination point
  if (!routing_response_.routing_request().has_end()) {
    ADEBUG << "routing_request has no end";
    return false;
  }
  common::math::Vec2d destination;
  destination.set_x(routing_response_.routing_request().end().pose().x());
  destination.set_y(routing_response_.routing_request().end().pose().y());

  // check if destination point is in planning range
  common::SLPoint destination_sl;
  reference_line_.get_point_in_frenet_frame(destination, &destination_sl);
  double destination_s = destination_sl.s();
  if (destination_s < 0 || destination_s > reference_line_.length()) {
    AINFO << "destination(s[:" << destination_sl.s()
          << "]) out of planning range. Skip";
    return true;
  }

  // adjust destination based on adc_front_s
  common::SLPoint adc_sl;
  auto& adc_position = common::VehicleState::instance()->pose().position();
  reference_line_.get_point_in_frenet_frame(
      {adc_position.x(), adc_position.y()}, &adc_sl);
  const auto& vehicle_param =
      common::VehicleConfigHelper::instance()->GetConfig().vehicle_param();
  double adc_front_s = adc_sl.s() + vehicle_param.front_edge_to_center();
  if (destination_sl.s() <= adc_front_s) {
    destination_s = adc_front_s + FLAGS_destination_adjust_distance_buffer;
  }

  std::unique_ptr<Obstacle> obstacle_ptr = CreateVirtualObstacle(
      FLAGS_destination_obstacle_id,
      destination_s,
      FLAGS_virtual_stop_wall_length,
      FLAGS_virtual_stop_wall_width,
      FLAGS_virtual_stop_wall_height);

  obstacles_.Add(FLAGS_destination_obstacle_id, std::move(obstacle_ptr));

  return true;
}

const ADCTrajectory &Frame::GetADCTrajectory() const { return trajectory_pb_; }

ADCTrajectory *Frame::MutableADCTrajectory() { return &trajectory_pb_; }

PathDecision *Frame::path_decision() { return path_decision_; }

std::vector<ReferenceLineInfo> &Frame::reference_line_info() {
  return reference_line_info_;
}

bool Frame::InitReferenceLineInfo(
    const std::vector<ReferenceLine> &reference_lines) {
  reference_line_info_.clear();
  for (const auto &reference_line : reference_lines) {
    reference_line_info_.emplace_back(reference_line);
    auto &info = reference_line_info_.back();
    if (!info.AddObstacles(obstacles_.Items())) {
      AERROR << "Failed to add obstacles to reference line";
      return false;
    }
  }
  return true;
}

bool Frame::Init(const PlanningConfig &config) {
  if (!pnc_map_) {
    AERROR << "map is null, call SetMap() first";
    return false;
  }
  const auto &point = init_pose_.position();
  if (std::isnan(point.x()) || std::isnan(point.y())) {
    AERROR << "init point is not set";
    return false;
  }
  smoother_config_ = config.reference_line_smoother_config();
  std::vector<ReferenceLine> reference_lines;
  if (!CreateReferenceLineFromRouting(init_pose_.position(), routing_response_,
                                      &reference_lines)) {
    AERROR << "Failed to create reference line from position: "
           << init_pose_.DebugString();
    return false;
  }

  if (FLAGS_enable_prediction) {
    CreatePredictionObstacles(prediction_);
  }

  CreateDestinationObstacle();

  InitReferenceLineInfo(reference_lines);
  reference_line_ = reference_lines.front();

  // FIXME(all) remove path decision from Frame.
  path_decision_ = reference_line_info_[0].path_decision();
  CHECK(path_decision_->path_obstacles().Items().size() > 0);

  if (FLAGS_enable_traffic_decision) {
    MakeTrafficDecision(routing_response_, reference_line_);
  }

  return true;
}

uint32_t Frame::sequence_num() const { return sequence_num_; }

const PlanningData &Frame::planning_data() const { return _planning_data; }

PlanningData *Frame::mutable_planning_data() { return &_planning_data; }

const ReferenceLine &Frame::reference_line() const { return reference_line_; }

bool Frame::MakeTrafficDecision(const routing::RoutingResponse &routing,
                                const ReferenceLine &reference_line) {
  const auto &path_obstacles = path_decision_->path_obstacles();
  for (const auto path_obstacle : path_obstacles.Items()) {
    const auto &obstacle = path_obstacle->Obstacle();

    // destination stop
    if (obstacle->Id() == FLAGS_destination_obstacle_id) {
      // check stop_posision on reference line
      auto stop_position = obstacle->Perception().position();
      common::SLPoint stop_line_sl;
      reference_line.get_point_in_frenet_frame(
          { stop_position.x(),  stop_position.x()}, &stop_line_sl);
      if (!reference_line.is_on_road(stop_line_sl)) {
        continue;
      }

      // check stop_line_s vs adc_s. stop_line_s must be ahead of adc_front_s
      common::SLPoint adc_sl;
      auto& adc_position = common::VehicleState::instance()->pose().position();
      reference_line.get_point_in_frenet_frame(
          {adc_position.x(), adc_position.y()}, &adc_sl);
      const auto& vehicle_param =
          common::VehicleConfigHelper::instance()->GetConfig().vehicle_param();
      double adc_front_s = adc_sl.s() + vehicle_param.front_edge_to_center();
      if (stop_line_sl.s() <= adc_front_s) {
        ADEBUG << "skip: object:" << obstacle->Id() << " fence route_s["
               << stop_line_sl.s() << "] behind adc_front_s["
               << adc_front_s << "]";
        continue;
      }

      ObjectDecisionType object_stop;
      ObjectStop *object_stop_ptr = object_stop.mutable_stop();
      object_stop_ptr->set_distance_s(FLAGS_stop_line_min_distance);
      object_stop_ptr->set_reason_code(
          StopReasonCode::STOP_REASON_DESTINATION);

      auto stop_ref_point = reference_line_.get_reference_point(
          stop_position.x(), stop_position.y());
      object_stop_ptr->mutable_stop_point()->set_x(stop_ref_point.x());
      object_stop_ptr->mutable_stop_point()->set_y(stop_ref_point.y());
      object_stop_ptr->set_stop_heading(stop_ref_point.heading());

      path_decision_->AddLongitudinalDecision("TBD", obstacle->Id(),
                                              object_stop);
    }
  }

  return true;
}

bool Frame::CreateReferenceLineFromRouting(
    const common::PointENU &position, const routing::RoutingResponse &routing,
    std::vector<ReferenceLine> *reference_lines) {
  CHECK_NOTNULL(reference_lines);

  hdmap::Path hdmap_path;
  if (!pnc_map_->CreatePathFromRouting(
          routing, position, FLAGS_look_backward_distance,
          FLAGS_look_forward_distance, &hdmap_path)) {
    AERROR << "Failed to get path from routing";
    return false;
  }
  reference_lines->emplace_back(ReferenceLine());
  ReferenceLineSmoother smoother;
  smoother.Init(smoother_config_);
  if (!smoother.smooth(ReferenceLine(hdmap_path), &reference_lines->back())) {
    AERROR << "Failed to smooth reference line";
    return false;
  }
  return true;
}

const IndexedObstacles &Frame::GetObstacles() const { return obstacles_; }

std::string Frame::DebugString() const {
  return "Frame: " + std::to_string(sequence_num_);
}

void Frame::RecordInputDebug() {
  if (!FLAGS_enable_record_debug) {
    ADEBUG << "Skip record input into debug";
    return;
  }
  auto planning_data = trajectory_pb_.mutable_debug()->mutable_planning_data();
  auto adc_position = planning_data->mutable_adc_position();
  const auto &localization =
      AdapterManager::GetLocalization()->GetLatestObserved();
  adc_position->CopyFrom(localization);

  const auto &chassis = AdapterManager::GetChassis()->GetLatestObserved();
  auto debug_chassis = planning_data->mutable_chassis();
  debug_chassis->CopyFrom(chassis);

  const auto &routing_response =
      AdapterManager::GetRoutingResponse()->GetLatestObserved();

  auto debug_routing = planning_data->mutable_routing();
  debug_routing->CopyFrom(routing_response);
}

void Frame::AlignPredictionTime(const double trajectory_header_time) {
  double prediction_header_time = prediction_.header().timestamp_sec();

  for (int i = 0; i < prediction_.prediction_obstacle_size(); i++) {
    prediction::PredictionObstacle *obstacle =
        prediction_.mutable_prediction_obstacle(i);
    for (int j = 0; j < obstacle->trajectory_size(); j++) {
      prediction::Trajectory *trajectory = obstacle->mutable_trajectory(j);
      for (int k = 0; k < trajectory->trajectory_point_size(); k++) {
        common::TrajectoryPoint *point =
            trajectory->mutable_trajectory_point(k);
        double abs_relative_time = point->relative_time();
        point->set_relative_time(prediction_header_time + abs_relative_time -
                                 trajectory_header_time);
      }
    }
  }
}

std::unique_ptr<Obstacle> Frame::CreateVirtualObstacle(
    const std::string &obstacle_id,
    const double route_s,
    const double length, const double width, const double height) {
  std::unique_ptr<Obstacle> obstacle_ptr(nullptr);

  // create a "virtual" perception_obstacle
  perception::PerceptionObstacle perception_obstacle;
  perception_obstacle.set_id(-1);  // simulator needs a valid integer
  auto dest_ref_point =
      reference_line_.get_reference_point(route_s);
  perception_obstacle.mutable_position()->set_x(dest_ref_point.x());
  perception_obstacle.mutable_position()->set_y(dest_ref_point.y());
  perception_obstacle.set_theta(dest_ref_point.heading());
  perception_obstacle.mutable_velocity()->set_x(0);
  perception_obstacle.mutable_velocity()->set_y(0);
  perception_obstacle.set_length(length);
  perception_obstacle.set_width(length);
  perception_obstacle.set_height(length);
  perception_obstacle.set_type(
      perception::PerceptionObstacle::UNKNOWN_UNMOVABLE);
  perception_obstacle.set_tracking_time(1.0);

  obstacle_ptr.reset(new Obstacle(obstacle_id, perception_obstacle));
  return obstacle_ptr;
}

}  // namespace planning
}  // namespace apollo
<commit_msg>planning: move destination after reference line. (#955)<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file frame.cc
 **/
#include "modules/planning/common/frame.h"

#include <cmath>
#include <list>
#include <string>
#include <utility>

#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/configs/vehicle_config_helper.h"
#include "modules/common/log.h"
#include "modules/common/math/vec2d.h"
#include "modules/common/vehicle_state/vehicle_state.h"
#include "modules/map/pnc_map/pnc_map.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/reference_line/reference_line_smoother.h"

namespace apollo {
namespace planning {

using apollo::common::adapter::AdapterManager;

const hdmap::PncMap *Frame::pnc_map_ = nullptr;

void Frame::SetMap(hdmap::PncMap *pnc_map) { pnc_map_ = pnc_map; }

FrameHistory::FrameHistory()
    : IndexedQueue<uint32_t, Frame>(FLAGS_max_history_frame_num) {}

Frame::Frame(const uint32_t sequence_num) : sequence_num_(sequence_num) {}

void Frame::SetVehicleInitPose(const localization::Pose &pose) {
  init_pose_ = pose;
}

const localization::Pose &Frame::VehicleInitPose() const { return init_pose_; }

void Frame::SetRoutingResponse(const routing::RoutingResponse &routing) {
  routing_response_ = routing;
}

void Frame::SetPlanningStartPoint(const common::TrajectoryPoint &start_point) {
  planning_start_point_ = start_point;
}

const hdmap::PncMap *Frame::PncMap() {
  DCHECK(pnc_map_) << "map is not setup in frame";
  return pnc_map_;
}

const common::TrajectoryPoint &Frame::PlanningStartPoint() const {
  return planning_start_point_;
}

void Frame::SetPrediction(const prediction::PredictionObstacles &prediction) {
  prediction_ = prediction;
}

void Frame::CreatePredictionObstacles(
    const prediction::PredictionObstacles &prediction) {
  std::list<std::unique_ptr<Obstacle> > obstacles;
  Obstacle::CreateObstacles(prediction, &obstacles);
  for (auto &ptr : obstacles) {
    auto id(ptr->Id());
    obstacles_.Add(id, std::move(ptr));
  }
}

bool Frame::CreateDestinationObstacle() {
  // set destination point
  if (!routing_response_.routing_request().has_end()) {
    ADEBUG << "routing_request has no end";
    return false;
  }
  common::math::Vec2d destination;
  destination.set_x(routing_response_.routing_request().end().pose().x());
  destination.set_y(routing_response_.routing_request().end().pose().y());

  // check if destination point is in planning range
  common::SLPoint destination_sl;
  reference_line_.get_point_in_frenet_frame(destination, &destination_sl);
  double destination_s = destination_sl.s();
  if (destination_s < 0 || destination_s > reference_line_.length()) {
    AINFO << "destination(s[:" << destination_sl.s()
          << "]) out of planning range. Skip";
    return true;
  }

  // adjust destination based on adc_front_s
  common::SLPoint adc_sl;
  auto& adc_position = common::VehicleState::instance()->pose().position();
  reference_line_.get_point_in_frenet_frame(
      {adc_position.x(), adc_position.y()}, &adc_sl);
  const auto& vehicle_param =
      common::VehicleConfigHelper::instance()->GetConfig().vehicle_param();
  double adc_front_s = adc_sl.s() + vehicle_param.front_edge_to_center();
  if (destination_sl.s() <= adc_front_s) {
    destination_s = adc_front_s + FLAGS_destination_adjust_distance_buffer;
  }

  std::unique_ptr<Obstacle> obstacle_ptr = CreateVirtualObstacle(
      FLAGS_destination_obstacle_id,
      destination_s,
      FLAGS_virtual_stop_wall_length,
      FLAGS_virtual_stop_wall_width,
      FLAGS_virtual_stop_wall_height);

  obstacles_.Add(FLAGS_destination_obstacle_id, std::move(obstacle_ptr));

  return true;
}

const ADCTrajectory &Frame::GetADCTrajectory() const { return trajectory_pb_; }

ADCTrajectory *Frame::MutableADCTrajectory() { return &trajectory_pb_; }

PathDecision *Frame::path_decision() { return path_decision_; }

std::vector<ReferenceLineInfo> &Frame::reference_line_info() {
  return reference_line_info_;
}

bool Frame::InitReferenceLineInfo(
    const std::vector<ReferenceLine> &reference_lines) {
  reference_line_info_.clear();
  for (const auto &reference_line : reference_lines) {
    reference_line_info_.emplace_back(reference_line);
    auto &info = reference_line_info_.back();
    if (!info.AddObstacles(obstacles_.Items())) {
      AERROR << "Failed to add obstacles to reference line";
      return false;
    }
  }
  return true;
}

bool Frame::Init(const PlanningConfig &config) {
  if (!pnc_map_) {
    AERROR << "map is null, call SetMap() first";
    return false;
  }
  const auto &point = init_pose_.position();
  if (std::isnan(point.x()) || std::isnan(point.y())) {
    AERROR << "init point is not set";
    return false;
  }
  smoother_config_ = config.reference_line_smoother_config();
  std::vector<ReferenceLine> reference_lines;
  if (!CreateReferenceLineFromRouting(init_pose_.position(), routing_response_,
                                      &reference_lines)) {
    AERROR << "Failed to create reference line from position: "
           << init_pose_.DebugString();
    return false;
  }

  if (FLAGS_enable_prediction) {
    CreatePredictionObstacles(prediction_);
  }

  InitReferenceLineInfo(reference_lines);
  reference_line_ = reference_lines.front();

  CreateDestinationObstacle();

  // FIXME(all) remove path decision from Frame.
  path_decision_ = reference_line_info_[0].path_decision();
  CHECK(path_decision_->path_obstacles().Items().size() > 0);

  if (FLAGS_enable_traffic_decision) {
    MakeTrafficDecision(routing_response_, reference_line_);
  }

  return true;
}

uint32_t Frame::sequence_num() const { return sequence_num_; }

const PlanningData &Frame::planning_data() const { return _planning_data; }

PlanningData *Frame::mutable_planning_data() { return &_planning_data; }

const ReferenceLine &Frame::reference_line() const { return reference_line_; }

bool Frame::MakeTrafficDecision(const routing::RoutingResponse &routing,
                                const ReferenceLine &reference_line) {
  const auto &path_obstacles = path_decision_->path_obstacles();
  for (const auto path_obstacle : path_obstacles.Items()) {
    const auto &obstacle = path_obstacle->Obstacle();

    // destination stop
    if (obstacle->Id() == FLAGS_destination_obstacle_id) {
      // check stop_posision on reference line
      auto stop_position = obstacle->Perception().position();
      common::SLPoint stop_line_sl;
      reference_line.get_point_in_frenet_frame(
          { stop_position.x(),  stop_position.x()}, &stop_line_sl);
      if (!reference_line.is_on_road(stop_line_sl)) {
        continue;
      }

      // check stop_line_s vs adc_s. stop_line_s must be ahead of adc_front_s
      common::SLPoint adc_sl;
      auto& adc_position = common::VehicleState::instance()->pose().position();
      reference_line.get_point_in_frenet_frame(
          {adc_position.x(), adc_position.y()}, &adc_sl);
      const auto& vehicle_param =
          common::VehicleConfigHelper::instance()->GetConfig().vehicle_param();
      double adc_front_s = adc_sl.s() + vehicle_param.front_edge_to_center();
      if (stop_line_sl.s() <= adc_front_s) {
        ADEBUG << "skip: object:" << obstacle->Id() << " fence route_s["
               << stop_line_sl.s() << "] behind adc_front_s["
               << adc_front_s << "]";
        continue;
      }

      ObjectDecisionType object_stop;
      ObjectStop *object_stop_ptr = object_stop.mutable_stop();
      object_stop_ptr->set_distance_s(FLAGS_stop_line_min_distance);
      object_stop_ptr->set_reason_code(
          StopReasonCode::STOP_REASON_DESTINATION);

      auto stop_ref_point = reference_line_.get_reference_point(
          stop_position.x(), stop_position.y());
      object_stop_ptr->mutable_stop_point()->set_x(stop_ref_point.x());
      object_stop_ptr->mutable_stop_point()->set_y(stop_ref_point.y());
      object_stop_ptr->set_stop_heading(stop_ref_point.heading());

      path_decision_->AddLongitudinalDecision("TBD", obstacle->Id(),
                                              object_stop);
    }
  }

  return true;
}

bool Frame::CreateReferenceLineFromRouting(
    const common::PointENU &position, const routing::RoutingResponse &routing,
    std::vector<ReferenceLine> *reference_lines) {
  CHECK_NOTNULL(reference_lines);

  hdmap::Path hdmap_path;
  if (!pnc_map_->CreatePathFromRouting(
          routing, position, FLAGS_look_backward_distance,
          FLAGS_look_forward_distance, &hdmap_path)) {
    AERROR << "Failed to get path from routing";
    return false;
  }
  reference_lines->emplace_back(ReferenceLine());
  ReferenceLineSmoother smoother;
  smoother.Init(smoother_config_);
  if (!smoother.smooth(ReferenceLine(hdmap_path), &reference_lines->back())) {
    AERROR << "Failed to smooth reference line";
    return false;
  }
  return true;
}

const IndexedObstacles &Frame::GetObstacles() const { return obstacles_; }

std::string Frame::DebugString() const {
  return "Frame: " + std::to_string(sequence_num_);
}

void Frame::RecordInputDebug() {
  if (!FLAGS_enable_record_debug) {
    ADEBUG << "Skip record input into debug";
    return;
  }
  auto planning_data = trajectory_pb_.mutable_debug()->mutable_planning_data();
  auto adc_position = planning_data->mutable_adc_position();
  const auto &localization =
      AdapterManager::GetLocalization()->GetLatestObserved();
  adc_position->CopyFrom(localization);

  const auto &chassis = AdapterManager::GetChassis()->GetLatestObserved();
  auto debug_chassis = planning_data->mutable_chassis();
  debug_chassis->CopyFrom(chassis);

  const auto &routing_response =
      AdapterManager::GetRoutingResponse()->GetLatestObserved();

  auto debug_routing = planning_data->mutable_routing();
  debug_routing->CopyFrom(routing_response);
}

void Frame::AlignPredictionTime(const double trajectory_header_time) {
  double prediction_header_time = prediction_.header().timestamp_sec();

  for (int i = 0; i < prediction_.prediction_obstacle_size(); i++) {
    prediction::PredictionObstacle *obstacle =
        prediction_.mutable_prediction_obstacle(i);
    for (int j = 0; j < obstacle->trajectory_size(); j++) {
      prediction::Trajectory *trajectory = obstacle->mutable_trajectory(j);
      for (int k = 0; k < trajectory->trajectory_point_size(); k++) {
        common::TrajectoryPoint *point =
            trajectory->mutable_trajectory_point(k);
        double abs_relative_time = point->relative_time();
        point->set_relative_time(prediction_header_time + abs_relative_time -
                                 trajectory_header_time);
      }
    }
  }
}

std::unique_ptr<Obstacle> Frame::CreateVirtualObstacle(
    const std::string &obstacle_id,
    const double route_s,
    const double length, const double width, const double height) {
  std::unique_ptr<Obstacle> obstacle_ptr(nullptr);

  // create a "virtual" perception_obstacle
  perception::PerceptionObstacle perception_obstacle;
  perception_obstacle.set_id(-1);  // simulator needs a valid integer
  auto dest_ref_point =
      reference_line_.get_reference_point(route_s);
  perception_obstacle.mutable_position()->set_x(dest_ref_point.x());
  perception_obstacle.mutable_position()->set_y(dest_ref_point.y());
  perception_obstacle.set_theta(dest_ref_point.heading());
  perception_obstacle.mutable_velocity()->set_x(0);
  perception_obstacle.mutable_velocity()->set_y(0);
  perception_obstacle.set_length(length);
  perception_obstacle.set_width(length);
  perception_obstacle.set_height(length);
  perception_obstacle.set_type(
      perception::PerceptionObstacle::UNKNOWN_UNMOVABLE);
  perception_obstacle.set_tracking_time(1.0);

  obstacle_ptr.reset(new Obstacle(obstacle_id, perception_obstacle));
  return obstacle_ptr;
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before>#include "dsa_common.h"

#include <boost/asio/strand.hpp>
#include <boost/beast/websocket.hpp>

#include "http_connection.h"
#include "web_server.h"
#include "network/connection.h"

namespace websocket =
    boost::beast::websocket;  // from <boost/beast/websocket.hpp>

namespace dsa {

HttpConnection::HttpConnection(WebServer& web_server)
    : _web_server(web_server), _socket(_web_server.io_service()) {}

void HttpConnection::accept() {
  // Read a request
  boost::beast::http::async_read(
      _socket, _buffer, _req,
      // TODO: run within the strand?
      [ this, sthis = shared_from_this() ](
          const boost::system::error_code& error, size_t bytes_transferred) {

        // TODO: check error/termination conditions

        if (websocket::is_upgrade(_req)) {
          // call corresponding server's callback
          _connection = _web_server.ws_handler(_req.target().to_string())(
              _web_server, std::move(_socket), std::move(_req));
        }
        return;
      });  // async_read
}

void HttpConnection::destroy() {
/*
  if(_connection != nullptr) {
    _connection->destroy();
  }
*/
}
}  // namespace dsa
<commit_msg>temporary fix for a websocket issue on Windows platform<commit_after>#include "dsa_common.h"

#include <boost/asio/strand.hpp>
#include <boost/beast/websocket.hpp>

#include "http_connection.h"
#include "web_server.h"
#include "network/connection.h"

namespace websocket =
    boost::beast::websocket;  // from <boost/beast/websocket.hpp>

namespace dsa {

HttpConnection::HttpConnection(WebServer& web_server)
    : _web_server(web_server), _socket(_web_server.io_service()) {}

void HttpConnection::accept() {
  // Read a request
  boost::beast::http::async_read(
      _socket, _buffer, _req,
      // TODO: run within the strand?
      [ this, sthis = shared_from_this() ](
          const boost::system::error_code& error, size_t bytes_transferred) {

        // TODO: check error/termination conditions

        if (websocket::is_upgrade(_req)) {
          // call corresponding server's callback
//          TODO - temporary fix for issue on Windowns platform
//          _connection = _web_server.ws_handler(_req.target().to_string())(
          _connection = _web_server.ws_handler("/")(
              _web_server, std::move(_socket), std::move(_req));
        }
        return;
      });  // async_read
}

void HttpConnection::destroy() {
/*
  if(_connection != nullptr) {
    _connection->destroy();
  }
*/
}
}  // namespace dsa
<|endoftext|>


<commit_before>// Copyright 2010-2014 RethinkDB, all rights reserved.
#ifndef CLUSTERING_ADMINISTRATION_DATUM_ADAPTER_HPP_
#define CLUSTERING_ADMINISTRATION_DATUM_ADAPTER_HPP_

#include <set>
#include <string>
#include <vector>

#include "containers/name_string.hpp"
#include "rdb_protocol/datum.hpp"

counted_t<const ql::datum_t> convert_name_to_datum(
        const name_string_t &value);
bool convert_name_from_datum(
        counted_t<const ql::datum_t> datum,
        const std::string &what,   /* e.g. "server name" or "table name" */
        name_string_t *value_out,
        std::string *error_out);

counted_t<const ql::datum_t> convert_db_and_table_to_datum(
        const name_string_t &database, const name_string_t &table);
bool convert_db_and_table_from_datum(
        counted_t<const ql::datum_t> datum,
        name_string_t *database_out,
        name_string_t *table_out,
        std::string *error_out);

counted_t<const ql::datum_t> convert_uuid_to_datum(
        const uuid_u &value);
bool convert_uuid_from_datum(
        counted_t<const ql::datum_t> datum,
        uuid_u *value_out,
        std::string *error_out);

template<class T>
counted_t<const ql::datum_t> convert_vector_to_datum(
        const std::function<counted_t<const ql::datum_t>(const T&)> &conv,
        const std::vector<T> &vector) {
    ql::datum_array_builder_t builder((ql::configured_limits_t()));
    builder.reserve(vector.size());
    for (const T &elem : vector) {
        builder.add(conv(elem));
    }
    return std::move(builder).to_counted();
}

template<class T>
bool convert_vector_from_datum(
        const std::function<bool(counted_t<const ql::datum_t>, T*, std::string*)> &conv,
        counted_t<const ql::datum_t> datum,
        std::vector<T> *vector_out,
        std::string *error_out) {
    if (datum->get_type() != ql::datum_t::R_ARRAY) {
        *error_out = "Expected an array, got " + datum->print();
        return false;
    }
    vector_out->resize(datum->size());
    for (size_t i = 0; i < datum->size(); ++i) {
        if (!conv(datum->get(i), &(*vector_out)[i], error_out)) {
            return false;
        }
    }
    return true;
}

template<class T>
counted_t<const ql::datum_t> convert_set_to_datum(
        const std::function<counted_t<const ql::datum_t>(const T&)> &conv,
        const std::set<T> &set) {
    ql::datum_array_builder_t builder((ql::configured_limits_t()));
    builder.reserve(set.size());
    for (const T &elem : set) {
        builder.add(conv(elem));
    }
    return std::move(builder).to_counted();
}

template<class T>
bool convert_set_from_datum(
        const std::function<bool(counted_t<const ql::datum_t>, T*, std::string*)> &conv,
        bool allow_duplicates,
        counted_t<const ql::datum_t> datum,
        std::set<T> *set_out,
        std::string *error_out) {
    if (datum->get_type() != ql::datum_t::R_ARRAY) {
        *error_out = "Expected an array, got " + datum->print();
        return false;
    }
    set_out->clear();
    for (size_t i = 0; i < datum->size(); ++i) {
        T value;
        if (!conv(datum->get(i), &value, error_out)) {
            return false;
        }
        if (!allow_duplicates && set_out->count(value) == 1) {
            *error_out = datum->get(i)->print() + " was specified more than once.";
            return false;
        }
        set_out->insert(value);
    }
    return true;
}

/* `converter_from_datum_object_t` is a helper for converting a `datum_t` to some other
type when the type's datum representation is an object with a fixed set of fields.
Construct a `converter_from_datum_object_t` and call `init()` with your datum. `init()`
will fail if the input isn't an object. Next, call `get()` or `get_optional()` for each
field of the object; `get()` will fail if the field isn't present. Finally, call
`check_no_extra_keys()`, which will fail if the object has any keys that you didn't call
`get()` or `get_optional()` for. This way, it will produce a nice error message if the
user passes an object with an invalid key. */
class converter_from_datum_object_t {
public:
    bool init(counted_t<const ql::datum_t> datum,
              std::string *error_out);
    bool get(const std::string &key,
             counted_t<const ql::datum_t> *value_out,
             std::string *error_out);
    void get_optional(const std::string &key,
                      counted_t<const ql::datum_t> *value_out);
    bool check_no_extra_keys(std::string *error_out);
private:
    counted_t<const ql::datum_t> datum;
    std::set<std::string> extra_keys;
};

#endif /* CLUSTERING_ADMINISTRATION_DATUM_ADAPTER_HPP_ */

<commit_msg>Fix minor style issue in datum_adapter.hpp<commit_after>// Copyright 2010-2014 RethinkDB, all rights reserved.
#ifndef CLUSTERING_ADMINISTRATION_DATUM_ADAPTER_HPP_
#define CLUSTERING_ADMINISTRATION_DATUM_ADAPTER_HPP_

#include <set>
#include <string>
#include <vector>

#include "containers/name_string.hpp"
#include "rdb_protocol/datum.hpp"

counted_t<const ql::datum_t> convert_name_to_datum(
        const name_string_t &value);
bool convert_name_from_datum(
        counted_t<const ql::datum_t> datum,
        const std::string &what,   /* e.g. "server name" or "table name" */
        name_string_t *value_out,
        std::string *error_out);

counted_t<const ql::datum_t> convert_db_and_table_to_datum(
        const name_string_t &database, const name_string_t &table);
bool convert_db_and_table_from_datum(
        counted_t<const ql::datum_t> datum,
        name_string_t *database_out,
        name_string_t *table_out,
        std::string *error_out);

counted_t<const ql::datum_t> convert_uuid_to_datum(
        const uuid_u &value);
bool convert_uuid_from_datum(
        counted_t<const ql::datum_t> datum,
        uuid_u *value_out,
        std::string *error_out);

template<class T>
counted_t<const ql::datum_t> convert_vector_to_datum(
        const std::function<counted_t<const ql::datum_t>(const T&)> &conv,
        const std::vector<T> &vector) {
    ql::datum_array_builder_t builder((ql::configured_limits_t()));
    builder.reserve(vector.size());
    for (const T &elem : vector) {
        builder.add(conv(elem));
    }
    return std::move(builder).to_counted();
}

template<class T>
bool convert_vector_from_datum(
        const std::function<bool(counted_t<const ql::datum_t>, T*, std::string*)> &conv,
        counted_t<const ql::datum_t> datum,
        std::vector<T> *vector_out,
        std::string *error_out) {
    if (datum->get_type() != ql::datum_t::R_ARRAY) {
        *error_out = "Expected an array, got " + datum->print();
        return false;
    }
    vector_out->resize(datum->size());
    for (size_t i = 0; i < datum->size(); ++i) {
        if (!conv(datum->get(i), &(*vector_out)[i], error_out)) {
            return false;
        }
    }
    return true;
}

template<class T>
counted_t<const ql::datum_t> convert_set_to_datum(
        const std::function<counted_t<const ql::datum_t>(const T&)> &conv,
        const std::set<T> &set) {
    ql::datum_array_builder_t builder((ql::configured_limits_t()));
    builder.reserve(set.size());
    for (const T &elem : set) {
        builder.add(conv(elem));
    }
    return std::move(builder).to_counted();
}

template<class T>
bool convert_set_from_datum(
        const std::function<bool(counted_t<const ql::datum_t>, T*, std::string*)> &conv,
        bool allow_duplicates,
        counted_t<const ql::datum_t> datum,
        std::set<T> *set_out,
        std::string *error_out) {
    if (datum->get_type() != ql::datum_t::R_ARRAY) {
        *error_out = "Expected an array, got " + datum->print();
        return false;
    }
    set_out->clear();
    for (size_t i = 0; i < datum->size(); ++i) {
        T value;
        if (!conv(datum->get(i), &value, error_out)) {
            return false;
        }
        auto res = set_out->insert(value);
        if (!allow_duplicates && !res.second) {
            *error_out = datum->get(i)->print() + " was specified more than once.";
            return false;
        }
    }
    return true;
}

/* `converter_from_datum_object_t` is a helper for converting a `datum_t` to some other
type when the type's datum representation is an object with a fixed set of fields.
Construct a `converter_from_datum_object_t` and call `init()` with your datum. `init()`
will fail if the input isn't an object. Next, call `get()` or `get_optional()` for each
field of the object; `get()` will fail if the field isn't present. Finally, call
`check_no_extra_keys()`, which will fail if the object has any keys that you didn't call
`get()` or `get_optional()` for. This way, it will produce a nice error message if the
user passes an object with an invalid key. */
class converter_from_datum_object_t {
public:
    bool init(counted_t<const ql::datum_t> datum,
              std::string *error_out);
    bool get(const std::string &key,
             counted_t<const ql::datum_t> *value_out,
             std::string *error_out);
    void get_optional(const std::string &key,
                      counted_t<const ql::datum_t> *value_out);
    bool check_no_extra_keys(std::string *error_out);
private:
    counted_t<const ql::datum_t> datum;
    std::set<std::string> extra_keys;
};

#endif /* CLUSTERING_ADMINISTRATION_DATUM_ADAPTER_HPP_ */

<|endoftext|>


<commit_before>/*
    Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>

    This file is part of the KDE project

    This library is free software you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    aint with this library see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "GPXgpxTagHandler.h"

#include "MarbleDebug.h"

#include "GPXElementDictionary.h"
#include "GeoDataParser.h"

#include "GeoDataDocument.h"
#include "GeoDataStyle.h"
#include "GeoDataStyleMap.h"
#include "GeoDataHotSpot.h"
#include "MarbleDirs.h"
#include "global.h"

namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER(gpx)

GeoNode* GPXgpxTagHandler::parse(GeoParser& parser) const
{
    GeoDataDocument* doc = geoDataDoc( parser );

    GeoDataStyle style;
    GeoDataLineStyle lineStyle;
    lineStyle.setColor( oxygenForestGreen4 );
    lineStyle.setWidth(2);
    style.setLineStyle(lineStyle);
    style.setStyleId("track");

    GeoDataStyleMap styleMap;
    styleMap.setStyleId("map-track");
    styleMap.insert("normal", QString("#").append(style.styleId()));
    doc->addStyleMap(styleMap);
    doc->addStyle(style);

    // create a style for routes
    GeoDataStyle routestyle;
    GeoDataLineStyle routeLineStyle;
    routeLineStyle.setColor( "blue" );
    routeLineStyle.setWidth(3);
    routestyle.setLineStyle(routeLineStyle);
    routestyle.setStyleId("route");

    GeoDataStyleMap routeStyleMap;
    routeStyleMap.setStyleId("map-route");
    routeStyleMap.insert("normal", QString("#").append(routestyle.styleId()));
    doc->addStyleMap(routeStyleMap);
    doc->addStyle(routestyle);

    // routepoint icon style
    GeoDataStyle routepointStyle;
    routepointStyle.setStyleId("routepoint");
    GeoDataIconStyle routeIconStyle;
    routeIconStyle.setIconPath(MarbleDirs::path("bitmaps/city_4_white.png"));
    routeIconStyle.setHotSpot(QPointF(0.5,0.5), GeoDataHotSpot::Fraction, GeoDataHotSpot::Fraction);
    routepointStyle.setIconStyle(routeIconStyle);

    GeoDataStyleMap routepointStyleMap;
    routepointStyleMap.setStyleId("map-routepoint");
    routepointStyleMap.insert("normal", QString("#").append(routepointStyle.styleId()));
    doc->addStyleMap(routepointStyleMap);
    doc->addStyle(routepointStyle);

    // create a default style for waypoint icons
    GeoDataStyle waypointStyle;
    waypointStyle.setStyleId("waypoint");
    GeoDataIconStyle iconStyle;
    iconStyle.setIconPath(MarbleDirs::path("bitmaps/flag.png"));
    iconStyle.setHotSpot(QPointF(0.12,0.03), GeoDataHotSpot::Fraction, GeoDataHotSpot::Fraction);
    waypointStyle.setIconStyle(iconStyle);

    GeoDataStyleMap wpStyleMap;
    styleMap.setStyleId("map-waypoint");
    styleMap.insert("normal", QString("#").append(waypointStyle.styleId()));
    doc->addStyleMap(wpStyleMap);
    doc->addStyle(waypointStyle);

#ifdef DEBUG_TAGS
    mDebug() << "Parsed <" << gpxTag_gpx << "> document: " << doc;
#endif
    return doc;
}

}
}
<commit_msg>get the route/wpt style correct<commit_after>/*
    Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>

    This file is part of the KDE project

    This library is free software you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    aint with this library see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "GPXgpxTagHandler.h"

#include "MarbleDebug.h"

#include "GPXElementDictionary.h"
#include "GeoDataParser.h"

#include "GeoDataDocument.h"
#include "GeoDataStyle.h"
#include "GeoDataStyleMap.h"
#include "GeoDataHotSpot.h"
#include "MarbleDirs.h"
#include "global.h"

namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER(gpx)

GeoNode* GPXgpxTagHandler::parse(GeoParser& parser) const
{
    GeoDataDocument* doc = geoDataDoc( parser );

    GeoDataStyle style;
    GeoDataLineStyle lineStyle;
    lineStyle.setColor( oxygenForestGreen4 );
    lineStyle.setWidth(2);
    style.setLineStyle(lineStyle);
    style.setStyleId("track");

    GeoDataStyleMap styleMap;
    styleMap.setStyleId("map-track");
    styleMap.insert("normal", QString("#").append(style.styleId()));
    doc->addStyleMap(styleMap);
    doc->addStyle(style);

    // create a style for routes
    GeoDataStyle routestyle;
    GeoDataLineStyle routeLineStyle;
    routeLineStyle.setColor( oxygenSkyBlue4 );
    routeLineStyle.setWidth(2);
    routestyle.setLineStyle(routeLineStyle);
    routestyle.setStyleId("route");

    GeoDataStyleMap routeStyleMap;
    routeStyleMap.setStyleId("map-route");
    routeStyleMap.insert("normal", QString("#").append(routestyle.styleId()));
    doc->addStyleMap(routeStyleMap);
    doc->addStyle(routestyle);

    // routepoint style
    GeoDataStyle routepointStyle;
    routepointStyle.setStyleId("routepoint");

    GeoDataIconStyle routepointIconStyle;
    routepointIconStyle.setIconPath(MarbleDirs::path("bitmaps/city_4_white.png"));
    routepointIconStyle.setHotSpot(QPointF(0.5,0.5), GeoDataHotSpot::Fraction, GeoDataHotSpot::Fraction);
    routepointStyle.setIconStyle(routepointIconStyle);

    GeoDataLabelStyle routepointLabelStyle;
    routepointLabelStyle.setAlignment(GeoDataLabelStyle::Corner);
    routepointStyle.setLabelStyle(routepointLabelStyle);

    GeoDataStyleMap routepointStyleMap;
    routepointStyleMap.setStyleId("map-routepoint");
    routepointStyleMap.insert("normal", QString("#").append(routepointStyle.styleId()));
    doc->addStyleMap(routepointStyleMap);
    doc->addStyle(routepointStyle);

    // create a default style for waypoint icons
    GeoDataStyle waypointStyle;
    waypointStyle.setStyleId("waypoint");
    GeoDataIconStyle iconStyle;
    iconStyle.setIconPath(MarbleDirs::path("bitmaps/flag.png"));
    iconStyle.setHotSpot(QPointF(0.12,0.03), GeoDataHotSpot::Fraction, GeoDataHotSpot::Fraction);
    waypointStyle.setIconStyle(iconStyle);

    GeoDataLabelStyle waypointLabelStyle;
    waypointLabelStyle.setAlignment(GeoDataLabelStyle::Corner);
    waypointStyle.setLabelStyle(waypointLabelStyle);

    GeoDataStyleMap waypointStyleMap;
    waypointStyleMap.setStyleId("map-waypoint");
    waypointStyleMap.insert("normal", QString("#").append(waypointStyle.styleId()));
    doc->addStyleMap(waypointStyleMap);
    doc->addStyle(waypointStyle);

#ifdef DEBUG_TAGS
    mDebug() << "Parsed <" << gpxTag_gpx << "> document: " << doc;
#endif
    return doc;
}

}
}
<|endoftext|>


<commit_before>/**
 * File    : C.cpp
 * Author  : Kazune Takahashi
 * Created : 12/9/2018, 10:32:26 PM
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(19920725));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

const int C = 5000;
// const ll M = 1000000007;

int N, A;
int x[50];

ll DP[60][10000];

int main()
{
  cin >> N >> A;
  for (auto i = 0; i < N; i++)
  {
    cin >> x[i];
    x[i] -= A;
  }
  fill(&DP[0][0], &DP[0][0] + 60 * 10000, 0);
  DP[0][C] = 1;
  for (auto i = 0; i < N; i++)
  {
    for (auto j = 0; j < 10000; j++)
    {
      if (DP[i][j] == 0)
      {
        continue;
      }
      DP[i + 1][j + x[i]] += DP[i][j];
    }
  }
  cout << DP[N][C] << endl;
}<commit_msg>tried C.cpp to 'C'<commit_after>/**
 * File    : C.cpp
 * Author  : Kazune Takahashi
 * Created : 12/9/2018, 10:32:26 PM
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(19920725));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

const int C = 5000;
// const ll M = 1000000007;

int N, A;
int x[50];

ll DP[60][10000];

int main()
{
  cin >> N >> A;
  for (auto i = 0; i < N; i++)
  {
    cin >> x[i];
    x[i] -= A;
  }
  fill(&DP[0][0], &DP[0][0] + 60 * 10000, 0);
  DP[0][C] = 1;
  for (auto i = 0; i < N; i++)
  {
    for (auto j = 0; j < 10000; j++)
    {
      if (DP[i][j] == 0)
      {
        continue;
      }
      DP[i + 1][j] += DP[i][j];
      DP[i + 1][j + x[i]] += DP[i][j];
    }
  }
  cout << DP[N][C] << endl;
}<|endoftext|>


<commit_before>#include <experimental/filesystem>
#include <time.h>

#include <Util/Util.h>
#include <Network/PacketContainer.h>
#include <Logging/Logger.h>

#include "Network/GameConnection.h"
#include "Actor/Player.h"

#include "Session.h"
#include "Framework.h"

extern Core::Framework g_fw;
namespace fs = std::experimental::filesystem;

Core::Session::Session( uint32_t sessionId ) :
  m_sessionId( sessionId ),
  m_lastDataTime( Util::getTimeSeconds() ),
  m_lastSqlTime( Util::getTimeSeconds() ),
  m_isValid( false )
{
}

Core::Session::~Session()
{
}

void Core::Session::setZoneConnection( Network::GameConnectionPtr pZoneCon )
{
  pZoneCon->m_conType = Network::ConnectionType::Zone;
  m_pZoneConnection = pZoneCon;
}

void Core::Session::setChatConnection( Network::GameConnectionPtr pChatCon )
{
  pChatCon->m_conType = Network::ConnectionType::Chat;
  m_pChatConnection = pChatCon;
}

Core::Network::GameConnectionPtr Core::Session::getZoneConnection() const
{
  return m_pZoneConnection;
}

Core::Network::GameConnectionPtr Core::Session::getChatConnection() const
{
  return m_pChatConnection;
}

bool Core::Session::loadPlayer()
{

  m_pPlayer = Entity::make_Player();

  if( !m_pPlayer->load( m_sessionId, shared_from_this() ) )
  {
    m_isValid = false;
    return false;
  }

  m_isValid = true;

  return true;

}

void Core::Session::close()
{
  if( m_pZoneConnection )
    m_pZoneConnection->Disconnect();

  if( m_pChatConnection )
    m_pChatConnection->Disconnect();

  // remove the session from the player
  if( m_pPlayer )
    // reset the zone, so the zone handler knows to remove the actor
    m_pPlayer->setCurrentZone( nullptr );
}

uint32_t Core::Session::getId() const
{
  return m_sessionId;
}

int64_t Core::Session::getLastDataTime() const
{
  return m_lastDataTime;
}

int64_t Core::Session::getLastSqlTime() const
{
  return m_lastSqlTime;
}

bool Core::Session::isValid() const
{
  return m_isValid;
}

void Core::Session::updateLastDataTime()
{
  m_lastDataTime = Util::getTimeSeconds();
}

void Core::Session::updateLastSqlTime()
{
  m_lastSqlTime = Util::getTimeSeconds();
}

void Core::Session::startReplay( const std::string& path )
{
  auto pLog = g_fw.get< Logger >();
  if( !fs::exists( path ) )
  {
    getPlayer()->sendDebug( "Couldn't find folder." );
    return;
  }

  m_replayCache.clear();

  std::vector< std::tuple< uint64_t, std::string > > loadedSets;

  for( auto it = fs::directory_iterator( fs::path( path ) );
       it != fs::directory_iterator(); ++it )
  {
    // Get the filename of the current element
    auto fileName = it->path().filename().string();
    auto unixTime = std::stoull( fileName.substr( 0, 14 ).c_str() );

    if( unixTime > 1000000000 )
    {
      loadedSets.push_back( std::tuple< uint64_t, std::string >( unixTime, it->path().string() ) );
    }
  }

  sort( loadedSets.begin(), loadedSets.end(),
        []( const std::tuple< uint64_t, std::string >& left, const std::tuple< uint64_t, std::string >& right )
        {
          return std::get< 0 >( left ) < std::get< 0 >( right );
        } );

  uint64_t startTime = std::get< 0 >( loadedSets.at( 0 ) );

  for( auto set : loadedSets )
  {
    m_replayCache.push_back( std::tuple< uint64_t, std::string >(
      Util::getTimeMs() + ( std::get< 0 >( set ) - startTime ), std::get< 1 >( set ) ) );

    pLog->info( "Registering " + std::get< 1 >( set ) + " for " + std::to_string( std::get< 0 >( set ) - startTime ) );
  }

  getPlayer()->sendDebug( "Registered " + std::to_string( m_replayCache.size() ) + " sets for replay" );
  m_isReplaying = true;
}

void Core::Session::stopReplay()
{
  m_isReplaying = false;
  m_replayCache.clear();
}

void Core::Session::processReplay()
{
  int at = 0;
  for( const auto& set : m_replayCache )
  {
    if( std::get< 0 >( set ) <= Util::getTimeMs() )
    {
      m_pZoneConnection->injectPacket( std::get< 1 >( set ), *getPlayer().get() );
      m_replayCache.erase( m_replayCache.begin() + at );
      //g_framework.getLogger().info( "Sent for " + std::to_string( std::get< 0 >( set ) ) + ", left: " + std::to_string( m_replayCache.size() ) );
    }
    at++;
  }

  if( m_replayCache.size() == 0 )
    m_isReplaying = false;
}

void Core::Session::sendReplayInfo()
{
  std::string message = std::to_string( m_replayCache.size() ) + " Sets left in cache, ";

  if( m_isReplaying )
    message += " is active";
  else
    message += " is idle";

  getPlayer()->sendDebug( message );
}

void Core::Session::update()
{
  if( m_isReplaying )
    processReplay();

  if( m_pZoneConnection )
  {
    m_pZoneConnection->processInQueue();

    // SESSION LOGIC
    m_pPlayer->update( Util::getTimeMs() );

    if( ( static_cast< uint32_t >( Util::getTimeSeconds() ) - static_cast< uint32_t >( getLastSqlTime() ) ) > 10 )
    {
      updateLastSqlTime();
      m_pPlayer->updateSql();
    }

    m_pZoneConnection->processOutQueue();
  }

  if( m_pChatConnection )
  {
    m_pChatConnection->processInQueue();
    m_pChatConnection->processOutQueue();
  }

}

Core::Entity::PlayerPtr Core::Session::getPlayer() const
{
  return m_pPlayer;
}

<commit_msg>Sync chardata on session close<commit_after>#include <experimental/filesystem>
#include <time.h>

#include <Util/Util.h>
#include <Network/PacketContainer.h>
#include <Logging/Logger.h>

#include "Network/GameConnection.h"
#include "Actor/Player.h"

#include "Session.h"
#include "Framework.h"

extern Core::Framework g_fw;
namespace fs = std::experimental::filesystem;

Core::Session::Session( uint32_t sessionId ) :
  m_sessionId( sessionId ),
  m_lastDataTime( Util::getTimeSeconds() ),
  m_lastSqlTime( Util::getTimeSeconds() ),
  m_isValid( false )
{
}

Core::Session::~Session()
{
}

void Core::Session::setZoneConnection( Network::GameConnectionPtr pZoneCon )
{
  pZoneCon->m_conType = Network::ConnectionType::Zone;
  m_pZoneConnection = pZoneCon;
}

void Core::Session::setChatConnection( Network::GameConnectionPtr pChatCon )
{
  pChatCon->m_conType = Network::ConnectionType::Chat;
  m_pChatConnection = pChatCon;
}

Core::Network::GameConnectionPtr Core::Session::getZoneConnection() const
{
  return m_pZoneConnection;
}

Core::Network::GameConnectionPtr Core::Session::getChatConnection() const
{
  return m_pChatConnection;
}

bool Core::Session::loadPlayer()
{

  m_pPlayer = Entity::make_Player();

  if( !m_pPlayer->load( m_sessionId, shared_from_this() ) )
  {
    m_isValid = false;
    return false;
  }

  m_isValid = true;

  return true;

}

void Core::Session::close()
{
  if( m_pZoneConnection )
    m_pZoneConnection->Disconnect();

  if( m_pChatConnection )
    m_pChatConnection->Disconnect();

  // remove the session from the player
  if( m_pPlayer )
  {
    // do one last update to db
    m_pPlayer->updateSql();
    // reset the zone, so the zone handler knows to remove the actor
    m_pPlayer->setCurrentZone( nullptr );
  }
}

uint32_t Core::Session::getId() const
{
  return m_sessionId;
}

int64_t Core::Session::getLastDataTime() const
{
  return m_lastDataTime;
}

int64_t Core::Session::getLastSqlTime() const
{
  return m_lastSqlTime;
}

bool Core::Session::isValid() const
{
  return m_isValid;
}

void Core::Session::updateLastDataTime()
{
  m_lastDataTime = Util::getTimeSeconds();
}

void Core::Session::updateLastSqlTime()
{
  m_lastSqlTime = Util::getTimeSeconds();
}

void Core::Session::startReplay( const std::string& path )
{
  auto pLog = g_fw.get< Logger >();
  if( !fs::exists( path ) )
  {
    getPlayer()->sendDebug( "Couldn't find folder." );
    return;
  }

  m_replayCache.clear();

  std::vector< std::tuple< uint64_t, std::string > > loadedSets;

  for( auto it = fs::directory_iterator( fs::path( path ) );
       it != fs::directory_iterator(); ++it )
  {
    // Get the filename of the current element
    auto fileName = it->path().filename().string();
    auto unixTime = std::stoull( fileName.substr( 0, 14 ).c_str() );

    if( unixTime > 1000000000 )
    {
      loadedSets.push_back( std::tuple< uint64_t, std::string >( unixTime, it->path().string() ) );
    }
  }

  sort( loadedSets.begin(), loadedSets.end(),
        []( const std::tuple< uint64_t, std::string >& left, const std::tuple< uint64_t, std::string >& right )
        {
          return std::get< 0 >( left ) < std::get< 0 >( right );
        } );

  uint64_t startTime = std::get< 0 >( loadedSets.at( 0 ) );

  for( auto set : loadedSets )
  {
    m_replayCache.push_back( std::tuple< uint64_t, std::string >(
      Util::getTimeMs() + ( std::get< 0 >( set ) - startTime ), std::get< 1 >( set ) ) );

    pLog->info( "Registering " + std::get< 1 >( set ) + " for " + std::to_string( std::get< 0 >( set ) - startTime ) );
  }

  getPlayer()->sendDebug( "Registered " + std::to_string( m_replayCache.size() ) + " sets for replay" );
  m_isReplaying = true;
}

void Core::Session::stopReplay()
{
  m_isReplaying = false;
  m_replayCache.clear();
}

void Core::Session::processReplay()
{
  int at = 0;
  for( const auto& set : m_replayCache )
  {
    if( std::get< 0 >( set ) <= Util::getTimeMs() )
    {
      m_pZoneConnection->injectPacket( std::get< 1 >( set ), *getPlayer().get() );
      m_replayCache.erase( m_replayCache.begin() + at );
      //g_framework.getLogger().info( "Sent for " + std::to_string( std::get< 0 >( set ) ) + ", left: " + std::to_string( m_replayCache.size() ) );
    }
    at++;
  }

  if( m_replayCache.size() == 0 )
    m_isReplaying = false;
}

void Core::Session::sendReplayInfo()
{
  std::string message = std::to_string( m_replayCache.size() ) + " Sets left in cache, ";

  if( m_isReplaying )
    message += " is active";
  else
    message += " is idle";

  getPlayer()->sendDebug( message );
}

void Core::Session::update()
{
  if( m_isReplaying )
    processReplay();

  if( m_pZoneConnection )
  {
    m_pZoneConnection->processInQueue();

    // SESSION LOGIC
    m_pPlayer->update( Util::getTimeMs() );

    if( ( static_cast< uint32_t >( Util::getTimeSeconds() ) - static_cast< uint32_t >( getLastSqlTime() ) ) > 10 )
    {
      updateLastSqlTime();
      m_pPlayer->updateSql();
    }

    m_pZoneConnection->processOutQueue();
  }

  if( m_pChatConnection )
  {
    m_pChatConnection->processInQueue();
    m_pChatConnection->processOutQueue();
  }

}

Core::Entity::PlayerPtr Core::Session::getPlayer() const
{
  return m_pPlayer;
}

<|endoftext|>