diff --git a/CMakeLists.txt b/CMakeLists.txt index baeb7f1..641b77e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,8 @@ cmake_minimum_required(VERSION 3.5) -project(librcsc VERSION 2020.08) +project(librcsc VERSION 2023) -set(LIBRCSC_SOVERSION 16) # protocol version +set(LIBRCSC_SOVERSION 18) # protocol version set(LIBRCSC_BUILDVERSION ${LIBRCSC_SOVERSION}.0.0) if(CMAKE_VERSION VERSION_LESS "3.7.0") @@ -10,7 +10,7 @@ if(CMAKE_VERSION VERSION_LESS "3.7.0") endif() # compliler options -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) if(NOT CMAKE_BUILD_TYPE) @@ -48,7 +48,7 @@ check_cxx_symbol_exists(select sys/select.h HAVE_SELECT) check_cxx_symbol_exists(socket sys/socket.h HAVE_SOCKET) # boost -find_package(Boost 1.36.0 COMPONENTS system REQUIRED) +find_package(Boost 1.41.0 COMPONENTS system REQUIRED) if(NOT Boost_FOUND) message(FATAL_ERROR "Boost not found!") endif() diff --git a/README.md b/README.md index d1c2b6b..b68fdd3 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# Librcsc +# Librcsc [![License: LGPL v3](https://img.shields.io/badge/License-LGPL_v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0) librcsc is a basic library to develop a simulated soccer team and related tools for the RoboCup Soccer Simulation. -All programs can work with rcssserver-16. +All programs can work with rcssserver-18. - The RoboCup Soccer Simulator: https://rcsoccersim.github.io/ - RoboCup Official Homepage: https://www.robocup.org/ @@ -12,11 +12,12 @@ All programs can work with rcssserver-16. ## Quick Start The latest librcsc depends on the following libraries: - - Boost 1.38 or later https://www.boost.org/ + - C++17 + - Boost 1.41 or later https://www.boost.org/ - (optional) Doxygen - (optional) Graphviz -In the case of Ubuntu 16.04 or later, execute the following commands for installing a basic development environment: +In the case of Ubuntu 20.04 or later, execute the following commands for installing a basic development environment: ``` sudo apt update sudo apt install build-essential libboost-all-dev autoconf automake libtool @@ -29,7 +30,7 @@ To build the library, execute commands from the root of source directory: make ``` -Once successfully built, you can install the library file and header files to the default installation directory (``/usr/local``): +Once successfully built, you can install the library file and header files to the default installation directory (``/usr/local``): ``` sudo make install ``` @@ -94,4 +95,3 @@ This will remove all the files that where installed, but not any directories tha - Hidehisa Akiyama, Tomoharu Nakashima, HELIOS Base: An Open Source Package for the RoboCup Soccer 2D Simulation, In Sven Behnke, Manuela Veloso, Arnoud Visser, and Rong Xiong editors, RoboCup2013: Robot World XVII, Lecture Notes in Artificial Intelligence, Springer Verlag, Berlin, 2014. http://dx.doi.org/10.1007/978-3-662-44468-9_46 - Hidehisa Akiyama, Itsuki Noda, Multi-Agent Positioning Mechanism in the Dynamic Environment, In Ubbo Visser, Fernando Ribeiro, Takeshi Ohashi, and Frank Dellaert, editors, RoboCup 2007: Robot Soccer World Cup XI Lecture Notes in Artificial Intelligence, vol. 5001, Springer, pp.377-384, July 2008. https://doi.org/10.1007/978-3-540-68847-1_38 - diff --git a/configure.ac b/configure.ac index ad3989c..58368a1 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ(2.65) LT_PREREQ(2.2) -AC_INIT([librcsc],[rc2021],[akky@users.sourceforge.jp]) +AC_INIT([librcsc],[2023],[akky@users.sourceforge.jp]) #LT_PREREQ(2.2.4) @@ -121,13 +121,13 @@ AC_CHECK_FUNCS([memset pow rint select socket sqrt strerror strtol]) # check C++ ################################################## -AX_CXX_COMPILE_STDCXX_14(noext) +AX_CXX_COMPILE_STDCXX_17(noext) ################################################## # check boost ################################################## -AX_BOOST_BASE([1.38.0]) +AX_BOOST_BASE([1.41.0]) AX_BOOST_SYSTEM CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" @@ -213,7 +213,6 @@ AC_CONFIG_FILES([Doxyfile rcsc/util/Makefile rcsc/common/Makefile rcsc/player/Makefile - rcsc/action/Makefile rcsc/formation/Makefile rcsc/coach/Makefile rcsc/trainer/Makefile diff --git a/m4/ax_boost_base.m4 b/m4/ax_boost_base.m4 index d540395..b1fed7a 100644 --- a/m4/ax_boost_base.m4 +++ b/m4/ax_boost_base.m4 @@ -11,9 +11,9 @@ # Test for the Boost C++ libraries of a particular version (or newer) # # If no path to the installed boost library is given the macro searchs -# under /usr, /usr/local, /opt and /opt/local and evaluates the -# $BOOST_ROOT environment variable. Further documentation is available at -# . +# under /usr, /usr/local, /opt, /opt/local and /opt/homebrew and evaluates +# the $BOOST_ROOT environment variable. Further documentation is available +# at . # # This macro calls: # @@ -33,7 +33,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 45 +#serial 52 # example boost program (need to pass version) m4_define([_AX_BOOST_BASE_PROGRAM], @@ -113,7 +113,8 @@ AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ dnl are found, e.g. when only header-only libraries are installed! AS_CASE([${host_cpu}], [x86_64],[libsubdirs="lib64 libx32 lib lib64"], - [ppc64|powerpc64|s390x|sparc64|aarch64|ppc64le|powerpc64le|riscv64],[libsubdirs="lib64 lib lib64"], + [mips*64*],[libsubdirs="lib64 lib32 lib lib64"], + [ppc64|powerpc64|s390x|sparc64|aarch64|ppc64le|powerpc64le|riscv64|e2k|loongarch64],[libsubdirs="lib64 lib lib64"], [libsubdirs="lib"] ) @@ -122,11 +123,12 @@ AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ dnl are almost assuredly the ones desired. AS_CASE([${host_cpu}], [i?86],[multiarch_libsubdir="lib/i386-${host_os}"], + [armv7l],[multiarch_libsubdir="lib/arm-${host_os}"], [multiarch_libsubdir="lib/${host_cpu}-${host_os}"] ) dnl first we check the system location for boost libraries - dnl this location ist chosen if boost libraries are installed with the --layout=system option + dnl this location is chosen if boost libraries are installed with the --layout=system option dnl or if you install boost with RPM AS_IF([test "x$_AX_BOOST_BASE_boost_path" != "x"],[ AC_MSG_CHECKING([for boostlib >= $1 ($WANT_BOOST_VERSION) includes in "$_AX_BOOST_BASE_boost_path/include"]) @@ -149,7 +151,7 @@ AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ else search_libsubdirs="$multiarch_libsubdir $libsubdirs" fi - for _AX_BOOST_BASE_boost_path_tmp in /usr /usr/local /opt /opt/local ; do + for _AX_BOOST_BASE_boost_path_tmp in /usr /usr/local /opt /opt/local /opt/homebrew ; do if test -d "$_AX_BOOST_BASE_boost_path_tmp/include/boost" && test -r "$_AX_BOOST_BASE_boost_path_tmp/include/boost" ; then for libsubdir in $search_libsubdirs ; do if ls "$_AX_BOOST_BASE_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi @@ -225,7 +227,7 @@ AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ fi else if test "x$cross_compiling" != "xyes" ; then - for _AX_BOOST_BASE_boost_path in /usr /usr/local /opt /opt/local ; do + for _AX_BOOST_BASE_boost_path in /usr /usr/local /opt /opt/local /opt/homebrew ; do if test -d "$_AX_BOOST_BASE_boost_path" && test -r "$_AX_BOOST_BASE_boost_path" ; then for i in `ls -d $_AX_BOOST_BASE_boost_path/include/boost-* 2>/dev/null`; do _version_tmp=`echo $i | sed "s#$_AX_BOOST_BASE_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4 index 9e9eaed..8edf515 100644 --- a/m4/ax_cxx_compile_stdcxx.m4 +++ b/m4/ax_cxx_compile_stdcxx.m4 @@ -10,13 +10,13 @@ # # Check for baseline language coverage in the compiler for the specified # version of the C++ standard. If necessary, add switches to CXX and -# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) -# or '14' (for the C++14 standard). +# CXXCPP to enable support. VERSION may be '11', '14', '17', or '20' for +# the respective C++ standard version. # # The second argument, if specified, indicates whether you insist on an # extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. # -std=c++11). If neither is specified, you get whatever works, with -# preference for an extended mode. +# preference for no added switch, and then for an extended mode. # # The third argument, if specified 'mandatory' or if left unspecified, # indicates that baseline support for the specified C++ standard is @@ -34,13 +34,16 @@ # Copyright (c) 2015 Paul Norman # Copyright (c) 2015 Moritz Klammler # Copyright (c) 2016, 2018 Krzesimir Nowak +# Copyright (c) 2019 Enji Cooper +# Copyright (c) 2020 Jason Merrill +# Copyright (c) 2021 Jörn Heusipp # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 10 +#serial 18 dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro dnl (serial version number 13). @@ -49,6 +52,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], [$1], [14], [ax_cxx_compile_alternatives="14 1y"], [$1], [17], [ax_cxx_compile_alternatives="17 1z"], + [$1], [20], [ax_cxx_compile_alternatives="20"], [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$2], [], [], [$2], [ext], [], @@ -61,6 +65,16 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl AC_LANG_PUSH([C++])dnl ac_success=no + m4_if([$2], [], [dnl + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi]) + m4_if([$2], [noext], [], [dnl if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do @@ -90,9 +104,18 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl dnl HP's aCC needs +std=c++11 according to: dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf dnl Cray's crayCC needs "-h std=c++11" + dnl MSVC needs -std:c++NN for C++17 and later (default is C++14) for alternative in ${ax_cxx_compile_alternatives}; do - for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do + if test x"$switch" = xMSVC; then + dnl AS_TR_SH maps both `:` and `=` to `_` so -std:c++17 would collide + dnl with -std=c++17. We suffix the cache variable name with _MSVC to + dnl avoid this. + switch=-std:c++${alternative} + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_${switch}_MSVC]) + else + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + fi AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, [ac_save_CXX="$CXX" @@ -139,7 +162,6 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 ) - dnl Test body for checking C++14 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], @@ -147,12 +169,24 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ) +dnl Test body for checking C++17 support + m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 ) +dnl Test body for checking C++20 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_20 +) + + dnl Tests for new features in C++11 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ @@ -164,7 +198,11 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ #error "This is not a C++ compiler" -#elif __cplusplus < 201103L +// MSVC always sets __cplusplus to 199711L in older versions; newer versions +// only set it correctly if /Zc:__cplusplus is specified as well as a +// /std:c++NN switch: +// https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ +#elif __cplusplus < 201103L && !defined _MSC_VER #error "This is not a C++11 compiler" @@ -189,11 +227,13 @@ namespace cxx11 struct Base { + virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { + virtual ~Derived() override {} virtual void f() override {} }; @@ -453,7 +493,7 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ #error "This is not a C++ compiler" -#elif __cplusplus < 201402L +#elif __cplusplus < 201402L && !defined _MSC_VER #error "This is not a C++14 compiler" @@ -577,7 +617,7 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ #error "This is not a C++ compiler" -#elif __cplusplus < 201703L +#elif __cplusplus < 201703L && !defined _MSC_VER #error "This is not a C++17 compiler" @@ -943,6 +983,36 @@ namespace cxx17 } // namespace cxx17 -#endif // __cplusplus < 201703L +#endif // __cplusplus < 201703L && !defined _MSC_VER + +]]) + + +dnl Tests for new features in C++20 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[ + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 202002L && !defined _MSC_VER + +#error "This is not a C++20 compiler" + +#else + +#include + +namespace cxx20 +{ + +// As C++20 supports feature test macros in the standard, there is no +// immediate need to actually test for feature availability on the +// Autoconf side. + +} // namespace cxx20 + +#endif // __cplusplus < 202002L && !defined _MSC_VER ]]) diff --git a/m4/ax_cxx_compile_stdcxx_17.m4 b/m4/ax_cxx_compile_stdcxx_17.m4 new file mode 100644 index 0000000..a683417 --- /dev/null +++ b/m4/ax_cxx_compile_stdcxx_17.m4 @@ -0,0 +1,35 @@ +# ============================================================================= +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_17.html +# ============================================================================= +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX_17([ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the C++17 +# standard; if necessary, add switches to CXX and CXXCPP to enable +# support. +# +# This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX +# macro with the version set to C++17. The two optional arguments are +# forwarded literally as the second and third argument respectively. +# Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for +# more information. If you want to use this macro, you also need to +# download the ax_cxx_compile_stdcxx.m4 file. +# +# LICENSE +# +# Copyright (c) 2015 Moritz Klammler +# Copyright (c) 2016 Krzesimir Nowak +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 2 + +AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX]) +AC_DEFUN([AX_CXX_COMPILE_STDCXX_17], [AX_CXX_COMPILE_STDCXX([17], [$1], [$2])]) diff --git a/rcsc/player/interception.cpp b/obsolete/newton_method_interception.cpp similarity index 100% rename from rcsc/player/interception.cpp rename to obsolete/newton_method_interception.cpp diff --git a/rcsc/player/interception.h b/obsolete/newton_method_interception.h similarity index 100% rename from rcsc/player/interception.h rename to obsolete/newton_method_interception.h diff --git a/rcsc/CMakeLists.txt b/rcsc/CMakeLists.txt index fba75a3..48867d7 100644 --- a/rcsc/CMakeLists.txt +++ b/rcsc/CMakeLists.txt @@ -15,7 +15,6 @@ add_subdirectory(color) add_subdirectory(common) add_subdirectory(monitor) add_subdirectory(player) -add_subdirectory(action) add_subdirectory(coach) add_subdirectory(trainer) @@ -35,7 +34,6 @@ add_library(rcsc SHARED $ $ $ - $ $ $ ) diff --git a/rcsc/Makefile.am b/rcsc/Makefile.am index 718a898..c15db81 100644 --- a/rcsc/Makefile.am +++ b/rcsc/Makefile.am @@ -15,7 +15,6 @@ SUBDIRS = \ common \ monitor \ player \ - action \ coach \ trainer \ . @@ -39,7 +38,6 @@ librcsc_la_LIBADD = \ formation/librcsc_formation.la \ monitor/librcsc_monitor.la \ player/librcsc_player.la \ - action/librcsc_action.la \ coach/librcsc_coach.la \ trainer/librcsc_trainer.la @@ -59,7 +57,7 @@ librcsc_la_LIBADD = \ ## action/librcsc_action_obsolete.la -librcsc_la_LDFLAGS = -version-info 16:0:0 +librcsc_la_LDFLAGS = -version-info 18:0:0 #libXXXX_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) # 1. Start with version information of `0:0:0' for each libtool library. # diff --git a/rcsc/action/bhv_go_to_point_look_ball.cpp b/rcsc/action/bhv_go_to_point_look_ball.cpp index 60a85d6..dbd40af 100644 --- a/rcsc/action/bhv_go_to_point_look_ball.cpp +++ b/rcsc/action/bhv_go_to_point_look_ball.cpp @@ -129,8 +129,8 @@ Bhv_GoToPointLookBall::execute( PlayerAgent * agent ) // back dash double dash_power = wm.self().getSafetyDashPower( wm.self().goalie() - ? M_dash_power - : M_dash_power * M_back_power_rate ); + ? -M_dash_power + : -M_dash_power * M_back_power_rate ); agent->doDash( dash_power ); agent->setNeckAction( new Neck_TurnToBall() ); } diff --git a/rcsc/coach/coach_agent.cpp b/rcsc/coach/coach_agent.cpp index 78e4ba4..0b31217 100644 --- a/rcsc/coach/coach_agent.cpp +++ b/rcsc/coach/coach_agent.cpp @@ -506,9 +506,9 @@ CoachAgent::initImpl( CmdLineParser & cmd_parser ) M_config.parse( cmd_parser ); if ( config().version() < 1.0 - || 18.0 <= config().version() ) + || MAX_PROTOCOL_VERSION < config().version() ) { - std::cerr << "Unsupported client version: " << config().version() + std::cerr << "(CoachAgent::initImpl) Unsupported client version: " << config().version() << std::endl; return false; } diff --git a/rcsc/common/logger.cpp b/rcsc/common/logger.cpp index 80c84e4..236214e 100644 --- a/rcsc/common/logger.cpp +++ b/rcsc/common/logger.cpp @@ -68,7 +68,9 @@ Logger dlog; Logger::Logger() : M_time( nullptr ), M_fout( nullptr ), - M_flags( 0 ) + M_flags( 0 ), + M_start_time( -1 ), + M_end_time( 99999999 ) { g_str.reserve( 8192 * 4 ); std::strcpy( g_buffer, "" ); @@ -104,6 +106,15 @@ Logger::setLogFlag( const GameTime * time, } } +/*-------------------------------------------------------------------*/ +void +Logger::setTimeRange( const int start_time, + const int end_time ) +{ + M_start_time = start_time; + M_end_time = end_time; +} + /*-------------------------------------------------------------------*/ /*! @@ -196,7 +207,9 @@ Logger::addText( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { va_list argp; va_start( argp, msg ); @@ -231,7 +244,9 @@ Logger::addPoint( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char msg[128]; snprintf( msg, 128, "%ld,%ld %d p %.4f %.4f ", @@ -260,7 +275,9 @@ Logger::addPoint( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char msg[128]; snprintf( msg, 128, "%ld,%ld %d p %.4f %.4f #%02x%02x%02x", @@ -288,7 +305,9 @@ Logger::addLine( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char msg[128]; snprintf( msg, 128, "%ld,%ld %d l %.4f %.4f %.4f %.4f ", @@ -319,7 +338,9 @@ Logger::addLine( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char msg[128]; snprintf( msg, 128, "%ld,%ld %d l %.4f %.4f %.4f %.4f #%02x%02x%02x", @@ -348,7 +369,9 @@ Logger::addArc( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char msg[128]; snprintf( msg, 128, "%ld,%ld %d a %.4f %.4f %.4f %.4f %.4f ", @@ -383,7 +406,9 @@ Logger::addArc( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char msg[128]; snprintf( msg, 128, "%ld,%ld %d a %.4f %.4f %.4f %.4f %.4f #%02x%02x%02x", @@ -411,7 +436,9 @@ Logger::addCircle( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char msg[128]; snprintf( msg, 128, "%ld,%ld %d %c %.4f %.4f %.4f ", @@ -443,7 +470,9 @@ Logger::addCircle( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char msg[128]; snprintf( msg, 128, "%ld,%ld %d %c %.4f %.4f %.4f #%02x%02x%02x", @@ -475,7 +504,9 @@ Logger::addTriangle( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char msg[128]; snprintf( msg, 128, "%ld,%ld %d %c %.4f %.4f %.4f %.4f %.4f %.4f ", @@ -510,7 +541,9 @@ Logger::addTriangle( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char msg[128]; snprintf( msg, 128, "%ld,%ld %d %c %.4f %.4f %.4f %.4f %.4f %.4f #%02x%02x%02x", @@ -540,7 +573,9 @@ Logger::addRect( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char msg[128]; snprintf( msg, 128, "%ld,%ld %d %c %.4f %.4f %.4f %.4f ", @@ -573,7 +608,9 @@ Logger::addRect( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char msg[128]; snprintf( msg, 128, "%ld,%ld %d %c %.4f %.4f %.4f %.4f #%02x%02x%02x", @@ -605,7 +642,9 @@ Logger::addSector( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char msg[128]; snprintf( msg, 128, "%ld,%ld %d %c %.4f %.4f %.4f %.4f %.4f %.4f ", @@ -641,7 +680,9 @@ Logger::addSector( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char msg[128]; snprintf( msg, 128, "%ld,%ld %d %c %.4f %.4f %.4f %.4f %.4f %.4f #%02x%02x%02x", @@ -669,7 +710,9 @@ Logger::addSector( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char msg[128]; double span_angle = ( sector.angleLeftStart().isLeftOf( sector.angleRightEnd() ) @@ -704,7 +747,9 @@ Logger::addSector( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char msg[128]; double span_angle = ( sector.angleLeftStart().isLeftOf( sector.angleRightEnd() ) @@ -737,7 +782,9 @@ Logger::addMessage( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char header[128]; snprintf( header, 128, "%ld,%ld %d m %.4f %.4f ", @@ -772,7 +819,9 @@ Logger::addMessage( const std::int32_t level, { if ( M_fout && M_time - && ( level & M_flags ) ) + && ( level & M_flags ) + && M_start_time <= M_time->cycle() + && M_time->cycle() <= M_end_time ) { char header[128]; snprintf( header, 128, "%ld,%ld %d m %.4f %.4f ", diff --git a/rcsc/common/logger.h b/rcsc/common/logger.h index ee9272e..c03a01a 100644 --- a/rcsc/common/logger.h +++ b/rcsc/common/logger.h @@ -155,6 +155,9 @@ class Logger { //! log level flag std::int32_t M_flags; + int M_start_time; + int M_end_time; + public: /*! \brief allocate message buffer memory @@ -176,6 +179,14 @@ class Logger { const std::int32_t level, const bool on = true ); + /*! + \brief set the range of the recorded game time + \param start_time lower value + \param end_time higher value + */ + void setTimeRange( const int start_time, + const int end_time ); + /*! \brief check if the level is enabled \param level checked log level diff --git a/rcsc/common/player_type.cpp b/rcsc/common/player_type.cpp index ea69892..6f94dba 100644 --- a/rcsc/common/player_type.cpp +++ b/rcsc/common/player_type.cpp @@ -353,6 +353,21 @@ PlayerType::setDefault() M_kick_power_rate = SP.kickPowerRate(); M_foul_detect_probability = SP.foulDetectProbability(); M_catchable_area_l_stretch = 1.0; + + const double maximum_dist_in_pitch = std::sqrt( std::pow( ServerParam::DEFAULT_PITCH_LENGTH, 2 ) + + std::pow( ServerParam::DEFAULT_PITCH_WIDTH, 2 ) ); + // v18 + M_unum_far_length = 20.0; + M_unum_too_far_length = 40.0; + M_team_far_length = maximum_dist_in_pitch; + M_team_too_far_length = maximum_dist_in_pitch; + M_player_max_observation_length = maximum_dist_in_pitch; + M_ball_vel_far_length = 20.0; + M_ball_vel_too_far_length = 40.0; + M_ball_max_observation_length = maximum_dist_in_pitch; + M_flag_chg_far_length = 20.0; + M_flag_chg_too_far_length = 40.0; + M_flag_max_observation_length = maximum_dist_in_pitch; } /*-------------------------------------------------------------------*/ @@ -463,6 +478,50 @@ PlayerType::parseV8( const char * msg ) { M_catchable_area_l_stretch = val; } + else if ( ! std::strcmp( name, "unum_far_length" ) ) + { + M_unum_far_length = val; + } + else if ( ! std::strcmp( name, "unum_too_far_length" ) ) + { + M_unum_too_far_length = val; + } + else if ( ! std::strcmp( name, "team_far_length" ) ) + { + M_team_far_length = val; + } + else if ( ! std::strcmp( name, "team_too_far_length" ) ) + { + M_team_too_far_length = val; + } + else if ( ! std::strcmp( name, "player_max_observation_length" ) ) + { + M_player_max_observation_length = val; + } + else if ( ! std::strcmp( name, "ball_vel_far_length" ) ) + { + M_ball_vel_far_length = val; + } + else if ( ! std::strcmp( name, "ball_vel_too_far_length" ) ) + { + M_ball_vel_too_far_length = val; + } + else if ( ! std::strcmp( name, "ball_max_observation_length" ) ) + { + M_ball_max_observation_length = val; + } + else if ( ! std::strcmp( name, "flag_chg_far_length" ) ) + { + M_flag_chg_far_length = val; + } + else if ( ! std::strcmp( name, "flag_chg_too_far_length" ) ) + { + M_flag_chg_too_far_length = val; + } + else if ( ! std::strcmp( name, "flag_max_observation_length" ) ) + { + M_flag_max_observation_length = val; + } else { std::cerr << __FILE__ << ":(PlayerType::parseV8) " @@ -957,6 +1016,25 @@ PlayerType::cyclesToReachDistance( const double & dash_dist ) const return cycle; } +/*-------------------------------------------------------------------*/ +double +PlayerType::getMovableDistance( const size_t step ) const +{ + if ( step == 0 ) + { + return 0.0; + } + + size_t index = step - 1; + if ( index >= M_dash_distance_table.size() ) + { + return M_dash_distance_table.back() + + realSpeedMax() * ( index - M_dash_distance_table.size() + 1 ); + } + + return M_dash_distance_table[index]; +} + /*-------------------------------------------------------------------*/ /*! diff --git a/rcsc/common/player_type.h b/rcsc/common/player_type.h index 1535923..a30ac0c 100644 --- a/rcsc/common/player_type.h +++ b/rcsc/common/player_type.h @@ -65,6 +65,18 @@ class PlayerType { double M_kick_power_rate; //!< kick power rate double M_foul_detect_probability; //!< foul detect probability double M_catchable_area_l_stretch; //!< catch area length stretch factor + // v18 + double M_unum_far_length; //!< Distance where the uniform number becomes ambiguous in see message + double M_unum_too_far_length; //!< Distance where the uniform number becomes completely unobservable + double M_team_far_length; //!< Distance where the team information becomes ambiguous in see message + double M_team_too_far_length; //!< Distance where the team information becomes completely unobservable + double M_player_max_observation_length; //!< Maximum distance where players can be observed + double M_ball_vel_far_length; //!< Distance where the ball relatie velocity becomes ambiguous in see message + double M_ball_vel_too_far_length; //!< Distance where the ball relative velocityr becomes completely unobservable + double M_ball_max_observation_length; //!< Maximum distance where the ball can be observed + double M_flag_chg_far_length; //!< Distance where the flag relative velocity becomes ambiguous in see message + double M_flag_chg_too_far_length;//!< Distance where the flag relative velocityr becomes completely unobservable + double M_flag_max_observation_length; //!< Maximum distance where the flag can be observed // // additional parameters @@ -300,6 +312,105 @@ class PlayerType { return M_catchable_area_l_stretch; } + /*! + \brief get the player_type parameter + \return player_type parameter + */ + double unumFarLength() const + { + return M_unum_far_length; + } + + /*! + \brief get the player_type parameter + \return player_type parameter + */ + double unumTooFarLength() const + { + return M_unum_too_far_length; + } + + /*! + \brief get the player_type parameter + \return player_type parameter + */ + double teamFarLength() const + { + return M_team_far_length; + } + + /*! + \brief get the player_type parameter + \return player_type parameter + */ + double teamTooFarLength() const + { + return M_team_too_far_length; + } + + /*! + \brief get the player_type parameter + \return player_type parameter + */ + double playerMaxObservationLength() const + { + return M_player_max_observation_length; + } + + /*! + \brief get the player_type parameter + \return player_type parameter + */ + double ballVelFarLength() const + { + return M_ball_vel_far_length; + } + + /*! + \brief get the player_type parameter + \return player_type parameter + */ + double ballVelTooFarLength() const + { + return M_ball_vel_too_far_length; + } + + /*! + \brief get the player_type parameter + \return player_type parameter + */ + double ballMaxObservationLength() const + { + return M_ball_max_observation_length; + } + + /*! + \brief get the player_type parameter + \return player_type parameter + */ + double flagChgFarLength() const + { + return M_flag_chg_far_length; + } + + /*! + \brief get the player_type parameter + \return player_type parameter + */ + double flagChgTooFarLength() const + { + return M_flag_chg_too_far_length; + } + + /*! + \brief get the player_type parameter + \return player_type parameter + */ + double flagMaxObservationLength() const + { + return M_flag_max_observation_length; + } + //////////////////////////////////////////////// // additional parameters @@ -460,6 +571,8 @@ class PlayerType { \return estimated cycles to reach */ int cyclesToReachDistance( const double & dash_dist ) const; + + double getMovableDistance( const size_t step ) const; //////////////////////////////////////////////// /*! \brief check if this type player can over player_speed_max diff --git a/rcsc/formation/formation_parser.cpp b/rcsc/formation/formation_parser.cpp index 443a600..41d0afe 100644 --- a/rcsc/formation/formation_parser.cpp +++ b/rcsc/formation/formation_parser.cpp @@ -44,9 +44,17 @@ namespace rcsc { Formation::Ptr FormationParser::parse( const std::string & filepath ) { - std::ifstream fin( filepath.c_str() ); + FormationParser::Ptr parser = create( filepath ); + + if ( ! parser ) + { + std::cerr << "ERROR (FormationParser::parse) could not create the formation parser instance." + << std::endl; + return Formation::Ptr(); + } - return parse( fin ); + std::ifstream fin( filepath ); + return parser->parseImpl( fin ); } /*-------------------------------------------------------------------*/ diff --git a/rcsc/formation/formation_parser.h b/rcsc/formation/formation_parser.h index a74eab0..ba57201 100644 --- a/rcsc/formation/formation_parser.h +++ b/rcsc/formation/formation_parser.h @@ -76,12 +76,7 @@ class FormationParser { virtual std::string name() const = 0; - /*! - \brief parse the given file - \param filepath the file path to be parsed - \return formation instance - */ - Formation::Ptr parse( const std::string & filepath ); +protected: /*! \brief parse the input stream @@ -89,9 +84,7 @@ class FormationParser { \return formation instance */ virtual - Formation::Ptr parse( std::istream & is ) = 0; - -protected: + Formation::Ptr parseImpl( std::istream & is ) = 0; /*! \brief check the consistency of role names @@ -105,14 +98,24 @@ class FormationParser { */ bool checkPositionPair( const Formation::ConstPtr ptr ); -public: + +private: /*! \brief create formation parser instance according to the header data \param filepath the path string of the input file \return formation parser instance */ - static FormationParser::Ptr create( const std::string & filepath ); + static FormationParser::Ptr create( const std::string & filepath ); + +public: + + /*! + \brief parse the given file + \param filepath the file path to be parsed + \return formation instance + */ + static Formation::Ptr parse( const std::string & filepath ); }; diff --git a/rcsc/formation/formation_parser_csv.cpp b/rcsc/formation/formation_parser_csv.cpp index 2098211..e0d5434 100644 --- a/rcsc/formation/formation_parser_csv.cpp +++ b/rcsc/formation/formation_parser_csv.cpp @@ -66,7 +66,7 @@ get_value_line( std::istream & is ) /*-------------------------------------------------------------------*/ Formation::Ptr -FormationParserCSV::parse( std::istream & is ) +FormationParserCSV::parseImpl( std::istream & is ) { const std::string method = parseMethodName( is ); diff --git a/rcsc/formation/formation_parser_csv.h b/rcsc/formation/formation_parser_csv.h index 86b9784..b8b44bb 100644 --- a/rcsc/formation/formation_parser_csv.h +++ b/rcsc/formation/formation_parser_csv.h @@ -66,12 +66,14 @@ class FormationParserCSV return "csv"; } +protected: + /*! \brief parse the input stream \param is reference to the input stream to be parsed \return formation instance */ - Formation::Ptr parse( std::istream & is ) override; + Formation::Ptr parseImpl( std::istream & is ) override; private: std::string parseMethodName( std::istream & is ); diff --git a/rcsc/formation/formation_parser_json.cpp b/rcsc/formation/formation_parser_json.cpp index d93ccaf..af4fa9f 100644 --- a/rcsc/formation/formation_parser_json.cpp +++ b/rcsc/formation/formation_parser_json.cpp @@ -48,13 +48,28 @@ namespace { /*-------------------------------------------------------------------*/ std::string -parse_method_name( const ptree & doc ) +get_version( const ptree & doc ) +{ + boost::optional< std::string > v = doc.get_optional< std::string >( "version" ); + + if ( ! v ) + { + std::cerr << "(FormationParserJSON::get_version) No version" << std::endl; + return std::string(); + } + + return *v; +} + +/*-------------------------------------------------------------------*/ +std::string +get_method_name( const ptree & doc ) { boost::optional< std::string > v = doc.get_optional< std::string >( "method" ); if ( ! v ) { - std::cerr << "(FormationParserJSON..parse_method_name) No method name" << std::endl; + std::cerr << "(FormationParserJSON::get_method_name) No method name" << std::endl; return std::string(); } @@ -177,7 +192,7 @@ parse_data( const ptree & doc, /*-------------------------------------------------------------------*/ Formation::Ptr -FormationParserJSON::parse( std::istream & is ) +FormationParserJSON::parseImpl( std::istream & is ) { ptree doc; try @@ -190,7 +205,7 @@ FormationParserJSON::parse( std::istream & is ) return Formation::Ptr(); } - const std::string method = parse_method_name( doc ); + const std::string method = get_method_name( doc ); Formation::Ptr ptr = Formation::create( method ); if ( ! ptr ) @@ -199,6 +214,8 @@ FormationParserJSON::parse( std::istream & is ) return Formation::Ptr(); } + ptr->setVersion( get_version( doc ) ); + if ( ! parse_role( doc, ptr ) ) return Formation::Ptr(); if ( ! parse_data( doc, ptr ) ) return Formation::Ptr(); diff --git a/rcsc/formation/formation_parser_json.h b/rcsc/formation/formation_parser_json.h index ea60eb9..e4b952b 100644 --- a/rcsc/formation/formation_parser_json.h +++ b/rcsc/formation/formation_parser_json.h @@ -66,12 +66,14 @@ class FormationParserJSON return "json"; } +protected: + /*! \brief parse the input stream \param is reference to the input stream to be parsed \return formation instance */ - Formation::Ptr parse( std::istream & is ) override; + Formation::Ptr parseImpl( std::istream & is ) override; }; diff --git a/rcsc/formation/formation_parser_static.cpp b/rcsc/formation/formation_parser_static.cpp index a3a65c2..d39b7c8 100644 --- a/rcsc/formation/formation_parser_static.cpp +++ b/rcsc/formation/formation_parser_static.cpp @@ -43,7 +43,7 @@ namespace rcsc { /*-------------------------------------------------------------------*/ Formation::Ptr -FormationParserStatic::parse( std::istream & is ) +FormationParserStatic::parseImpl( std::istream & is ) { Formation::Ptr ptr( new FormationStatic() ); diff --git a/rcsc/formation/formation_parser_static.h b/rcsc/formation/formation_parser_static.h index 70c0c25..fc7bcb0 100644 --- a/rcsc/formation/formation_parser_static.h +++ b/rcsc/formation/formation_parser_static.h @@ -66,12 +66,14 @@ class FormationParserStatic return "static"; } +protected: + /*! \brief parse the input stream \param is reference to the input stream to be parsed \return formation instance */ - Formation::Ptr parse( std::istream & is ) override; + Formation::Ptr parseImpl( std::istream & is ) override; private: diff --git a/rcsc/formation/formation_parser_v1.cpp b/rcsc/formation/formation_parser_v1.cpp index 5dad420..3d383b2 100644 --- a/rcsc/formation/formation_parser_v1.cpp +++ b/rcsc/formation/formation_parser_v1.cpp @@ -39,7 +39,7 @@ namespace rcsc { /*-------------------------------------------------------------------*/ Formation::Ptr -FormationParserV1::parse( std::istream & is ) +FormationParserV1::parseImpl( std::istream & is ) { const std::string method = parseHeader( is ); diff --git a/rcsc/formation/formation_parser_v1.h b/rcsc/formation/formation_parser_v1.h index a6e6b86..11a342b 100644 --- a/rcsc/formation/formation_parser_v1.h +++ b/rcsc/formation/formation_parser_v1.h @@ -66,12 +66,14 @@ class FormationParserV1 return "v1"; } +protected: + /*! \brief parse the input stream \param is reference to the input stream to be parsed \return formation instance */ - Formation::Ptr parse( std::istream & is ) override; + Formation::Ptr parseImpl( std::istream & is ) override; private: std::string parseHeader( std::istream & is ); diff --git a/rcsc/formation/formation_parser_v2.cpp b/rcsc/formation/formation_parser_v2.cpp index dd33239..855e1fb 100644 --- a/rcsc/formation/formation_parser_v2.cpp +++ b/rcsc/formation/formation_parser_v2.cpp @@ -41,7 +41,7 @@ namespace rcsc { /*-------------------------------------------------------------------*/ Formation::Ptr -FormationParserV2::parse( std::istream & is ) +FormationParserV2::parseImpl( std::istream & is ) { const std::string method = parseHeader( is ); diff --git a/rcsc/formation/formation_parser_v2.h b/rcsc/formation/formation_parser_v2.h index 53942ee..c63c9d2 100644 --- a/rcsc/formation/formation_parser_v2.h +++ b/rcsc/formation/formation_parser_v2.h @@ -67,12 +67,14 @@ class FormationParserV2 return "v2"; } +protected: + /*! \brief parse the input stream \param is reference to the input stream to be parsed \return formation instance */ - Formation::Ptr parse( std::istream & is ) override; + Formation::Ptr parseImpl( std::istream & is ) override; private: diff --git a/rcsc/formation/formation_parser_v3.cpp b/rcsc/formation/formation_parser_v3.cpp index 1a53bb8..9ddd7b3 100644 --- a/rcsc/formation/formation_parser_v3.cpp +++ b/rcsc/formation/formation_parser_v3.cpp @@ -39,7 +39,7 @@ namespace rcsc { /*-------------------------------------------------------------------*/ Formation::Ptr -FormationParserV3::parse( std::istream & is ) +FormationParserV3::parseImpl( std::istream & is ) { const std::string method = parseHeader( is ); @@ -302,7 +302,23 @@ FormationParserV3::parseData( std::istream & is, } } - return true; + std::string line; + while ( std::getline( is, line ) ) + { + if ( line.empty() + || line[0] == '#' + || ! line.compare( 0, 2, "//" ) ) + { + continue; + } + + if ( ! line.compare( 0, 13, "End Samples" ) ) + { + return true; + } + } + + return false; } /*-------------------------------------------------------------------*/ diff --git a/rcsc/formation/formation_parser_v3.h b/rcsc/formation/formation_parser_v3.h index d9b0402..d4d26f5 100644 --- a/rcsc/formation/formation_parser_v3.h +++ b/rcsc/formation/formation_parser_v3.h @@ -67,12 +67,14 @@ class FormationParserV3 return "v3"; } +protected: + /*! \brief parse the input stream \param is reference to the input stream to be parsed \return formation instance */ - Formation::Ptr parse( std::istream & is ) override; + Formation::Ptr parseImpl( std::istream & is ) override; private: diff --git a/rcsc/math_util.h b/rcsc/math_util.h index bc4ace1..4bd81c0 100644 --- a/rcsc/math_util.h +++ b/rcsc/math_util.h @@ -38,7 +38,7 @@ namespace rcsc { //! epsilon value -static const double EPS = 1.0e-10; +constexpr double EPS = 1.0e-10; /*-------------------------------------------------------------------*/ /*! diff --git a/rcsc/player/CMakeLists.txt b/rcsc/player/CMakeLists.txt index 46d0f6f..c5a0867 100644 --- a/rcsc/player/CMakeLists.txt +++ b/rcsc/player/CMakeLists.txt @@ -7,6 +7,9 @@ add_library(rcsc_player OBJECT body_sensor.cpp debug_client.cpp fullstate_sensor.cpp + intercept.cpp + intercept_simulator_player.cpp + intercept_simulator_self_v17.cpp intercept_table.cpp localization_default.cpp object_table.cpp @@ -14,12 +17,10 @@ add_library(rcsc_player OBJECT player_command.cpp player_agent.cpp player_config.cpp - player_intercept.cpp player_object.cpp player_state.cpp say_message_builder.cpp see_state.cpp - self_intercept_simulator.cpp self_object.cpp soccer_action.cpp view_grid_map.cpp @@ -29,8 +30,6 @@ add_library(rcsc_player OBJECT ) target_include_directories(rcsc_player - PUBLIC - ${Boost_INCLUDE_DIRS} PRIVATE ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR} @@ -45,6 +44,10 @@ install(FILES debug_client.h free_message.h fullstate_sensor.h + intercept.h + intercept_simulator_player.h + intercept_simulator_self.h + intercept_simulator_self_v17.h intercept_table.h localization.h localization_default.h @@ -54,13 +57,11 @@ install(FILES player_agent.h player_config.h player_evaluator.h - player_intercept.h player_object.h player_predicate.h player_state.h say_message_builder.h see_state.h - self_intercept_simulator.h self_object.h soccer_action.h soccer_intention.h diff --git a/rcsc/player/Makefile.am b/rcsc/player/Makefile.am index 454a3e2..bdadaa8 100644 --- a/rcsc/player/Makefile.am +++ b/rcsc/player/Makefile.am @@ -10,6 +10,9 @@ librcsc_player_la_SOURCES = \ body_sensor.cpp \ debug_client.cpp \ fullstate_sensor.cpp \ + intercept.cpp \ + intercept_simulator_player.cpp \ + intercept_simulator_self_v17.cpp \ intercept_table.cpp \ localization_default.cpp \ object_table.cpp \ @@ -17,12 +20,10 @@ librcsc_player_la_SOURCES = \ player_command.cpp \ player_agent.cpp \ player_config.cpp \ - player_intercept.cpp \ player_object.cpp \ player_state.cpp \ say_message_builder.cpp \ see_state.cpp \ - self_intercept_simulator.cpp \ self_object.cpp \ soccer_action.cpp \ view_grid_map.cpp \ @@ -30,9 +31,6 @@ librcsc_player_la_SOURCES = \ visual_sensor.cpp \ world_model.cpp -# ball_state.cpp - - librcsc_playerincludedir = $(includedir)/rcsc/player librcsc_playerinclude_HEADERS = \ @@ -44,6 +42,10 @@ librcsc_playerinclude_HEADERS = \ debug_client.h \ free_message.h \ fullstate_sensor.h \ + intercept.h \ + intercept_simulator_player.h \ + intercept_simulator_self.h \ + intercept_simulator_self_v17.h \ intercept_table.h \ localization.h \ localization_default.h \ @@ -53,13 +55,11 @@ librcsc_playerinclude_HEADERS = \ player_agent.h \ player_config.h \ player_evaluator.h \ - player_intercept.h \ player_object.h \ player_predicate.h \ player_state.h \ say_message_builder.h \ see_state.h \ - self_intercept_simulator.h \ self_object.h \ soccer_action.h \ soccer_intention.h \ @@ -69,9 +69,6 @@ librcsc_playerinclude_HEADERS = \ visual_sensor.h \ world_model.h -# ball_state.h - - AM_CPPFLAGS = -I$(top_srcdir) AM_CFLAGS = -Wall -W AM_CXXFLAGS = -Wall -W diff --git a/rcsc/player/action_effector.cpp b/rcsc/player/action_effector.cpp index a2878c0..b38fc51 100644 --- a/rcsc/player/action_effector.cpp +++ b/rcsc/player/action_effector.cpp @@ -57,6 +57,7 @@ ActionEffector::ActionEffector( const PlayerAgent & agent ) M_command_body( nullptr ), M_command_turn_neck( nullptr ), M_command_change_view( nullptr ), + M_command_change_focus( nullptr ), M_command_say( nullptr ), M_command_pointto( nullptr ), M_command_attentionto( nullptr ), @@ -115,6 +116,12 @@ ActionEffector::~ActionEffector() M_command_change_view = nullptr; } + if ( M_command_change_focus ) + { + delete M_command_change_focus; + M_command_change_focus = nullptr; + } + if ( M_command_say ) { delete M_command_say; @@ -384,6 +391,22 @@ ActionEffector::checkCommandCount( const BodySensor & sense ) M_command_counter[PlayerCommand::CHANGE_VIEW] = sense.changeViewCount(); } + if ( sense.changeFocusCount() != M_command_counter[PlayerCommand::CHANGE_FOCUS] ) + { + std::cout << M_agent.config().teamName() << ' ' + << M_agent.world().self().unum() << ": " + << M_agent.world().time() + << " lost change_focus? at " << M_last_action_time + << " sense=" << sense.changeViewCount() + << " internal=" << M_command_counter[PlayerCommand::CHANGE_FOCUS] + << std::endl; + dlog.addText( Logger::SYSTEM, + __FILE__": lost change_focus? sense= %d internal= %d", + sense.changeFocusCount(), + M_command_counter[PlayerCommand::CHANGE_FOCUS] ); + M_command_counter[PlayerCommand::CHANGE_FOCUS] = sense.changeFocusCount(); + } + if ( sense.sayCount() != M_command_counter[PlayerCommand::SAY] ) { std::cout << M_agent.config().teamName() << ' ' @@ -462,6 +485,10 @@ ActionEffector::makeCommand( std::ostream & to ) { dlog.addText( Logger::SYSTEM, __FILE__": WARNING. no body command." ); + std::cerr << M_agent.world().teamName() << ' ' + << M_agent.world().self().unum()<< ": " + << M_agent.world().time() + << " WARNING. no body command." << std::endl; // register dummy command PlayerTurnCommand turn( 0 ); turn.toCommandString( to ); @@ -486,6 +513,14 @@ ActionEffector::makeCommand( std::ostream & to ) M_command_change_view = nullptr; } + if ( M_command_change_focus ) + { + M_command_change_focus->toCommandString( to ); + incCommandCount( PlayerCommand::CHANGE_FOCUS ); + delete M_command_change_focus; + M_command_change_focus = nullptr; + } + if ( M_command_pointto ) { M_command_pointto->toCommandString( to ); @@ -544,6 +579,12 @@ ActionEffector::clearAllCommands() M_command_change_view = nullptr; } + if ( M_command_change_focus ) + { + delete M_command_change_focus; + M_command_change_focus = nullptr; + } + if ( M_command_pointto ) { delete M_command_pointto; @@ -1078,26 +1119,34 @@ ActionEffector::setCatch() = AngleDeg::atan2_deg( ServerParam::i().catchAreaWidth() * 0.5, ServerParam::i().catchAreaLength() ); - // relative angle - AngleDeg ball_rel_angle = M_agent.world().ball().angleFromSelf() - M_agent.world().self().body(); + const AngleDeg ball_rel_angle = M_agent.world().ball().angleFromSelf() - M_agent.world().self().body(); // add diagonal angle - AngleDeg catch_angle = ball_rel_angle + diagonal_angle; + AngleDeg catch_angle = ( ball_rel_angle.degree() > 0.0 + ? ball_rel_angle - diagonal_angle + : ball_rel_angle + diagonal_angle ); + + dlog.addText( Logger::ACTION, + __FILE__" (setCatch) (raw) ball_angle=%.1f diagonal_angle=%.1f catch_angle=%.1f", + ball_rel_angle.degree(), + diagonal_angle, + catch_angle.degree() ); + + if ( catch_angle.degree() < ServerParam::i().minCatchAngle() ) + { + catch_angle = ServerParam::i().minCatchAngle(); + } - if ( catch_angle.degree() < ServerParam::i().minCatchAngle() - || ServerParam::i().maxCatchAngle() < catch_angle.degree() ) + if ( catch_angle.degree() > ServerParam::i().maxCatchAngle() ) { - catch_angle = ball_rel_angle - diagonal_angle; + catch_angle = ServerParam::i().maxCatchAngle(); } dlog.addText( Logger::ACTION, - __FILE__" (setCatch) ball_dir=%.1f diagonal_angle=%.1f -> catch_angle=%.1f(gloabl=%.1f)", - ball_rel_angle.degree(), - diagonal_angle, + __FILE__" (setCatch) (result) catch_angle=%.1f(gloabl=%.1f)", catch_angle.degree(), ( catch_angle + M_agent.world().self().body() ).degree() ); - ////////////////////////////////////////////////// // create command object if ( M_command_body ) @@ -1298,6 +1347,32 @@ ActionEffector::setChangeView( const ViewWidth & width ) /*-------------------------------------------------------------------*/ /*! +*/ +void +ActionEffector::setChangeFocus( const double moment_dist, + const AngleDeg & moment_dir ) +{ + dlog.addText( Logger::ACTION, + __FILE__" (setChangeFocus) register change_focus. moment_dist=%lf moment_dir=%lf", + moment_dist, moment_dir ); + + ////////////////////////////////////////////////// + // create command object + if ( M_command_change_focus ) + { + delete M_command_change_focus; + M_command_change_focus = nullptr; + } + + double command_moment_dist = rint( moment_dist * 1000.0 ) * 0.001; + double command_moment_dir = rint( moment_dir.degree() * 1000.0 ) * 0.001; + + M_command_change_focus = new PlayerChangeFocusCommand( command_moment_dist, command_moment_dir ); +} + +/*-------------------------------------------------------------------*/ +/*! + */ void ActionEffector::addSayMessage( SayMessage * message ) diff --git a/rcsc/player/action_effector.h b/rcsc/player/action_effector.h index 7372d95..c050670 100644 --- a/rcsc/player/action_effector.h +++ b/rcsc/player/action_effector.h @@ -65,6 +65,8 @@ class ActionEffector { PlayerTurnNeckCommand * M_command_turn_neck; //! pointer of change_view for dynamic allocation PlayerChangeViewCommand * M_command_change_view; + //! pointer of change_focus for dynamic allocation + PlayerChangeFocusCommand * M_command_change_focus; //! pointer of say for dynamic allocation PlayerSayCommand * M_command_say; //! pointer of pointto for dynamic allocation @@ -318,6 +320,14 @@ class ActionEffector { */ void setChangeView( const ViewWidth & width ); + /*! + \brief create change_focus command + \param moment_dist distance added to the current focus point + \param moment_dir direction added to the current focus point + */ + void setChangeFocus( const double moment_dist, + const AngleDeg & moment_dir ); + /*! \brief add new say message \param message pointer to the dynamically allocated say message object. @@ -605,6 +615,18 @@ class ActionEffector { */ ViewWidth queuedNextViewWidth() const; + /*! + \brief get the next focus distance estimated by the queued acction effect + \return queued focus distance + */ + //double queuedNextFocusDist() const; + + /*! + \brief get the next focus direction estimated by the queued acction effect + \return queued focus direction + */ + //AngleDeg queuedNextFocusDir() const; + /*! \brief check if the target point can see only by turn_neck with the buffer \param point target point diff --git a/rcsc/player/body_sensor.cpp b/rcsc/player/body_sensor.cpp index 61157c4..7694365 100644 --- a/rcsc/player/body_sensor.cpp +++ b/rcsc/player/body_sensor.cpp @@ -62,6 +62,7 @@ BodySensor::BodySensor() , M_catch_count( 0 ) , M_move_count( 0 ) , M_change_view_count( 0 ) + , M_change_focus_count( 0 ) , M_arm_movable( 0 ) , M_arm_expires( 0 ) , M_pointto_dist( 0.0 ) @@ -87,9 +88,9 @@ BodySensor::BodySensor() */ void -BodySensor::parse1( const char * msg, - const double & version, - const GameTime & current ) +BodySensor::parse( const char * msg, + const double & version, + const GameTime & current ) { // ver. 4 & under // (sense_body 0 (view_mode high normal) (stamina 4000 1) (speed 0) @@ -135,6 +136,15 @@ BodySensor::parse1( const char * msg, // (collision {none|[(ball)][player][post]})) // (foul (charged 0) (card {none|yellow|red})) + // ver. 18 + // (sense_body 66 (view_mode high normal) (stamina 3503.4 1 124000) (speed 0.06 -79) + // (head_angle 89) (kick 4) (dash 20) (turn 24) (say 0) (turn_neck 28) (catch 0) + // (move 1) (change_view 16) (arm (movable 0) (expires 0) (target 0 0) (count 0)) + // (focus (target none) (count 0)) (tackle (expires 0) (count 0)) + // (collision {none|[(ball)][player][post]}) + // (foul (charged 0) (card {none|yellow|red}) + // (focus_point 0 0)) + //char ss[8]; M_time = current; @@ -257,90 +267,45 @@ BodySensor::parse1( const char * msg, M_move_count = static_cast< int >( std::strtol( msg, &next, 10 ) ); msg = next; - while ( *msg != '(' ) ++msg; - while ( *msg != ' ' ) ++msg; // skip "(chage_view" + while ( *msg != '\0' && *msg != '(' ) ++msg; + while ( *msg != '\0' && *msg != ' ' ) ++msg; // skip "(chage_view" M_change_view_count = static_cast< int >( std::strtol( msg, &next, 10 ) ); msg = next; + if ( version >= 18.0 ) + { + while ( *msg != '\0' && *msg != '(' ) ++msg; + while ( *msg != '\0' && *msg != ' ' ) ++msg; // skip "(change_focus" + M_change_focus_count = static_cast< int >( std::strtol( msg, &next, 10 ) ); + msg = next; + } + if ( version < 8.0 ) { return; } - // `(arm (movable ) (expires ) - // (target ) (count ))' - while ( *msg != '\0' && *msg != '(' ) ++msg; - while ( *msg != '\0' && *msg != ' ' ) ++msg; // skip "(arm" - while ( *msg != '\0' && *msg != '(' ) ++msg; - while ( *msg != '\0' && *msg != ' ' ) ++msg; // skip "(movable" - M_arm_movable = static_cast< int >( std::strtol( msg, &next, 10 ) ); - msg = next; - - while ( *msg != '\0' && *msg != '(' ) ++msg; - while ( *msg != '\0' && *msg != ' ' ) ++msg; // skip "(expires" - M_arm_expires = static_cast< int >( std::strtol( msg, &next, 10 ) ); - msg = next; - - while ( *msg != '\0' && *msg != '(' ) ++msg; - while ( *msg != '\0' && *msg != ' ' ) ++msg; // skip "(target" - ++msg; - M_pointto_dist = std::strtod( msg, &next ); - msg = next; - M_pointto_dir = std::strtod( msg, &next ); - msg = next; - while ( *msg != '\0' && *msg != '(' ) ++msg; - while ( *msg != '\0' && *msg != ' ' ) ++msg; // skip "(count" - M_pointto_count = static_cast< int >( std::strtol( msg, &next, 10 ) ); - msg = next; - - // `(focus (target []) (count )' - // := "none" | "l" | "r" - while ( *msg != '\0' && *msg != '(' ) ++msg; - while ( *msg != '\0' && *msg != ' ' ) ++msg; // skip "(focus" - while ( *msg != '\0' && *msg != '(' ) ++msg; - while ( *msg != '\0' && *msg != ' ' ) ++msg; // skip "(target" - ++msg; // skip space - if ( *msg == 'n' ) // "none" + if ( ! parseArm( msg, &next ) ) { - M_attentionto_side = NEUTRAL; - M_attentionto_unum = Unum_Unknown; - } - else if ( *msg == 'l' ) - { - M_attentionto_side = LEFT; - ++msg; - M_attentionto_unum = static_cast< int >( std::strtol( msg, &next, 10 ) ); - msg = next; - } - else if ( *msg == 'r' ) - { - M_attentionto_side = RIGHT; - ++msg; - M_attentionto_unum = static_cast< int >( std::strtol( msg, &next, 10 ) ); - msg = next; - } - else - { - std::cerr << "sense_body: focus ?? [" << msg << std::endl; + return; } - - while ( *msg != '\0' && *msg != '(' ) ++msg; - while ( *msg != '\0' && *msg != ' ' ) ++msg; // skip "(count" - M_attentionto_count = static_cast< int >( std::strtol( msg, &next, 10 ) ); msg = next; - // `(tackle (expires ) (count ))' + // (focus (target []) (count ) while ( *msg != '\0' && *msg != '(' ) ++msg; - while ( *msg != '\0' && *msg != ' ' ) ++msg; // skip "(tackle" - while ( *msg != '\0' && *msg != '(' ) ++msg; - while ( *msg != '\0' && *msg != ' ' ) ++msg; // skip "(expires" - M_tackle_expires = static_cast< int >( std::strtol( msg, &next, 10 ) ); + if ( ! parseAttentionto( msg, &next ) ) + { + return; + } msg = next; + // (tackle (expires ) (count )) while ( *msg != '\0' && *msg != '(' ) ++msg; - while ( *msg != '\0' && *msg != ' ' ) ++msg; // skip "(count" - M_tackle_count = static_cast< int >( std::strtol( msg, &next, 10 ) ); + if ( ! parseTackle( msg, &next ) ) + { + return; + } msg = next; if ( version < 12.0 ) @@ -348,11 +313,8 @@ BodySensor::parse1( const char * msg, return; } - while ( *msg != '\0' && *msg != '(' ) ++msg; - - // // (collision {none|[(ball)][(player)][(post)]}) - // + while ( *msg != '\0' && *msg != '(' ) ++msg; parseCollision( msg, &next ); msg = next; @@ -364,10 +326,23 @@ BodySensor::parse1( const char * msg, // // (foul (charged 0) (card {none|yellow|red})) // + while ( *msg != '\0' && *msg != '(' ) ++msg; parseFoul( msg, &next ); + msg = next; + if ( version < 18.0 ) + { + return; + } + + // + // (focus_point 0.0 0.0)) + // + while ( *msg != '\0' && *msg != '(' ) ++msg; + parseFocusPoint( msg, &next ); } +#if 0 /*-------------------------------------------------------------------*/ /*! @@ -436,9 +411,23 @@ BodySensor::parse2( const char * msg, M_attentionto_unum = Unum_Unknown; } + char *next = nullptr; if ( version >= 12.0 ) { - parseCollision( msg + n_read, NULL ); + parseCollision( msg + n_read, &next ); + msg = next; + } + + if ( version >= 14.0 ) + { + parseFoul( msg, &next ); + msg = next; + } + + if ( version >= 18.0 ) + { + parseFocusPoint( msg, &next ); + msg = next; } } else if ( version >= 7.0 @@ -540,6 +529,127 @@ BodySensor::parse2( const char * msg, break; } } +#endif + +/*-------------------------------------------------------------------*/ +bool +BodySensor::parseArm( const char * msg, + char ** next ) +{ + int movable, expires, count; + double dist, dir; + int n_read = 0; + if ( std::sscanf( msg, + " ( arm ( movable %d ) ( expires %d ) ( target %lf %lf ) ( count %d ) ) %n", + &movable, &expires, &dist, &dir, &count, &n_read ) != 5 ) + { + std::cerr << M_time << " sense_body. illegal arm [" << msg << "]" << std::endl; + return false; + } + + M_arm_movable = movable; + M_arm_expires = expires; + M_pointto_dist = dist; + M_pointto_dir = dir; + M_pointto_count = count; + + *next = const_cast< char * >( msg ) + n_read; + return true; +} + +/*-------------------------------------------------------------------*/ +bool +BodySensor::parseAttentionto( const char * msg, + char ** next ) +{ + // `(focus (target []) (count )' + // := "none" | "l" | "r" + + char side[8]; + int unum = Unum_Unknown; + int count = 0; + int n_read = 0; + + if ( std::strncmp( "(focus ", msg, 7 ) ) + { + std::cerr << "ERROR: " << M_time + << " (BodySensor::parseAttentionto) [" << msg << "]" << std::endl; + return false; + } + + msg += 7; + if ( std::sscanf( msg, " ( target %7[^)] %d ) %n", side, &unum, &n_read ) != 2 + && std::sscanf( msg, " ( target %7[^)] ) %n", side, &n_read ) != 1 ) + { + std::cerr << "ERROR: " << M_time + << " (BodySensor::parseAttentionto) [" << msg << "]" << std::endl; + return false; + } + msg += n_read; + + if ( std::sscanf( msg, " ( count %d ) %n", &count, &n_read ) != 1 ) + { + std::cerr << "ERROR: " << M_time + << " (BodySensor::parseAttentionto) [" << msg << "]" << std::endl; + return false; + } + msg += n_read; + + if ( side[0] == 'n' ) + { + M_attentionto_side = NEUTRAL; + M_attentionto_unum = Unum_Unknown; + } + else if ( side[0] == 'l' ) + { + M_attentionto_side = LEFT; + M_attentionto_unum = unum; + } + else if ( side[0] == 'r' ) + { + M_attentionto_side = RIGHT; + M_attentionto_unum = unum; + } + else + { + std::cerr << "ERROR: " << M_time + << " (BodySensor::parseAttentionto) Unknown side [" << side << "]" + << std::endl; + return false; + } + + M_attentionto_count = count; + + // skip to the next element + while ( *msg != '\0' && *msg != '(' ) ++msg; + *next = const_cast< char * >( msg ); + + return true; +} + +/*-------------------------------------------------------------------*/ +bool +BodySensor::parseTackle( const char * msg, + char ** next ) +{ + // `(tackle (expires ) (count ))' + int expires, count; + int n_read = 0; + if ( std::sscanf( msg, + " ( tackle ( expires %d ) ( count %d ) ) %n", + &expires, &count, &n_read ) != 2 ) + { + std::cerr << "ERROR: " << M_time + << " (BodySensor::parseTackle) [" << msg << "]" << std::endl; + return false; + } + + M_tackle_expires = expires; + M_tackle_count = count; + + *next = const_cast< char * >( msg ) + n_read; + return true; +} /*-------------------------------------------------------------------*/ /*! @@ -692,6 +802,37 @@ BodySensor::parseFoul( const char * msg, return true; } + +/*-------------------------------------------------------------------*/ +/*! + +*/ +bool +BodySensor::parseFocusPoint( const char * msg, + char ** next ) +{ + // (focus_point ) + + double focus_dist = 0.0; + double focus_dir = 0.0; + int n_read = 0; + + if ( std::sscanf( msg, " (focus_point %lf %lf) %n", &focus_dist, &focus_dir, &n_read ) != 2 ) + { + std::cerr << M_time << " ERROR: Illegal focus_point in sense_body [" << msg << "]" << std::endl; + return false; + } + + M_focus_dist = focus_dist; + M_focus_dir = focus_dir; + + if ( next ) + { + *next = const_cast< char * >( msg ) + n_read; + } + return true; +} + /*-------------------------------------------------------------------*/ /*! diff --git a/rcsc/player/body_sensor.h b/rcsc/player/body_sensor.h index 540d4ae..a0830b4 100644 --- a/rcsc/player/body_sensor.h +++ b/rcsc/player/body_sensor.h @@ -66,6 +66,7 @@ class BodySensor { int M_catch_count; //!< sensed command count int M_move_count; //!< sensed command count int M_change_view_count; //!< sensed command count + int M_change_focus_count; //!< sensed command count /*! the number of cycles till the arm is movable. @@ -111,6 +112,10 @@ class BodySensor { int M_charged_expires; //!< foul charged expire cycle Card M_card; //!< yellow/red card + // v18+ + double M_focus_dist; //!< distance to the focus point + double M_focus_dir; //!< direction to the focus point, relative to the body direction + public: /*! \brief init member variables @@ -125,31 +130,37 @@ class BodySensor { */ void parse( const char * msg, const double & version, - const GameTime & current ) - { - parse1( msg, version, current ); - } + const GameTime & current ); + +private: /*! - \brief analyze server message usind very ugly style but very fast - \param msg server message - \param version client version - \param current current game time - */ - void parse1( const char * msg, - const double & version, - const GameTime & current ); + \brief analyze arm information in the sense_body message. + \param msg server message started with (arm + \param pointer pointer to the next character after parsing + \return parsing result + */ + bool parseArm( const char * msg, + char ** next ); + /*! - \brief analyze server message using std::sscanf. - \param msg server message - \param version client version - \param current current game time - */ - void parse2( const char * msg, - const double & version, - const GameTime & current ); + \brief analyze attentionto(focus) information in the sense_body message. + \param msg server message started with (focus + \param pointer pointer to the next character after parsing + \return parsing result + */ + bool parseAttentionto( const char * msg, + char ** next ); + + /*! + \brief analyze tackle information in the sense_body message. + \param msg server message started with (tackle + \param pointer pointer to the next character after parsing + \return parsing result + */ + bool parseTackle( const char * msg, + char ** next ); -private: /*! \brief analyze collision information contained by sense_body message. @@ -169,6 +180,15 @@ class BodySensor { bool parseFoul( const char * msg, char ** next ); + /*! + \brief analyze focus point information + \param msg server message started with (focus_point + \param pointer pointer to the next character after parsing + \return parsing result + */ + bool parseFocusPoint( const char * msg, + char ** next ); + public: /*! @@ -333,6 +353,15 @@ class BodySensor { return M_change_view_count; } + /*! + \brief get analyzed change_focus count + \return count of performed change_focus command + */ + int changeFocusCount() const + { + return M_change_focus_count; + } + /*! \brief get analyzed cycles till the arm is movable \return cycles till the arm is movable @@ -479,6 +508,24 @@ class BodySensor { return M_card; } + /*! + \brief get the focus distance value + \return the distance to the focus point + */ + double focusDist() const + { + return M_focus_dist; + } + + /*! + \brief get the focus direction value + \return the direction to the focus point, relative to the body angle + */ + double focusDir() const + { + return M_focus_dir; + } + /*! \brief put data to output stream \param os reference to the output stream diff --git a/rcsc/player/fullstate_sensor.cpp b/rcsc/player/fullstate_sensor.cpp index cda7490..6148352 100644 --- a/rcsc/player/fullstate_sensor.cpp +++ b/rcsc/player/fullstate_sensor.cpp @@ -164,15 +164,22 @@ FullstateSensor::parseV8( const char * msg, players : {| } player : (v8-13) - ((p {l|r} {g|}) - [ ] - ( [ ])) - - player : (v14) - ((p {l|r} [g] ) - [ ] - ( [ ]) - [t|k] [y|r]) + ((p {l|r} {g|}) + [ ] + (stamina [ ])) + + player : (v14) tackle/kick/yellow/red + ((p {l|r} [g] ) + [ ] + (stamina [ ]) + [t|k] [y|r]) + + player: v18+ + ((p {l|r} [g] ) + [ ] + (focus_point ) + (stamina [ ]) + [t|k] [y|r]) */ @@ -239,14 +246,12 @@ FullstateSensor::parseV8( const char * msg, M_ball.vel_.y = std::strtod( msg, &next ); msg = next; //((p {l|r} {g|}) - // [ ] - // ( [ ]) - // [t|k] [y|r]) - // - //((p {l|r} [g] }) - // [ ] - // ( [ ]) + // + // + // [ ] + // (stamina [ ]) // [t|k|f] [y|r]) + // while ( *msg != '\0' && *msg != '(' ) ++msg; // skip to "(p" while ( *msg != '\0' ) { @@ -292,24 +297,36 @@ FullstateSensor::parseV8( const char * msg, player.vel_.y = std::strtod( msg, &next ); msg = next; player.body_ = std::strtod( msg, &next ); msg = next; player.neck_ = std::strtod( msg, &next ); msg = next; - ++msg; + + while ( *msg != '\0' && *msg == ' ' ) ++msg; if ( *msg != '(' ) { player.pointto_dist_ = std::strtod( msg, &next ); msg = next; player.pointto_dir_ = std::strtod( msg, &next ); msg = next; } - while ( *msg != '\0' && *msg != '(' ) ++msg; // skip to "(stamina" - while ( *msg != '\0' && *msg != ' ' ) ++msg; // skip to space " " - ++msg; - player.stamina_ = std::strtod( msg, &next ); msg = next; - player.effort_ = std::strtod( msg, &next ); msg = next; - player.recovery_ = std::strtod( msg, &next ); msg = next; - if ( *msg != ')' ) + while ( *msg != '\0' && *msg != '(' ) ++msg; // skip to "(" + + if ( std::strncmp( msg, "(focus_point ", 13 ) == 0 ) + { + msg += 13; + player.focus_dist_ = std::strtod( msg, &next ); msg = next; + player.focus_dir_ = std::strtod( msg, &next ); msg = next; + while ( *msg != '\0' && *msg != '(' ) ++msg; // skip to "(" + } + + if ( std::strncmp( msg, "(stamina ", 9 ) == 0 ) { - player.stamina_capacity_ = std::strtod( msg, &next ); msg = next; + msg += 9; + player.stamina_ = std::strtod( msg, &next ); msg = next; + player.effort_ = std::strtod( msg, &next ); msg = next; + player.recovery_ = std::strtod( msg, &next ); msg = next; + if ( *msg != ')' ) + { + player.stamina_capacity_ = std::strtod( msg, &next ); msg = next; + } + while ( *msg == ')' ) ++msg; } - while ( *msg == ')' ) ++msg; while ( *msg == ' ' ) ++msg; if ( *msg == 'k' ) // kick diff --git a/rcsc/player/fullstate_sensor.h b/rcsc/player/fullstate_sensor.h index 635d4cb..571475d 100644 --- a/rcsc/player/fullstate_sensor.h +++ b/rcsc/player/fullstate_sensor.h @@ -78,6 +78,11 @@ class FullstateSensor { double recovery_; //!< recovery value double stamina_capacity_; //!< stamina capacity value + //! v18+. disntance to the focus point + double focus_dist_; + //! v18+. direction to the focus point + double focus_dir_; + //! v8+. distance from pos_ to pointing point double pointto_dist_; //! v8+. pointing direction direction relative to face(=body+neck) @@ -108,6 +113,8 @@ class FullstateSensor { stamina_( 0.0 ), effort_( 0.0 ), recovery_( 0.0 ), + focus_dist_( 0.0 ), + focus_dir_( 0.0 ), pointto_dist_( -1.0 ), pointto_dir_( 0.0 ), kicked_( false ), diff --git a/rcsc/player/intercept.cpp b/rcsc/player/intercept.cpp new file mode 100644 index 0000000..0814a78 --- /dev/null +++ b/rcsc/player/intercept.cpp @@ -0,0 +1,44 @@ +// -*-c++-*- + +/*! + \file intercept_table.cpp + \brief interception info holder Source File +*/ + +/* + *Copyright: + + Copyright (C) Hidehisa AKIYAMA + + This code is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + *EndCopyright: + */ + +///////////////////////////////////////////////////////////////////// + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "intercept.h" + +#include + +namespace rcsc { + +const double Intercept::MIN_VALUE = -std::numeric_limits< double >::max(); + +} diff --git a/rcsc/player/intercept.h b/rcsc/player/intercept.h new file mode 100644 index 0000000..212d639 --- /dev/null +++ b/rcsc/player/intercept.h @@ -0,0 +1,278 @@ +// -*-c++-*- + +/*! + \file intercept.h + \brief intercept action type Header File +*/ + +/* + *Copyright: + + Copyright (C) Hidehisa AKIYAMA + + This code is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + *EndCopyright: + */ + +///////////////////////////////////////////////////////////////////// + +#ifndef RCSC_PLAYER_INTERCEPT_H +#define RCSC_PLAYER_INTERCEPT_H + +#include + +namespace rcsc { + +/*-------------------------------------------------------------------*/ + +/*! + \class Intercept + \brief intercept action data +*/ +class Intercept { +public: + + /*! + \enum StaminaType + \brief stamina type + */ + enum StaminaType { + NORMAL = 0, //!< ball gettable without stamina exhaust + EXHAUST = 100, //!< fastest ball gettable, but recovery may be consumed. + }; + + /*! + \enum ActionType + \brief action type + */ + enum ActionType { + OMNI_DASH = 0, + TURN_FORWARD_DASH = 1, + TURN_BACK_DASH = 2, + UNKNOWN_TYPE = 100, + }; + + static const double MIN_VALUE; + +private: + int M_index; //!< index value in all candidates + double M_value; //!< evaluation value + + StaminaType M_stamina_type; //!< stamina type + ActionType M_action_type; //!< action type + + int M_turn_step; //!< estimated turn step + double M_turn_angle; //!< angle difference between current body angle and dash angle + + int M_dash_step; //!< estimated dash step + double M_dash_power; //!< first dash power + double M_dash_dir; //!< first dash direction (relative to body) + + Vector2D M_self_pos; //!< estimated final self position + double M_ball_dist; //!< estimated final ball distance + double M_stamina; //!< estimated final stamina value + +public: + + /*! + \brief create invalid info + */ + Intercept() + : M_index( -1 ), + M_value( MIN_VALUE ), + M_stamina_type( EXHAUST ), + M_action_type( UNKNOWN_TYPE ), + M_turn_step( 10000 ), + M_turn_angle( 0.0 ), + M_dash_step( 10000 ), + M_dash_power( 100000.0 ), + M_dash_dir( 0.0 ), + M_self_pos( -10000.0, 0.0 ), + M_ball_dist( 10000000.0 ), + M_stamina( 0.0 ) + { } + + /*! + \brief construct with all variables + */ + Intercept( const StaminaType stamina_type, + const ActionType action_type, + const int turn_step, + const double turn_angle, + const int dash_step, + const double dash_power, + const double dash_dir, + const Vector2D & self_pos, + const double ball_dist, + const double stamina ) + : M_index( -1 ), + M_value( MIN_VALUE ), + M_stamina_type( stamina_type ), + M_action_type( action_type ), + M_turn_step( turn_step ), + M_turn_angle( turn_angle ), + M_dash_step( dash_step ), + M_dash_power( dash_power ), + M_dash_dir( dash_dir ), + M_self_pos( self_pos ), + M_ball_dist( ball_dist ), + M_stamina( stamina ) + { } + + /*! + \brief set the evaluaion value with index count + \param idx index value + \param value evaluation value + */ + void setEvaluation( const int idx, + const double value ) + { + M_index = idx; + M_value = value; + } + + /*! + \brief check if this object is legal one or not. + \return checked result. + */ + bool isValid() const + { + return M_action_type != UNKNOWN_TYPE; + } + + /*! + \brief get the index count within candidate list + \return index count + */ + int index() const + { + return M_index; + } + + + /*! + \brief get the evaluation value of this intercept candidate + \return evaluation value + */ + double value() const + { + return M_value; + } + + /*! + \brief get the result stamina type + \return stamina type id + */ + StaminaType staminaType() const + { + return M_stamina_type; + } + + /*! + \brief get the action type + \return type id + */ + ActionType actionType() const + { + return M_action_type; + } + + /*! + \brief get estimated total turn steps + \return the number of turn steps + */ + int turnStep() const + { + return M_turn_step; + } + + /*! + \brief get the required first turn angle + \return the first turn angle in degree + */ + double turnAngle() const + { + return M_turn_angle; + } + + /*! + \brief get estimated total dash cycles + \return the number of dash steps + */ + int dashStep() const + { + return M_dash_step; + } + + /*! + \brief get esitimated total step to reach + \return the number of total steps + */ + int reachStep() const + { + return turnStep() + dashStep(); + } + + /*! + \brief get dash power for the first dash + \return dash power value + */ + double dashPower() const + { + return M_dash_power; + } + + /*! + \brief ger the dash direction for the first dash + \return dash direction value (relative to body) + */ + double dashDir() const + { + return M_dash_dir; + } + + /*! + \brief get the estimated final self position + \return final self position + */ + const Vector2D & selfPos() const + { + return M_self_pos; + } + + /*! + \brief get the estimated final ball distance + \return final ball distance + */ + double ballDist() const + { + return M_ball_dist; + } + + /*! + \brief get the estimated final self stamina value + \return final self stamina value + */ + double stamina() const + { + return M_stamina; + } + +}; + +} + +#endif diff --git a/rcsc/player/player_intercept.cpp b/rcsc/player/intercept_simulator_player.cpp similarity index 75% rename from rcsc/player/player_intercept.cpp rename to rcsc/player/intercept_simulator_player.cpp index 96aa3dc..2f8beff 100644 --- a/rcsc/player/player_intercept.cpp +++ b/rcsc/player/intercept_simulator_player.cpp @@ -1,8 +1,8 @@ // -*-c++-*- /*! - \file player_intercept.cpp - \brief intercept predictor for other players Source File + \file intercept_simulator_player.cpp + \brief intercept simulator for other players Source File */ /* @@ -33,7 +33,8 @@ #include #endif -#include "player_intercept.h" +#include "intercept_simulator_player.h" + #include "world_model.h" #include "ball_object.h" #include "player_object.h" @@ -55,7 +56,7 @@ inline Vector2D get_pos( const PlayerObject & p ) { - return ( p.heardPosCount() < p.seenPosCount() + return ( p.heardPosCount() <= p.seenPosCount() - 2 ? p.heardPos() : p.seenPos() ); } @@ -117,10 +118,10 @@ get_penalty_step( const PlayerObject & p ) /*-------------------------------------------------------------------*/ /*! -*/ + */ inline Vector2D -PlayerIntercept::PlayerData::inertiaPoint( const int step ) const +InterceptSimulatorPlayer::PlayerData::inertiaPoint( const int step ) const { return ptype_.inertiaPoint( pos_, vel_, step + bonus_step_ ); } @@ -128,24 +129,77 @@ PlayerIntercept::PlayerData::inertiaPoint( const int step ) const /*-------------------------------------------------------------------*/ /*! -*/ -PlayerIntercept::PlayerIntercept( const WorldModel & world, - const std::vector< Vector2D > & ball_cache ) - : M_world( world ), - M_ball_cache( ball_cache ), - M_ball_move_angle( ( ball_cache.back() - ball_cache.front() ).th() ) + */ +InterceptSimulatorPlayer::InterceptSimulatorPlayer( const Vector2D & ball_pos, + const Vector2D & ball_vel ) + : M_ball_move_angle( ball_vel.th() ) { + createBallCache( ball_pos, ball_vel ); +} +/*-------------------------------------------------------------------*/ +void +InterceptSimulatorPlayer::createBallCache( const Vector2D & ball_pos, + const Vector2D & ball_vel ) +{ + constexpr int MAX_STEP = 50; + + const ServerParam & SP = ServerParam::i(); + const double max_x = ( SP.keepawayMode() + ? SP.keepawayLength() * 0.5 + : SP.pitchHalfLength() + 5.0 ); + const double max_y = ( SP.keepawayMode() + ? SP.keepawayWidth() * 0.5 + : SP.pitchHalfWidth() + 5.0 ); + const double bdecay = SP.ballDecay(); + + M_ball_cache.clear(); + M_ball_cache.reserve( MAX_STEP ); + + Vector2D bpos = ball_pos; + Vector2D bvel = ball_vel; + double bspeed = bvel.r(); + + for ( int i = 0; i < MAX_STEP; ++i ) + { + M_ball_cache.push_back( bpos ); + + if ( bspeed < 0.005 && i >= 10 ) + { + break; + } + + bpos += bvel; + bvel *= bdecay; + bspeed *= bdecay; + + if ( max_x < bpos.absX() + || max_y < bpos.absY() ) + { + break; + } + } } /*-------------------------------------------------------------------*/ /*! -*/ + */ int -PlayerIntercept::predict( const PlayerObject & player, - const bool goalie ) const +InterceptSimulatorPlayer::simulate( const WorldModel & wm, + const PlayerObject & player, + const bool goalie ) const { + if ( player.posCount() >= 10 ) + { + return 1000; + } + + if ( player.isKickable( 0.0 ) ) + { + return 0; + } + const PlayerType * ptype = player.playerTypePtr(); if ( ! ptype ) @@ -167,8 +221,8 @@ PlayerIntercept::predict( const PlayerObject & player, *ptype, get_pos( player ), get_vel( player ), - get_control_area( player, M_world, goalie ), - get_bonus_step( player, M_world.ourSide() ), + get_control_area( player, wm, goalie ), + get_bonus_step( player, wm.ourSide() ), get_penalty_step( player ) ); const int min_step = estimateMinStep( data ); @@ -203,7 +257,7 @@ PlayerIntercept::predict( const PlayerObject & player, && ( ball_pos.absX() < pen_area_x || pen_area_y < ball_pos.absY() ) ) { - // never reach + // never reach #ifdef DEBUG2 dlog.addText( Logger::INTERCEPT, "--->cycle=%d goalie. out of penalty area. ball(%.2f %.2f)", @@ -258,9 +312,9 @@ PlayerIntercept::predict( const PlayerObject & player, /*-------------------------------------------------------------------*/ /*! -*/ + */ int -PlayerIntercept::estimateMinStep( const PlayerData & data ) const +InterceptSimulatorPlayer::estimateMinStep( const PlayerData & data ) const { Vector2D rel = data.pos_ - M_ball_cache.front(); rel.rotate( - M_ball_move_angle ); @@ -273,19 +327,19 @@ PlayerIntercept::estimateMinStep( const PlayerData & data ) const /*-------------------------------------------------------------------*/ /*! -*/ + */ bool -PlayerIntercept::canReachAfterTurnDash( const PlayerData & data, - const Vector2D & ball_pos, - const int total_step ) const +InterceptSimulatorPlayer::canReachAfterTurnDash( const PlayerData & data, + const Vector2D & ball_pos, + const int total_step ) const { /* TODO if ( canReachAfterOmniDash() ) { - return true; + return true; } - */ + */ int n_turn = predictTurnCycle( data, ball_pos, total_step ); #ifdef DEBUG2 @@ -297,6 +351,11 @@ PlayerIntercept::canReachAfterTurnDash( const PlayerData & data, int max_dash = total_step - n_turn - data.penalty_step_; if ( max_dash < 0 ) { +#ifdef DEBUG2 + dlog.addText( Logger::INTERCEPT, + "______ step %d [false] max_dash=%d", + total_step, max_dash ); +#endif return false; } @@ -309,11 +368,11 @@ PlayerIntercept::canReachAfterTurnDash( const PlayerData & data, /*-------------------------------------------------------------------*/ /*! -*/ + */ int -PlayerIntercept::predictTurnCycle( const PlayerData & data, - const Vector2D & ball_pos, - const int total_step ) const +InterceptSimulatorPlayer::predictTurnCycle( const PlayerData & data, + const Vector2D & ball_pos, + const int total_step ) const { Vector2D inertia_pos = data.inertiaPoint( total_step ); Vector2D ball_rel = ball_pos - inertia_pos; @@ -334,6 +393,13 @@ PlayerIntercept::predictTurnCycle( const PlayerData & data, angle_diff = 180.0 - angle_diff; } +#ifdef DEBUG2 + dlog.addText( Logger::INTERCEPT, + "______ step %d: player=(%.1f %.1f) ball_dist=%.3f angle_diff=%.1f turn_margin=%.1f", + total_step, data.pos_.x, data.pos_.y,//inertia_pos.x, inertia_pos.y, + ball_dist, angle_diff, turn_margin ); +#endif + int n_turn = 0; if ( angle_diff > turn_margin ) @@ -358,12 +424,12 @@ PlayerIntercept::predictTurnCycle( const PlayerData & data, /*-------------------------------------------------------------------*/ /*! -*/ + */ bool -PlayerIntercept::canReachAfterDash( const PlayerData & data, - const Vector2D & ball_pos, - const int total_step, - const int n_turn ) const +InterceptSimulatorPlayer::canReachAfterDash( const PlayerData & data, + const Vector2D & ball_pos, + const int total_step, + const int n_turn ) const { Vector2D inertia_pos = data.inertiaPoint( total_step ); Vector2D ball_rel = ball_pos - inertia_pos; @@ -401,15 +467,21 @@ PlayerIntercept::canReachAfterDash( const PlayerData & data, return true; } +#ifdef DEBUG2 + dlog.addText( Logger::INTERCEPT, + "______ unum=%d [false] total=%d >= turn=%d dash=%d -bonus=%d penalty=%d", + data.player_.unum(), total_step, n_turn, n_dash, bonus_step, data.penalty_step_ ); +#endif + return false; } /*-------------------------------------------------------------------*/ /*! -*/ + */ int -PlayerIntercept::predictFinal( const PlayerData & data ) const +InterceptSimulatorPlayer::predictFinal( const PlayerData & data ) const { Vector2D ball_pos = M_ball_cache.back(); int ball_step = M_ball_cache.size() - 1; diff --git a/rcsc/player/player_intercept.h b/rcsc/player/intercept_simulator_player.h similarity index 81% rename from rcsc/player/player_intercept.h rename to rcsc/player/intercept_simulator_player.h index e161899..10b531b 100644 --- a/rcsc/player/player_intercept.h +++ b/rcsc/player/intercept_simulator_player.h @@ -1,8 +1,8 @@ // -*-c++-*- /*! - \file player_intercept.h - \brief intercept predictor for other players Header File + \file intercept_simulator_player.h + \brief intercept simulator for other players Header File */ /* @@ -29,8 +29,8 @@ ///////////////////////////////////////////////////////////////////// -#ifndef RCSC_PLAYER_PLAYER_INTERCEPT_H -#define RCSC_PLAYER_PLAYER_INTERCEPT_H +#ifndef RCSC_PLAYER_INTERCEPT_SIMULATOR_PLAYER_H +#define RCSC_PLAYER_INTERCEPT_SIMULATOR_PLAYER_H #include #include @@ -43,16 +43,16 @@ class PlayerObject; class WorldModel; /*! - \class PlayerIntercept - \brief intercept predictor for other players + \class InterceptSimulatorPlayer + \brief intercept simulator for other players */ -class PlayerIntercept { +class InterceptSimulatorPlayer { private: /*! \struct PlayerData \brief player data - */ + */ struct PlayerData { const PlayerObject & player_; //!< player reference const PlayerType & ptype_; //!< player type @@ -76,58 +76,66 @@ class PlayerIntercept { control_area_( control_area ), bonus_step_( bonus_step ), penalty_step_( penalty_step ) - { } + { } Vector2D inertiaPoint( const int step ) const; }; - //! const reference to the WorldModel instance - const WorldModel & M_world; - //! const reference to the predicted ball position cache instance - const std::vector< Vector2D > & M_ball_cache; + //! predicted ball positions + std::vector< Vector2D > M_ball_cache; //! ball velocity angle const AngleDeg M_ball_move_angle; // not used - PlayerIntercept() = delete; + InterceptSimulatorPlayer() = delete; public: /*! \brief construct with all variables. - \param world const reference to the WormdModel instance - \param ball_pos_cache const reference to the ball position container + \param ball_pos initial ball position + \param ball_vel initial ball velocity */ - PlayerIntercept( const WorldModel & world, - const std::vector< Vector2D > & ball_cache ); + InterceptSimulatorPlayer( const Vector2D & ball_pos, + const Vector2D & ball_vel ); /*! \brief destructor. nothing to do */ - ~PlayerIntercept() - { } + ~InterceptSimulatorPlayer() + { } ////////////////////////////////////////////////////////// /*! \brief get predicted ball gettable cycle + \param wm const reference to the instance of world model \param player const reference to the player object \param goalie goalie mode or not \param max_cycle max predict cycle. estimation loop is limited to this value. \return predicted cycle value */ - int predict( const PlayerObject & player, - const bool goalie ) const; + int simulate( const WorldModel & wm, + const PlayerObject & player, + const bool goalie ) const; private: + /*! + \brief create predicted ball positions + \param ball_pos initial ball position + \param ball_vel initial ball velocity + */ + void createBallCache( const Vector2D & ball_pos, + const Vector2D & ball_vel ); + /*! \brief estimate minimum reach step (very rough calculation) \param ptype player type \param control_area kickable/catchable area \param player_pos player's initial position - */ + */ int estimateMinStep( const PlayerData & data ) const; diff --git a/rcsc/player/intercept_simulator_self.h b/rcsc/player/intercept_simulator_self.h new file mode 100644 index 0000000..97da9a3 --- /dev/null +++ b/rcsc/player/intercept_simulator_self.h @@ -0,0 +1,70 @@ +// -*-c++-*- + +/*! + \file intercept_simulator_self.h + \brief base class of the self intercept simulator +*/ + +/* + *Copyright: + + Copyright (C) Hidehisa AKIYAMA + + This code is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + *EndCopyright: + */ + +///////////////////////////////////////////////////////////////////// + +#ifndef RCSC_PLAYER_INTERCEPT_SIMULATOR_SELF_H +#define RCSC_PLAYER_INTERCEPT_SIMULATOR_SELF_H + +#include + +namespace rcsc { + +class WorldModel; + +class InterceptSimulatorSelf { +private: + +protected: + + //! protected constructor since this is an abstract class + InterceptSimulatorSelf() = default; + +public: + + //! virtual destructor + virtual + ~InterceptSimulatorSelf() = default; + + /*! + \brief pure virtual function. simulate self interception, and store the results to self_results + \param wm world model + \param max_step max prediction step + \param self_results reference to the result container + */ + virtual + void simulate( const WorldModel & wm, + const int max_step, + std::vector< Intercept > & self_results ) = 0; + +}; + +} + +#endif diff --git a/rcsc/player/self_intercept_v13.cpp b/rcsc/player/intercept_simulator_self_v13.cpp similarity index 100% rename from rcsc/player/self_intercept_v13.cpp rename to rcsc/player/intercept_simulator_self_v13.cpp diff --git a/rcsc/player/self_intercept_v13.h b/rcsc/player/intercept_simulator_self_v13.h similarity index 100% rename from rcsc/player/self_intercept_v13.h rename to rcsc/player/intercept_simulator_self_v13.h diff --git a/rcsc/player/self_intercept_simulator.cpp b/rcsc/player/intercept_simulator_self_v17.cpp similarity index 66% rename from rcsc/player/self_intercept_simulator.cpp rename to rcsc/player/intercept_simulator_self_v17.cpp index 1d35b35..752597e 100644 --- a/rcsc/player/self_intercept_simulator.cpp +++ b/rcsc/player/intercept_simulator_self_v17.cpp @@ -1,8 +1,8 @@ // -*-c++-*- /*! - \file self_intercept_simulator.cpp - \brief self intercept simulator for creating candidate intercept actions + \file intercept_simulator_selv_v17.cpp + \brief intercept simulator for self */ /* @@ -34,7 +34,7 @@ #include #endif -#include "self_intercept_simulator.h" +#include "intercept_simulator_self_v17.h" #include "ball_object.h" #include "self_object.h" @@ -97,7 +97,7 @@ debug_print_results( const WorldModel & wm, const std::vector< InterceptInfo > & self_cache ) { dlog.addText( Logger::INTERCEPT, - "(SelfIntercept) solution size = %zd kickable=%.3f catchable=%.3f:%.3f", + "(SelfIntercept) solution size = %zd kickable=%.3f catchable=%.3f:%.3f", self_cache.size(), wm.self().playerType().kickableArea(), wm.self().playerType().reliableCatchableDist(), @@ -113,7 +113,7 @@ debug_print_results( const WorldModel & wm, type_char( self_cache[i].actionType() ), self_cache[i].reachCycle(), self_cache[i].turnCycle(), - self_cache[i].dashCycle(), + self_cache[i].dashStep(), self_cache[i].dashPower(), self_cache[i].dashDir(), self_cache[i].selfPos().x, self_cache[i].selfPos().y, @@ -128,45 +128,45 @@ debug_print_results( const WorldModel & wm, */ struct InterceptSorter { - bool operator()( const InterceptInfo & lhs, - const InterceptInfo & rhs ) const - { - if ( lhs.reachCycle() < rhs.reachCycle() ) - { - return true; - } - - if ( lhs.reachCycle() > rhs.reachCycle() ) - { - return false; - } - - // reach steps are same - - if ( lhs.turnCycle() < rhs.turnCycle() ) - { - return true; - } - - if ( lhs.turnCycle() > rhs.turnCycle() ) - { - return false; - } - - // turn steps are same - - // if ( lhs.type() < rhs.type() ) - // { - // return true; - // } - - if ( std::fabs( lhs.stamina() - rhs.stamina() ) < 200.0 ) - { - return lhs.ballDist() < rhs.ballDist(); - } - - return lhs.stamina() > rhs.stamina(); - } + bool operator()( const Intercept & lhs, + const Intercept & rhs ) const + { + if ( lhs.reachStep() < rhs.reachStep() ) + { + return true; + } + + if ( lhs.reachStep() > rhs.reachStep() ) + { + return false; + } + + // reach steps are same + + if ( lhs.turnStep() < rhs.turnStep() ) + { + return true; + } + + if ( lhs.turnStep() > rhs.turnStep() ) + { + return false; + } + + // turn steps are same + + // if ( lhs.type() < rhs.type() ) + // { + // return true; + // } + + if ( std::fabs( lhs.stamina() - rhs.stamina() ) < 200.0 ) + { + return lhs.ballDist() < rhs.ballDist(); + } + + return lhs.stamina() > rhs.stamina(); + } }; /*-------------------------------------------------------------------*/ @@ -174,15 +174,15 @@ struct InterceptSorter { */ struct InterceptEqual { - bool operator()( const InterceptInfo & lhs, - const InterceptInfo & rhs ) const - { - return lhs.staminaType() == rhs.staminaType() - && lhs.actionType() == rhs.actionType() - && lhs.turnCycle() == rhs.turnCycle() - && lhs.dashCycle() == rhs.dashCycle() - && lhs.dashDir() == rhs.dashDir(); - } + bool operator()( const Intercept & lhs, + const Intercept & rhs ) const + { + return lhs.staminaType() == rhs.staminaType() + && lhs.actionType() == rhs.actionType() + && lhs.turnStep() == rhs.turnStep() + && lhs.dashStep() == rhs.dashStep() + && lhs.dashDir() == rhs.dashDir(); + } }; /*-------------------------------------------------------------------*/ @@ -190,13 +190,13 @@ struct InterceptEqual { */ struct InterceptEqualSimple { - bool operator()( const InterceptInfo & lhs, - const InterceptInfo & rhs ) const - { - return lhs.actionType() == rhs.actionType() - && lhs.turnCycle() == rhs.turnCycle() - && lhs.dashCycle() == rhs.dashCycle(); - } + bool operator()( const Intercept & lhs, + const Intercept & rhs ) const + { + return lhs.actionType() == rhs.actionType() + && lhs.turnStep() == rhs.turnStep() + && lhs.dashStep() == rhs.dashStep(); + } }; } @@ -205,17 +205,31 @@ struct InterceptEqualSimple { */ void -SelfInterceptSimulator::simulate( const WorldModel & wm, - const int max_step, - std::vector< InterceptInfo > & self_cache ) +InterceptSimulatorSelfV17::simulate( const WorldModel & wm, + const int max_step, + std::vector< Intercept > & self_cache ) { #ifdef DEBUG_PROFILE rcsc::Timer timer; #endif + if ( wm.kickableOpponent() + //|| wm.kickableTeammate() + ) + { + M_ball_vel.assign( 0.0, 0.0 ); + } + else + { + M_ball_vel = wm.ball().vel(); + } + simulateOneStep( wm, self_cache ); simulateTurnDash( wm, max_step, false, self_cache ); // forward dash - simulateTurnDash( wm, max_step, true, self_cache ); // back dash + if ( ServerParam::i().minDashPower() < ServerParam::i().maxDashPower() * -0.7 ) + { + simulateTurnDash( wm, max_step, true, self_cache ); // back dash + } simulateOmniDash( wm, max_step, self_cache ); // omni dash if ( self_cache.empty() ) @@ -246,10 +260,10 @@ SelfInterceptSimulator::simulate( const WorldModel & wm, */ void -SelfInterceptSimulator::simulateOneStep( const WorldModel & wm, - std::vector< InterceptInfo > & self_cache ) +InterceptSimulatorSelfV17::simulateOneStep( const WorldModel & wm, + std::vector< Intercept > & self_cache ) { - const Vector2D ball_next = wm.ball().pos() + wm.ball().vel(); + const Vector2D ball_next = wm.ball().pos() + ballVel(); const bool goalie_mode = ( wm.self().goalie() && wm.lastKickerSide() != wm.ourSide() @@ -288,13 +302,13 @@ SelfInterceptSimulator::simulateOneStep( const WorldModel & wm, */ bool -SelfInterceptSimulator::simulateNoDash( const WorldModel & wm, - std::vector< InterceptInfo > & self_cache ) +InterceptSimulatorSelfV17::simulateNoDash( const WorldModel & wm, + std::vector< Intercept > & self_cache ) { const PlayerType & ptype = wm.self().playerType(); const Vector2D self_next = wm.self().pos() + wm.self().vel(); - const Vector2D ball_next = wm.ball().pos() + wm.ball().vel(); + const Vector2D ball_next = wm.ball().pos() + ballVel(); const bool goalie_mode = ( wm.self().goalie() @@ -306,7 +320,8 @@ SelfInterceptSimulator::simulateNoDash( const WorldModel & wm, ? ptype.maxCatchableDist() : ptype.kickableArea() ); - const double ball_noise = wm.ball().vel().r() * ServerParam::i().ballRand() * BALL_NOISE_RATE; + //const double ball_noise = wm.ball().vel().r() * ServerParam::i().ballRand() * BALL_NOISE_RATE; + const double ball_noise = ballVel().r() * ServerParam::i().ballRand() * BALL_NOISE_RATE; const double ball_next_dist = self_next.dist( ball_next ); if ( ball_next_dist > control_area - CONTROL_BUF - ball_noise ) @@ -325,8 +340,8 @@ SelfInterceptSimulator::simulateNoDash( const WorldModel & wm, StaminaModel stamina_model = wm.self().staminaModel(); stamina_model.simulateWait( ptype ); - self_cache.emplace_back( InterceptInfo::NORMAL, - InterceptInfo::TURN_FORWARD_DASH, + self_cache.emplace_back( Intercept::NORMAL, + Intercept::TURN_FORWARD_DASH, 1, 0.0, // 1 turn, but 0 moment 0, 0.0, 0.0, // 0 dash self_next, @@ -345,7 +360,7 @@ SelfInterceptSimulator::simulateNoDash( const WorldModel & wm, { AngleDeg ball_angle = ( ball_next - self_next ).th() - wm.self().body(); double kick_rate = ptype.kickRate( ball_next_dist, ball_angle.abs() ); - Vector2D ball_next_vel = wm.ball().vel() * ServerParam::i().ballDecay(); + Vector2D ball_next_vel = ballVel() * ServerParam::i().ballDecay(); if ( ServerParam::i().maxPower() * kick_rate <= ball_next_vel.r() * ServerParam::i().ballDecay() * 1.1 ) @@ -366,8 +381,8 @@ SelfInterceptSimulator::simulateNoDash( const WorldModel & wm, StaminaModel stamina_model = wm.self().staminaModel(); stamina_model.simulateWait( ptype ); - self_cache.emplace_back( InterceptInfo::NORMAL, - InterceptInfo::TURN_FORWARD_DASH, + self_cache.emplace_back( Intercept::NORMAL, + Intercept::TURN_FORWARD_DASH, 0, 0.0, // 0 turn 1, 0.0, 0.0, // 1 dash, 0 power self_next, @@ -381,18 +396,167 @@ SelfInterceptSimulator::simulateNoDash( const WorldModel & wm, return true; } + /*-------------------------------------------------------------------*/ /*! */ void -SelfInterceptSimulator::simulateOneDash( const WorldModel & wm, - std::vector< InterceptInfo > & self_cache ) +InterceptSimulatorSelfV17::simulateOneDash( const WorldModel & wm, + std::vector< Intercept > & self_cache ) +{ + simulateOneDashOld( wm, self_cache ); + // if ( ServerParam::i().minDashPower() < ServerParam::i().maxDashPower() * -0.7 ) + // { + // simulateOneDashOld( wm, self_cache ); + // } + // else + // { + // simulateOneDashAnyDir( wm, self_cache ); + // } +} + + +/*-------------------------------------------------------------------*/ +void +InterceptSimulatorSelfV17::simulateOneDashAnyDir( const WorldModel & wm, + std::vector< Intercept > & self_cache ) { const ServerParam & SP = ServerParam::i(); const PlayerType & ptype = wm.self().playerType(); - const Vector2D ball_next = wm.ball().pos() + wm.ball().vel(); + //const Vector2D self_next = wm.self().pos() + wm.self().vel(); + const Vector2D ball_next = wm.ball().pos() + ballVel(); + const bool goalie_mode + = ( wm.self().goalie() + && wm.lastKickerSide() != wm.ourSide() + && ball_next.x < SP.ourPenaltyAreaLineX() + && ball_next.absY() < SP.penaltyAreaHalfWidth() + ); + + Vector2D required_vel = ball_next - wm.self().pos(); + { + const double best_ball_dist = ptype.playerSize() + SP.ballSize() + ptype.kickableMargin() * 0.5; + const double best_move_dist = wm.self().pos().dist( ball_next ) - best_ball_dist; + if ( best_move_dist > 0.0 ) + { + required_vel.setLength( best_move_dist ); + } + else + { + required_vel *= -1.0; + required_vel.setLength( std::fabs( best_move_dist ) ); + } + } + + const Vector2D required_accel = required_vel - wm.self().vel(); + + StaminaModel stamina_model = wm.self().staminaModel(); + + const double dash_dir = SP.discretizeDashAngle( ( required_accel.th() - wm.self().body() ).degree() ); + const double dash_rate = SP.dashDirRate( dash_dir ) * ptype.dashPowerRate() * stamina_model.effort(); + + const double required_dash_power = std::min( required_accel.r() / dash_rate, SP.maxDashPower() ); + const double safe_dash_power = stamina_model.getSafetyDashPower( ptype, required_dash_power, 1.0 ); + + Vector2D self_pos = wm.self().pos(); + + double dash_power = safe_dash_power; + bool ok = false; + { + // safety dash power case + const Vector2D dash_accel = Vector2D::from_polar( safe_dash_power * dash_rate, wm.self().body() + dash_dir ); + const Vector2D self_vel = wm.self().vel() + dash_accel; + self_pos = wm.self().pos() + self_vel; + if ( goalie_mode + && ptype.getCatchProbability( self_pos, wm.self().body(), ball_next, 0.05, 1.0 ) > 0.9 ) + { + ok = true; + stamina_model.simulateDash( ptype, safe_dash_power ); + } + + if ( ! ok + && self_pos.dist( ball_next ) < ptype.kickableArea() - 0.075 ) + { + ok = true; + stamina_model.simulateDash( ptype, safe_dash_power ); + } + } + + if ( ! ok + && required_dash_power > safe_dash_power ) + { + // exhaust case + const Vector2D dash_accel = Vector2D::from_polar( required_dash_power * dash_rate, wm.self().body() + dash_dir ); + const Vector2D self_vel = wm.self().vel() + dash_accel; + self_pos = wm.self().pos() + self_vel; + + if ( goalie_mode + && ptype.getCatchProbability( self_pos, wm.self().body(), ball_next, 0.05, 1.0 ) > 0.9 ) + { + ok = true; + dash_power = required_dash_power; + stamina_model.simulateDash( ptype, dash_power ); + } + + if ( ! ok + && self_pos.dist( ball_next ) < ptype.kickableArea() - 0.075 ) + { + ok = true; + dash_power = required_dash_power; + stamina_model.simulateDash( ptype, dash_power ); + } + } + + if ( ! ok ) + { + // not found +#ifdef DEBUG_PRINT_ONE_STEP + dlog.addText( Logger::INTERCEPT, + "<<<<< 1 dash: not found" ); +#endif + return; + } + + Intercept::StaminaType stamina_type = Intercept::NORMAL; + if ( stamina_model.recovery() < wm.self().staminaModel().recovery() - 1.0e-5 + && ! stamina_model.capacityIsEmpty() ) + { + stamina_type = Intercept::EXHAUST; + } + + const double result_ball_dist = self_pos.dist( ball_next ); +#ifdef DEBUG_PRINT_ONE_STEP + dlog.addText( Logger::INTERCEPT, + "<<<<< 1 dash: power=%.1f dir=%.1f self_pos=(%.2f %.2f) ball_dist=%.3f", + dash_power, dash_dir, + self_pos.x, self_pos.y, result_ball_dist ); +#endif + + self_cache.emplace_back( stamina_type, + Intercept::OMNI_DASH, + 0, // turn step + 0, // turn angle + 1, // dash step + dash_power, + dash_dir, + self_pos, + result_ball_dist, + stamina_model.stamina() ); +} + +/*-------------------------------------------------------------------*/ +/*! + + */ +void +InterceptSimulatorSelfV17::simulateOneDashOld( const WorldModel & wm, + std::vector< Intercept > & self_cache ) +{ + const ServerParam & SP = ServerParam::i(); + const PlayerType & ptype = wm.self().playerType(); + + const Vector2D ball_next = wm.ball().pos() + ballVel(); const bool goalie_mode = ( wm.self().goalie() && wm.lastKickerSide() != wm.ourSide() @@ -403,12 +567,12 @@ SelfInterceptSimulator::simulateOneDash( const WorldModel & wm, ? ptype.maxCatchableDist() : ptype.kickableArea() ); - const double dash_angle_step = std::max( 5.0, SP.dashAngleStep() ); + const double dash_angle_step = std::max( 2.0, SP.dashAngleStep() ); const size_t dash_angle_divs - = static_cast< size_t >( std::floor( ( SP.maxDashAngle() - SP.minDashAngle() ) - / dash_angle_step ) ); + = static_cast< size_t >( std::floor( ( SP.maxDashAngle() - SP.minDashAngle() ) + / dash_angle_step ) ); - std::vector< InterceptInfo > tmp_cache; + std::vector< Intercept > tmp_cache; tmp_cache.reserve( dash_angle_divs ); for ( size_t d = 0 ; d < dash_angle_divs; ++d ) @@ -439,19 +603,19 @@ SelfInterceptSimulator::simulateOneDash( const WorldModel & wm, Vector2D max_forward_accel = rotate.transform( forward_dash_power * dash_rate, 0.0 ); Vector2D max_back_accel = rotate.transform( back_dash_power * dash_rate, 0.0 ); - InterceptInfo safe_dash = getOneAdjustDash( wm, - dash_angle, - max_forward_accel, - max_back_accel, - control_area ); + Intercept safe_dash = getOneAdjustDash( wm, + dash_angle, + max_forward_accel, + max_back_accel, + control_area ); if ( safe_dash.isValid() ) { #ifdef DEBUG_PRINT_ONE_STEP dlog.addText( Logger::INTERCEPT, "OK 1 dash: mode=%d power=%.1f dir=%.1f self_pos=(%.2f %.2f) stamina=%.1f", - safe_dash.mode(), + safe_dash.staminaType(), safe_dash.dashPower(), - safe_dash.dashAngle().degree(), + safe_dash.dashDir(), safe_dash.selfPos().x, safe_dash.selfPos().y, safe_dash.stamina() ); #endif @@ -473,18 +637,18 @@ SelfInterceptSimulator::simulateOneDash( const WorldModel & wm, Vector2D max_forward_accel = rotate.transform( SP.maxDashPower() * dash_rate, 0.0 ); Vector2D max_back_accel = rotate.transform( SP.minDashPower() * dash_rate, 0.0 ); - InterceptInfo exhaust_dash = getOneAdjustDash( wm, dash_angle, - max_forward_accel, - max_back_accel, - control_area ); + Intercept exhaust_dash = getOneAdjustDash( wm, dash_angle, + max_forward_accel, + max_back_accel, + control_area ); if ( exhaust_dash.isValid() ) { #ifdef DEBUG_PRINT_ONE_STEP dlog.addText( Logger::INTERCEPT, "OK 1 dash: mode=%d power=%.1f dir=%.1f self_pos=(%.2f %.2f) stamina=%.1f", - exhaust_dash.mode(), + exhaust_dash.staminaType(), exhaust_dash.dashPower(), - exhaust_dash.dashAngle().degree(), + exhaust_dash.dashDir(), exhaust_dash.selfPos().x, exhaust_dash.selfPos().y, exhaust_dash.stamina() ); #endif @@ -500,14 +664,13 @@ SelfInterceptSimulator::simulateOneDash( const WorldModel & wm, } const double safe_ball_dist - = std::max( control_area - 0.2 - wm.ball().vel().r() * SP.ballRand(), + = std::max( control_area - 0.2 - ballVel().r() * SP.ballRand(), ptype.playerSize() + SP.ballSize() + ptype.kickableMargin() * 0.4 ); - const InterceptInfo * best = &(tmp_cache.front()); + const Intercept * best = &(tmp_cache.front()); - for ( std::vector< InterceptInfo >::iterator it = tmp_cache.begin() + 1, - end = tmp_cache.end(); + for ( std::vector< Intercept >::iterator it = tmp_cache.begin() + 1, end = tmp_cache.end(); it != end; ++it ) { @@ -533,7 +696,7 @@ SelfInterceptSimulator::simulateOneDash( const WorldModel & wm, #ifdef DEBUG_PRINT_ONE_STEP dlog.addText( Logger::INTERCEPT, "<<<<< 1 dash: best (t=%d d=%d) self_pos=(%.2f %.2f) ball_dist=%.3f stamina=%.1f", - best->reachCycle(), best->turnCycle(), best->dashCycle(), + best->reachStep(), best->turnStep(), best->dashStep(), best->ballDist(), best->selfPos().x, best->selfPos().y, best->stamina() ); @@ -546,19 +709,19 @@ SelfInterceptSimulator::simulateOneDash( const WorldModel & wm, /*! */ -InterceptInfo -SelfInterceptSimulator::getOneAdjustDash( const WorldModel & wm, - const AngleDeg & dash_angle, - const Vector2D & max_forward_accel, - const Vector2D & max_back_accel, - const double control_area ) +Intercept +InterceptSimulatorSelfV17::getOneAdjustDash( const WorldModel & wm, + const AngleDeg & dash_angle, + const Vector2D & max_forward_accel, + const Vector2D & max_back_accel, + const double control_area ) { const ServerParam & SP = ServerParam::i(); const double control_buf = control_area - 0.075; const Vector2D self_next = wm.self().pos() + wm.self().vel( ); - const Vector2D ball_next = wm.ball().pos() + wm.ball().vel(); + const Vector2D ball_next = wm.ball().pos() + ballVel(); const AngleDeg dash_dir = dash_angle - wm.self().body(); const Matrix2D rotate = Matrix2D::make_rotation( -dash_angle ); @@ -580,7 +743,7 @@ SelfInterceptSimulator::getOneAdjustDash( const WorldModel & wm, ball_rel.dist( forward_accel_rel ), ball_rel.dist( back_accel_rel ) ); #endif - return InterceptInfo(); + return Intercept(); } double dash_power = -1000.0; @@ -665,13 +828,13 @@ SelfInterceptSimulator::getOneAdjustDash( const WorldModel & wm, dlog.addText( Logger::INTERCEPT, "__(getOneAdjustDash) XXX Failed" ); #endif - return InterceptInfo(); + return Intercept(); } // // register // - InterceptInfo::StaminaType stamina_type = InterceptInfo::NORMAL; + Intercept::StaminaType stamina_type = Intercept::NORMAL; const Vector2D accel = Vector2D::polar2vector( dash_power * dash_rate, dash_angle ); const Vector2D self_next_after_dash = wm.self().pos() + wm.self().vel() + accel; @@ -682,25 +845,25 @@ SelfInterceptSimulator::getOneAdjustDash( const WorldModel & wm, if ( stamina_model.recovery() < wm.self().staminaModel().recovery() - 1.0e-5 && ! stamina_model.capacityIsEmpty() ) { - stamina_type = InterceptInfo::EXHAUST; + stamina_type = Intercept::EXHAUST; } - InterceptInfo info( stamina_type, - ( dash_power > 0.0 - ? InterceptInfo::TURN_FORWARD_DASH - : InterceptInfo::TURN_BACK_DASH ), - 0, 0.0, - 1, dash_power, dash_dir.degree(), - self_next_after_dash, - self_next_after_dash.dist( ball_next ), - stamina_model.stamina() ); + Intercept info( stamina_type, + ( dash_power > 0.0 + ? Intercept::TURN_FORWARD_DASH + : Intercept::TURN_BACK_DASH ), + 0, 0.0, + 1, dash_power, dash_dir.degree(), + self_next_after_dash, + self_next_after_dash.dist( ball_next ), + stamina_model.stamina() ); #ifdef DEBUG_PRINT_ONE_STEP dlog.addText( Logger::INTERCEPT, "__*** (predictOneDashAdjust) --->Success! power=%.3f rel_dir=%.1f angle=%.1f" " my_pos=(%.2f %.2f) ball_dist=%.3f stamina=%.1f", info.dashPower(), - info.dashAngle().degree(), + info.dashDir(), dash_angle.degree(), self_next_after_dash.x, self_next_after_dash.y, info.ballDist(), @@ -715,11 +878,11 @@ SelfInterceptSimulator::getOneAdjustDash( const WorldModel & wm, */ double -SelfInterceptSimulator::getOneStepDashPower( const WorldModel & wm, - const Vector2D & ball_next_rel, - const AngleDeg & dash_angle, - const double max_forward_accel_x, - const double max_back_accel_x ) +InterceptSimulatorSelfV17::getOneStepDashPower( const WorldModel & wm, + const Vector2D & ball_next_rel, + const AngleDeg & dash_angle, + const double max_forward_accel_x, + const double max_back_accel_x ) { const PlayerType & ptype = wm.self().playerType(); @@ -741,13 +904,13 @@ SelfInterceptSimulator::getOneStepDashPower( const WorldModel & wm, } const double forward_trap_accel_x - = ball_next_rel.x - - std::sqrt( std::pow( best_ctrl_dist_forward, 2 ) - - std::pow( ball_next_rel.y, 2 ) ); + = ball_next_rel.x + - std::sqrt( std::pow( best_ctrl_dist_forward, 2 ) + - std::pow( ball_next_rel.y, 2 ) ); const double backward_trap_accel_x - = ball_next_rel.x - + std::sqrt( std::pow( best_ctrl_dist_backward, 2 ) - - std::pow( ball_next_rel.y, 2 ) ); + = ball_next_rel.x + + std::sqrt( std::pow( best_ctrl_dist_backward, 2 ) + - std::pow( ball_next_rel.y, 2 ) ); // // get the minimum dash power @@ -788,12 +951,16 @@ namespace { */ int -get_min_step( const WorldModel & wm ) +get_min_step( const WorldModel & wm, + const Vector2D & ball_vel ) { const Rect2D pitch_rect = Rect2D::from_center( Vector2D( 0.0, 0.0 ), ServerParam::i().pitchLength() + 10.0, ServerParam::i().pitchWidth() + 10.0 ); - Vector2D final_pos = wm.ball().inertiaFinalPoint(); + //Vector2D final_pos = wm.ball().inertiaFinalPoint(); + Vector2D final_pos = inertia_final_point( wm.ball().pos(), + ball_vel, + ServerParam::i().ballDecay() ); if ( ! pitch_rect.contains( final_pos ) ) { @@ -886,17 +1053,19 @@ simulate_turn_step( const WorldModel & wm, */ void -SelfInterceptSimulator::simulateTurnDash( const WorldModel & wm, - const int max_step, - const bool back_dash, - std::vector< InterceptInfo > & self_cache ) +InterceptSimulatorSelfV17::simulateTurnDash( const WorldModel & wm, + const int max_step, + const bool back_dash, + std::vector< Intercept > & self_cache ) { const ServerParam & SP = ServerParam::i(); const PlayerType & ptype = wm.self().playerType(); - const int min_step = get_min_step( wm ); + const int min_step = get_min_step( wm, ballVel() ); - Vector2D ball_pos = wm.ball().inertiaPoint( min_step - 1 ); - Vector2D ball_vel = wm.ball().vel() * std::pow( SP.ballDecay(), min_step - 1 ); + //Vector2D ball_pos = wm.ball().inertiaPoint( min_step - 1 ); + Vector2D ball_pos = inertia_n_step_point( wm.ball().pos(), ballVel(), min_step - 1, SP.ballDecay() ); + //Vector2D ball_vel = wm.ball().vel() * std::pow( SP.ballDecay(), min_step - 1 ); + Vector2D ball_vel = ballVel() * std::pow( SP.ballDecay(), min_step - 1 ); double ball_speed = ball_vel.r(); int success_count = 0; @@ -940,13 +1109,13 @@ SelfInterceptSimulator::simulateTurnDash( const WorldModel & wm, continue; } - InterceptInfo info = getTurnDash( wm, ball_pos, control_area, ball_noise, step, back_dash ); + Intercept info = getTurnDash( wm, ball_pos, control_area, ball_noise, step, back_dash ); if ( info.isValid() ) { #ifdef DEBUG_PRINT_TURN_DASH dlog.addText( Logger::INTERCEPT, ">>>>> %d: (simulateTurnDash) OK turn=%d dash=%d", - step, info.turnCycle(), info.dashCycle() ); + step, info.turnStep(), info.dashStep() ); #endif self_cache.push_back( info ); if ( ++success_count >= 10 ) @@ -969,13 +1138,13 @@ SelfInterceptSimulator::simulateTurnDash( const WorldModel & wm, /*! */ -InterceptInfo -SelfInterceptSimulator::getTurnDash( const WorldModel & wm, - const Vector2D & ball_pos, - const double control_area, - const double ball_noise, - const int step, - const bool back_dash ) +Intercept +InterceptSimulatorSelfV17::getTurnDash( const WorldModel & wm, + const Vector2D & ball_pos, + const double control_area, + const double ball_noise, + const int step, + const bool back_dash ) { const ServerParam & SP = ServerParam::i(); const PlayerType & ptype = wm.self().playerType(); @@ -1000,7 +1169,7 @@ SelfInterceptSimulator::getTurnDash( const WorldModel & wm, "%d: xx (getTurnDash) n_turn=%d dash_angle=%.1f", step, n_turn, dash_angle.degree() ); #endif - return InterceptInfo(); + return Intercept(); } const AngleDeg body_angle = ( n_turn == 0 ? wm.self().body() @@ -1027,7 +1196,7 @@ SelfInterceptSimulator::getTurnDash( const WorldModel & wm, if ( ( back_dash && ball_rel_to_inertia.x > 0.0 ) || ( ! back_dash && ball_rel_to_inertia.x < 0.0 ) ) { - return InterceptInfo(); + return Intercept(); } } @@ -1074,27 +1243,56 @@ SelfInterceptSimulator::getTurnDash( const WorldModel & wm, } } + bool ok = false; if ( self_pos.absX() > ball_rel.absX() - 1.0e-5 || self_pos.r2() > ball_rel.r2() - || self_pos.dist2( ball_rel ) < std::pow( control_area - control_buf, 2 ) ) + || self_pos.dist2( ball_rel ) < std::pow( ptype.kickableArea() - control_buf, 2 ) ) { - InterceptInfo::StaminaType stamina_type = ( stamina_model.recovery() < wm.self().staminaModel().recovery() - 1.0e-5 - && ! stamina_model.capacityIsEmpty() - ? InterceptInfo::EXHAUST - : InterceptInfo::NORMAL ); - return InterceptInfo( stamina_type, - ( back_dash - ? InterceptInfo::TURN_BACK_DASH - : InterceptInfo::TURN_FORWARD_DASH ), - n_turn, ( body_angle - wm.self().body() ).degree(), - max_dash_step, first_dash_power, 0.0, - wm.self().pos() + self_pos.rotatedVector( body_angle ), - self_pos.dist( ball_rel ), - stamina_model.stamina() ); + ok = true; + } + + if ( ! ok + && goalie_mode + && ptype.getCatchProbability( self_pos, 0.0, ball_rel, 0.05, 1.0 ) > 0.9 ) + { + ok = true; + } + + if ( ok ) + { + Intercept::StaminaType stamina_type = ( stamina_model.recovery() < wm.self().staminaModel().recovery() - 1.0e-5 + && ! stamina_model.capacityIsEmpty() + ? Intercept::EXHAUST + : Intercept::NORMAL ); + return Intercept( stamina_type, + ( back_dash + ? Intercept::TURN_BACK_DASH + : Intercept::TURN_FORWARD_DASH ), + n_turn, ( body_angle - wm.self().body() ).degree(), + max_dash_step, first_dash_power, 0.0, + wm.self().pos() + self_pos.rotatedVector( body_angle ), + self_pos.dist( ball_rel ), + stamina_model.stamina() ); } - return InterceptInfo(); + return Intercept(); +} + +/*-------------------------------------------------------------------*/ +void +InterceptSimulatorSelfV17::simulateOmniDash( const WorldModel & wm, + const int max_step, + std::vector< Intercept > & self_cache ) +{ + if ( ServerParam::i().dashAngleStep() > 1.5 ) + { + simulateOmniDashOld( wm, max_step, self_cache ); + } + else + { + simulateOmniDashAny( wm, max_step, self_cache ); + } } /*-------------------------------------------------------------------*/ @@ -1102,12 +1300,139 @@ SelfInterceptSimulator::getTurnDash( const WorldModel & wm, */ void -SelfInterceptSimulator::simulateOmniDash( const WorldModel & wm, - const int max_step, - std::vector< InterceptInfo > & self_cache ) +InterceptSimulatorSelfV17::simulateOmniDashAny( const WorldModel & wm, + const int max_step, + std::vector< Intercept > & self_cache ) { const ServerParam & SP = ServerParam::i(); - const double dash_angle_step = std::max( 15.0, SP.dashAngleStep() ); + const PlayerType & ptype = wm.self().playerType(); + const double max_side_speed = ( SP.maxDashPower() + * ptype.dashPowerRate() + * ptype.effortMax() + * SP.dashDirRate( 90.0 ) ) / ( 1.0 - ptype.playerDecay() ); + const Matrix2D rotate_matrix = Matrix2D::make_rotation( -wm.self().body() ); + //const double first_ball_speed = wm.ball().vel().r(); + const double first_ball_speed = ballVel().r(); + +#ifdef DEBUG_PRINT_OMNI_DASH + dlog.addText( Logger::INTERCEPT, + "===== (simulateOmniDashAny) max_step=%d", max_step ); +#endif + + int success_count = 0; + for ( int ball_step = 1; ball_step <= max_step; ++ball_step ) + { + //const Vector2D ball_pos = wm.ball().inertiaPoint( ball_step ); + const Vector2D ball_pos = inertia_n_step_point( wm.ball().pos(), ballVel(), ball_step, SP.ballDecay() ); + const bool goalie_mode = ( wm.self().goalie() + && wm.lastKickerSide() != wm.ourSide() + && ball_pos.x < SP.ourPenaltyAreaLineX() - 0.5 + && ball_pos.absY() < SP.penaltyAreaHalfWidth() - 0.5 ); + const double control_area = ( goalie_mode + ? ptype.maxCatchableDist() + : ptype.kickableArea() ); + const double ball_noise = ( first_ball_speed * std::pow( SP.ballDecay(), ball_step - 1 ) + * SP.ballRand() + * BALL_NOISE_RATE ); + const double control_buf = ( goalie_mode + ? 0.0 + : CONTROL_BUF + ball_noise ); + + const Vector2D self_inertia = wm.self().inertiaPoint( ball_step ); + + const Vector2D ball_rel = rotate_matrix.transform( ball_pos - self_inertia ); + if ( ball_rel.absY() - control_area > max_side_speed * ball_step ) + { + continue; + } + + //const AngleDeg accel_angle = ( ball_pos - self_inertia ).th(); + + double first_dash_power = 0.0; + double first_dash_dir = 0.0; + + Vector2D self_pos = wm.self().pos(); + Vector2D self_vel = wm.self().vel(); + StaminaModel stamina_model = wm.self().staminaModel(); + + for ( int step = 1; step <= ball_step; ++step ) + { + const Vector2D required_vel = ( ball_pos - self_pos ) + * ( ( 1.0 - ptype.playerDecay() ) + / ( 1.0 - std::pow( ptype.playerDecay(), ball_step - step + 1 ) ) ); + const Vector2D required_accel = required_vel - self_vel; + + const double dash_dir = SP.discretizeDashAngle( ( required_accel.th() - wm.self().body() ).degree() ); + const double dash_rate = SP.dashDirRate( dash_dir ) * ptype.dashPowerRate() * stamina_model.effort(); + double dash_power = std::min( SP.maxDashPower(), required_accel.r() / dash_rate ); + dash_power = stamina_model.getSafetyDashPower( ptype, dash_power, 1.0 ); + + if ( step == 1 ) + { + first_dash_power = dash_power; + first_dash_dir = dash_dir; + } + + const Vector2D dash_accel = Vector2D::from_polar( dash_power * dash_rate, wm.self().body() + dash_dir ); + self_vel += dash_accel; + self_pos += self_vel; + self_vel *= ptype.playerDecay(); + stamina_model.simulateDash( ptype, dash_power ); + + bool ok = false; + + if ( self_pos.dist2( ball_pos ) < std::pow( ptype.kickableArea() - control_buf, 2 ) + || self_inertia.dist2( self_pos ) > self_inertia.dist2( ball_pos ) ) + { + ok = true; + } + + if ( ! ok + && goalie_mode + && ptype.getCatchProbability( self_pos, wm.self().body(), ball_pos, 0.05, 1.0 ) > 0.9 ) + { + ok = true; +#ifdef DEBUG_PRINT_OMNI_DASH + dlog.addText( Logger::INTERCEPT, + "[omni]>>> found in goalie mode" ); +#endif + } + + if ( ok ) + { + Intercept::StaminaType stamina_type = ( stamina_model.recovery() < wm.self().staminaModel().recovery() - 1.0e-5 + && ! stamina_model.capacityIsEmpty() + ? Intercept::EXHAUST + : Intercept::NORMAL ); + self_cache.emplace_back( stamina_type, + Intercept::OMNI_DASH, + 0, 0.0, + ball_step, first_dash_power, first_dash_dir, + self_pos, + self_pos.dist( ball_pos ), + stamina_model.stamina() ); + ++success_count; +#ifdef DEBUG_PRINT_OMNI_DASH + dlog.addText( Logger::INTERCEPT, + "[omni]>>> found ball_step=%d self_step=%d", ball_step, step ); +#endif + break; + } + } + } +} + +/*-------------------------------------------------------------------*/ +/*! + + */ +void +InterceptSimulatorSelfV17::simulateOmniDashOld( const WorldModel & wm, + const int max_step, + std::vector< Intercept > & self_cache ) +{ + const ServerParam & SP = ServerParam::i(); + const double dash_angle_step = std::max( 5.0, SP.dashAngleStep() ); const size_t dash_angle_divs = static_cast< size_t >( std::floor( 360.0 / dash_angle_step ) ); const PlayerType & ptype = wm.self().playerType(); @@ -1153,7 +1478,7 @@ SelfInterceptSimulator::simulateOmniDash( const WorldModel & wm, // // simulation loop // - const double first_ball_speed = wm.ball().vel().r(); + const double first_ball_speed = ballVel().r(); #ifdef DEBUG_PRINT_OMNI_DASH dlog.addText( Logger::INTERCEPT, @@ -1165,7 +1490,8 @@ SelfInterceptSimulator::simulateOmniDash( const WorldModel & wm, double last_y_diff = 100000.0; for ( int reach_step = 1; reach_step <= max_step; ++reach_step ) { - const Vector2D ball_pos = wm.ball().inertiaPoint( reach_step ); + //const Vector2D ball_pos = wm.ball().inertiaPoint( reach_step ); + const Vector2D ball_pos = inertia_n_step_point( wm.ball().pos(), ballVel(), reach_step, SP.ballDecay() ); const bool goalie_mode = ( wm.self().goalie() && wm.lastKickerSide() != wm.ourSide() @@ -1335,17 +1661,17 @@ SelfInterceptSimulator::simulateOmniDash( const WorldModel & wm, std::ostringstream ostr; for ( size_t i = 0; i < dash_list.size(); ++i ) { - ostr << '(' << dash_list[i].first << ' ' << dash_list[i].second << ')'; + ostr << '(' << dash_list[i].first << ' ' << dash_list[i].second << ')'; } dlog.addText( Logger::INTERCEPT, ">>> dash %s", ostr.str().c_str() ); #endif - InterceptInfo::StaminaType stamina_type = ( stamina_model.recovery() < wm.self().staminaModel().recovery() - 1.0e-5 - && ! stamina_model.capacityIsEmpty() - ? InterceptInfo::EXHAUST - : InterceptInfo::NORMAL ); + Intercept::StaminaType stamina_type = ( stamina_model.recovery() < wm.self().staminaModel().recovery() - 1.0e-5 + && ! stamina_model.capacityIsEmpty() + ? Intercept::EXHAUST + : Intercept::NORMAL ); self_cache.emplace_back( stamina_type, - InterceptInfo::OMNI_DASH, + Intercept::OMNI_DASH, 0, 0.0, reach_step, first_dash_power, first_dash_dir, self_pos, @@ -1388,14 +1714,15 @@ SelfInterceptSimulator::simulateOmniDash( const WorldModel & wm, */ void -SelfInterceptSimulator::simulateFinal( const WorldModel & wm, - const int max_step, - std::vector< InterceptInfo > & self_cache ) +InterceptSimulatorSelfV17::simulateFinal( const WorldModel & wm, + const int max_step, + std::vector< Intercept > & self_cache ) { const PlayerType & ptype = wm.self().playerType(); const Vector2D self_pos = wm.self().inertiaFinalPoint(); - const Vector2D ball_pos = wm.ball().inertiaFinalPoint(); + //const Vector2D ball_pos = wm.ball().inertiaFinalPoint(); + const Vector2D ball_pos = inertia_final_point( wm.ball().pos(), ballVel(), ServerParam::i().ballDecay() ); const bool goalie_mode = ( wm.self().goalie() && wm.lastKickerSide() != wm.ourSide() && ball_pos.x < ServerParam::i().ourPenaltyAreaLineX() - 0.5 @@ -1419,8 +1746,8 @@ SelfInterceptSimulator::simulateFinal( const WorldModel & wm, stamina_model.simulateWaits( ptype, n_turn ); stamina_model.simulateDashes( ptype, n_dash, ServerParam::i().maxDashPower() ); - self_cache.emplace_back( InterceptInfo::NORMAL, - InterceptInfo::TURN_FORWARD_DASH, + self_cache.emplace_back( Intercept::NORMAL, + Intercept::TURN_FORWARD_DASH, n_turn, ( dash_angle - wm.self().body() ).degree(), n_dash, ServerParam::i().maxDashPower(), 0.0, ball_pos, diff --git a/rcsc/player/self_intercept_simulator.h b/rcsc/player/intercept_simulator_self_v17.h similarity index 50% rename from rcsc/player/self_intercept_simulator.h rename to rcsc/player/intercept_simulator_self_v17.h index e7330c5..363cefa 100644 --- a/rcsc/player/self_intercept_simulator.h +++ b/rcsc/player/intercept_simulator_self_v17.h @@ -1,8 +1,8 @@ // -*-c++-*- /*! - \file self_intercept_simulator.h - \brief self intercept simulator for creating candidate intercept actions + \file intercept_simulator_self_v17.h + \brief intercept simulator for self */ /* @@ -29,52 +29,65 @@ ///////////////////////////////////////////////////////////////////// -#ifndef RCSC_PLAYER_SELF_INTERCEPT_SIMULATOR_H -#define RCSC_PLAYER_SELF_INTERCEPT_SIMULATOR_H +#ifndef RCSC_PLAYER_INTERCEPT_SIMULATOR_SELF_V17_H +#define RCSC_PLAYER_INTERCEPT_SIMULATOR_SELF_V17_H + +#include -#include #include #include namespace rcsc { - class BallObject; class SelfObject; class WorldModel; class StaminaModel; -class SelfInterceptSimulator { +class InterceptSimulatorSelfV17 + : public InterceptSimulatorSelf { private: + Vector2D M_ball_vel; + public: /*! - \brief simulate self interception, and store the results to self_cache + \brief simulate self interception, and store the results to self_results \param max_step max estimation cycle - \param self_cache reference to the interception info container - to store the result + \param self_results reference to the result container */ void simulate( const WorldModel & wm, const int max_step, - std::vector< InterceptInfo > & self_cache ); + std::vector< Intercept > & self_results ) override; private: + const Vector2D & ballVel() const + { + return M_ball_vel; + } + // // one step simulation // void simulateOneStep( const WorldModel & wm, - std::vector< InterceptInfo > & self_cache ); + std::vector< Intercept > & self_cache ); bool simulateNoDash( const WorldModel & wm, - std::vector< InterceptInfo > & self_cache ); + std::vector< Intercept > & self_cache ); + void simulateOneDash( const WorldModel & wm, - std::vector< InterceptInfo > & self_cache ); - InterceptInfo getOneAdjustDash( const WorldModel & wm, - const AngleDeg & dash_angle, - const Vector2D & max_forward_accel, - const Vector2D & max_back_accel, - const double control_area ); + std::vector< Intercept > & self_cache ); + void simulateOneDashAnyDir( const WorldModel & wm, + std::vector< Intercept > & self_cache ); + + void simulateOneDashOld( const WorldModel & wm, + std::vector< Intercept > & self_cache ); + Intercept getOneAdjustDash( const WorldModel & wm, + const AngleDeg & dash_angle, + const Vector2D & max_forward_accel, + const Vector2D & max_back_accel, + const double control_area ); double getOneStepDashPower( const WorldModel & wm, const Vector2D & next_ball_rel, const AngleDeg & dash_angle, @@ -87,21 +100,28 @@ class SelfInterceptSimulator { void simulateTurnDash( const WorldModel & wm, const int max_step, const bool back_dash, - std::vector< InterceptInfo > & self_cache ); - InterceptInfo getTurnDash( const WorldModel & wm, - const Vector2D & ball_pos, - const double control_area, - const double ball_noise, - const int step, - const bool back_dash ); + std::vector< Intercept > & self_cache ); + Intercept getTurnDash( const WorldModel & wm, + const Vector2D & ball_pos, + const double control_area, + const double ball_noise, + const int step, + const bool back_dash ); void simulateOmniDash( const WorldModel & wm, const int max_step, - std::vector< InterceptInfo > & self_cache ); + std::vector< Intercept > & self_cache ); + void simulateOmniDashAny( const WorldModel & wm, + const int max_step, + std::vector< Intercept > & self_cache ); + void simulateOmniDashOld( const WorldModel & wm, + const int max_step, + std::vector< Intercept > & self_cache ); + void simulateFinal( const WorldModel & wm, const int max_step, - std::vector< InterceptInfo > & self_cache ); + std::vector< Intercept > & self_cache ); }; } diff --git a/rcsc/player/self_intercept.cpp b/rcsc/player/intercept_simulator_self_v7.cpp similarity index 100% rename from rcsc/player/self_intercept.cpp rename to rcsc/player/intercept_simulator_self_v7.cpp diff --git a/rcsc/player/self_intercept.h b/rcsc/player/intercept_simulator_self_v7.h similarity index 100% rename from rcsc/player/self_intercept.h rename to rcsc/player/intercept_simulator_self_v7.h diff --git a/rcsc/player/intercept_table.cpp b/rcsc/player/intercept_table.cpp index 338c0d9..6d4f796 100644 --- a/rcsc/player/intercept_table.cpp +++ b/rcsc/player/intercept_table.cpp @@ -34,8 +34,10 @@ #endif #include "intercept_table.h" -#include "self_intercept_simulator.h" -#include "player_intercept.h" + +#include "intercept_simulator_self_v17.h" +#include "intercept_simulator_player.h" + #include "world_model.h" #include "player_object.h" #include "abstract_player_object.h" @@ -59,12 +61,10 @@ const int MAX_STEP = 50; /*! */ -InterceptTable::InterceptTable( const WorldModel & world ) - : M_world( world ), - M_update_time( 0, 0 ) +InterceptTable::InterceptTable() + : M_update_time( 0, 0 ) { - M_ball_cache.reserve( MAX_STEP ); - M_self_cache.reserve( ( MAX_STEP + 1 ) * 2 ); + M_self_results.reserve( ( MAX_STEP + 1 ) * 2 ); clear(); } @@ -76,22 +76,20 @@ InterceptTable::InterceptTable( const WorldModel & world ) void InterceptTable::clear() { - M_ball_cache.clear(); - - M_self_reach_step = 1000; - M_self_exhaust_reach_step = 1000; - M_teammate_reach_step = 1000; - M_second_teammate_reach_step = 1000; - M_goalie_reach_step = 1000; - M_opponent_reach_step = 1000; - M_second_opponent_reach_step = 1000; - - M_fastest_teammate = nullptr; + M_self_step = 1000; + M_self_exhaust_step = 1000; + M_teammate_step = 1000; + M_second_teammate_step = 1000; + M_our_goalie_step = 1000; + M_opponent_step = 1000; + M_second_opponent_step = 1000; + + M_first_teammate = nullptr; M_second_teammate = nullptr; - M_fastest_opponent = nullptr; + M_first_opponent = nullptr; M_second_opponent = nullptr; - M_self_cache.clear(); + M_self_results.clear(); M_player_map.clear(); } @@ -101,13 +99,13 @@ InterceptTable::clear() */ void -InterceptTable::update() +InterceptTable::update( const WorldModel & wm ) { - if ( M_world.time() == M_update_time ) + if ( wm.time() == M_update_time ) { return; } - M_update_time = M_world.time(); + M_update_time = wm.time(); #ifdef DEBUG_PRINT dlog.addText( Logger::INTERCEPT, @@ -119,14 +117,14 @@ InterceptTable::update() this->clear(); // playmode check - if ( M_world.gameMode().type() == GameMode::TimeOver - || M_world.gameMode().type() == GameMode::BeforeKickOff ) + if ( wm.gameMode().type() == GameMode::TimeOver + || wm.gameMode().type() == GameMode::BeforeKickOff ) { return; } - if ( ! M_world.self().posValid() - || ! M_world.ball().posValid() ) + if ( ! wm.self().posValid() + || ! wm.ball().posValid() ) { dlog.addText( Logger::INTERCEPT, __FILE__" (update) Invalid self or ball pos" ); @@ -134,51 +132,49 @@ InterceptTable::update() } #ifdef DEBUG - if ( M_world.self().isKickable() - || M_world.kickableTeammate() - || M_world.kickableOpponent() ) + if ( wm.self().isKickable() + || wm.kickableTeammate() + || wm.kickableOpponent() ) { dlog.addText( Logger::INTERCEPT, __FILE__" (update) Already exist kickable player" ); } #endif - createBallCache(); - #ifdef DEBUG dlog.addText( Logger::INTERCEPT, "==========Intercept Predict Self==========" ); #endif - predictSelf(); + predictSelf( wm ); #ifdef DEBUG dlog.addText( Logger::INTERCEPT, "==========Intercept Predict Opponent==========" ); #endif - predictOpponent(); + predictOpponent( wm ); #ifdef DEBUG dlog.addText( Logger::INTERCEPT, "==========Intercept Predict Teammate==========" ); #endif - predictTeammate(); + predictTeammate( wm ); dlog.addText( Logger::INTERCEPT, "<-----Intercept Self reach step = %d. exhaust reach step = %d ", - M_self_reach_step, - M_self_exhaust_reach_step ); - if ( M_fastest_teammate ) + M_self_step, + M_self_exhaust_step ); + if ( M_first_teammate ) { dlog.addText( Logger::INTERCEPT, "<-----Intercept Teammate fastest reach step = %d." " teammate %d (%.1f %.1f)", - M_teammate_reach_step, - M_fastest_teammate->unum(), - M_fastest_teammate->pos().x, - M_fastest_teammate->pos().y ); + M_teammate_step, + M_first_teammate->unum(), + M_first_teammate->pos().x, + M_first_teammate->pos().y ); } @@ -187,21 +183,21 @@ InterceptTable::update() dlog.addText( Logger::INTERCEPT, "<-----Intercept Teammate 2nd reach step = %d." " teammate %d (%.1f %.1f)", - M_second_teammate_reach_step, + M_second_teammate_step, M_second_teammate->unum(), M_second_teammate->pos().x, M_second_teammate->pos().y ); } - if ( M_fastest_opponent ) + if ( M_first_opponent ) { dlog.addText( Logger::INTERCEPT, "<-----Intercept Opponent fastest reach step = %d." " opponent %d (%.1f %.1f)", - M_opponent_reach_step, - M_fastest_opponent->unum(), - M_fastest_opponent->pos().x, - M_fastest_opponent->pos().y ); + M_opponent_step, + M_first_opponent->unum(), + M_first_opponent->pos().x, + M_first_opponent->pos().y ); } if ( M_second_opponent ) @@ -209,7 +205,7 @@ InterceptTable::update() dlog.addText( Logger::INTERCEPT, "<-----Intercept Opponent 2nd reach step = %d." " opponent %d (%.1f %.1f)", - M_second_opponent_reach_step, + M_second_opponent_step, M_second_opponent->unum(), M_second_opponent->pos().x, M_second_opponent->pos().y ); @@ -226,17 +222,18 @@ InterceptTable::update() */ void -InterceptTable::hearTeammate( const int unum, +InterceptTable::hearTeammate( const WorldModel & wm, + const int unum, const int step ) { - if ( M_fastest_teammate - && step >= M_teammate_reach_step ) + if ( M_first_teammate + && step >= M_teammate_step ) { return; } const PlayerObject * target = nullptr; - for ( const PlayerObject * t : M_world.teammates() ) + for ( const PlayerObject * t : wm.teammates() ) { if ( t->unum() == unum ) { @@ -247,18 +244,18 @@ InterceptTable::hearTeammate( const int unum, if ( target ) { - M_fastest_teammate = target; - M_teammate_reach_step = step; + M_first_teammate = target; + M_teammate_step = step; M_player_map[ target ] = step; dlog.addText( Logger::INTERCEPT, "<----- Hear Intercept Teammate fastest reach step = %d." " teammate %d (%.1f %.1f)", - M_teammate_reach_step, - M_fastest_teammate->unum(), - M_fastest_teammate->pos().x, - M_fastest_teammate->pos().y ); + M_teammate_step, + M_first_teammate->unum(), + M_first_teammate->pos().x, + M_first_teammate->pos().y ); } } @@ -267,36 +264,37 @@ InterceptTable::hearTeammate( const int unum, */ void -InterceptTable::hearOpponent( const int unum, +InterceptTable::hearOpponent( const WorldModel & wm, + const int unum, const int step ) { - if ( M_fastest_opponent ) + if ( M_first_opponent ) { - if ( step >= M_opponent_reach_step ) + if ( step >= M_opponent_step ) { dlog.addText( Logger::INTERCEPT, "<----- Hear Intercept Opponent. no update." " exist faster reach step %d >= %d", - step, M_opponent_reach_step ); + step, M_opponent_step ); return; } - if ( M_fastest_opponent->unum() == unum - && M_fastest_opponent->posCount() == 0 ) + if ( M_first_opponent->unum() == unum + && M_first_opponent->posCount() == 0 ) { dlog.addText( Logger::INTERCEPT, "<----- Hear Intercept Opponent . no update." " opponent %d (%.1f %.1f) is seen", - M_fastest_opponent->unum(), - M_fastest_opponent->pos().x, - M_fastest_opponent->pos().y ); + M_first_opponent->unum(), + M_first_opponent->pos().x, + M_first_opponent->pos().y ); return; } } const PlayerObject * p = nullptr; - for ( const PlayerObject * i : M_world.opponents() ) + for ( const PlayerObject * i : wm.opponents() ) { if ( i->unum() == unum ) { @@ -308,18 +306,18 @@ InterceptTable::hearOpponent( const int unum, if ( p ) { - M_fastest_opponent = p; - M_opponent_reach_step = step; + M_first_opponent = p; + M_opponent_step = step; M_player_map[ p ] = step; dlog.addText( Logger::INTERCEPT, "<----- Hear Intercept Opponent fastest reach step = %d." " opponent %d (%.1f %.1f)", - M_opponent_reach_step, - M_fastest_opponent->unum(), - M_fastest_opponent->pos().x, - M_fastest_opponent->pos().y ); + M_opponent_step, + M_first_opponent->unum(), + M_first_opponent->pos().x, + M_first_opponent->pos().y ); } } @@ -328,108 +326,48 @@ InterceptTable::hearOpponent( const int unum, */ void -InterceptTable::createBallCache() +InterceptTable::predictSelf( const WorldModel & wm ) { - const ServerParam & SP = ServerParam::i(); - const double max_x = ( SP.keepawayMode() - ? SP.keepawayLength() * 0.5 - : SP.pitchHalfLength() + 5.0 ); - const double max_y = ( SP.keepawayMode() - ? SP.keepawayWidth() * 0.5 - : SP.pitchHalfWidth() + 5.0 ); - const double bdecay = SP.ballDecay(); - - Vector2D bpos = M_world.ball().pos(); - Vector2D bvel = M_world.ball().vel(); - double bspeed = bvel.r(); - - for ( int i = 0; i < MAX_STEP; ++i ) - { - M_ball_cache.push_back( bpos ); - - if ( bspeed < 0.005 && i >= 10 ) - { - break; - } - - bpos += bvel; - bvel *= bdecay; - bspeed *= bdecay; - - if ( max_x < bpos.absX() - || max_y < bpos.absY() ) - { - break; - } - } - -#ifdef DEBUG_PRINT - dlog.addText( Logger::INTERCEPT, - "(InterceptTable::createBallCache) size=%d last pos=(%.2f %.2f)", - M_ball_cache.size(), - M_ball_cache.back().x, M_ball_cache.back().y ); -#endif -} - -/*-------------------------------------------------------------------*/ -/*! - -*/ -void -InterceptTable::predictSelf() -{ - if ( M_world.self().isKickable() ) + if ( wm.self().isKickable() ) { dlog.addText( Logger::INTERCEPT, "Intercept Self. already kickable. no estimation loop!" ); - M_self_reach_step = 0; - M_self_exhaust_reach_step = 0; + M_self_step = 0; + M_self_exhaust_step = 0; return; } - int max_step = std::min( MAX_STEP, static_cast< int >( M_ball_cache.size() ) ); + constexpr int max_step = 50; - // SelfInterceptV13 predictor( M_world ); - // predictor.predict( max_step, M_self_cache ); - SelfInterceptSimulator sim; - sim.simulate( M_world, max_step, M_self_cache ); + std::shared_ptr< InterceptSimulatorSelf > sim( new InterceptSimulatorSelfV17() ); + sim->simulate( wm, max_step, M_self_results ); - if ( M_self_cache.empty() ) + if ( M_self_results.empty() ) { - std::cerr << M_world.self().unum() << ' ' - << M_world.time() - << " Interecet Self cache is empty!" + std::cerr << wm.self().unum() << ' ' + << wm.time() + << ": (InterceptTable::predictSelf) Unexpected reach. empty result." << std::endl; dlog.addText( Logger::INTERCEPT, - "Intercept Self. Self cache is empty!" ); + __FILE__":(InterceptTable::predictSelf) empty" ); // if self cache is empty, - // reach point should be the inertia final point of the ball + // the inertia final point of the ball will be set as an interception point return; } -// #ifdef SELF_INTERCEPT_USE_NO_SAVE_RECEVERY -// std::sort( M_self_cache.begin(), -// M_self_cache.end(), -// InterceptInfo::Cmp() ); -// M_self_cache.erase( std::unique( M_self_cache.begin(), -// M_self_cache.end(), -// InterceptInfo::Equal() ), -// M_self_cache.end() ); -// #endif - - int min_step = M_self_reach_step; - int exhaust_min_step = M_self_exhaust_reach_step; + int min_step = 1000; + int exhaust_min_step = 1000; - for ( const InterceptInfo & i : M_self_cache ) + for ( const Intercept & i : M_self_results ) { - if ( i.staminaType() == InterceptInfo::NORMAL ) + if ( i.staminaType() == Intercept::NORMAL ) { if ( i.reachStep() < min_step ) { min_step = i.reachStep(); } } - else if ( i.staminaType() == InterceptInfo::EXHAUST ) + else if ( i.staminaType() == Intercept::EXHAUST ) { if ( i.reachStep() < exhaust_min_step ) { @@ -440,12 +378,12 @@ InterceptTable::predictSelf() dlog.addText( Logger::INTERCEPT, "Intercept Self. solution size = %d", - M_self_cache.size() ); + M_self_results.size() ); - M_self_reach_step = min_step; - M_self_exhaust_reach_step = exhaust_min_step; + M_self_step = min_step; + M_self_exhaust_step = exhaust_min_step; - //M_player_map.insert( std::pair< const AbstractPlayerObject *, int >( &(M_world.self()), min_step ) ); + //M_player_map.insert( std::pair< const AbstractPlayerObject *, int >( &(wm.self()), min_step ) ); } /*-------------------------------------------------------------------*/ @@ -453,30 +391,31 @@ InterceptTable::predictSelf() */ void -InterceptTable::predictTeammate() +InterceptTable::predictTeammate( const WorldModel & wm ) { int min_step = 1000; int second_min_step = 1000; - if ( M_world.kickableTeammate() ) + if ( wm.kickableTeammate() ) { - M_teammate_reach_step = 0; + M_teammate_step = 0; min_step = 0; - M_fastest_teammate = M_world.kickableTeammate(); + M_first_teammate = wm.kickableTeammate(); dlog.addText( Logger::INTERCEPT, "Intercept Teammate. exist kickable teammate" ); dlog.addText( Logger::INTERCEPT, "---> set fastest teammate %d (%.1f %.1f)", - M_fastest_teammate->unum(), - M_fastest_teammate->pos().x, M_fastest_teammate->pos().y ); + M_first_teammate->unum(), + M_first_teammate->pos().x, M_first_teammate->pos().y ); } - PlayerIntercept predictor( M_world, M_ball_cache ); + InterceptSimulatorPlayer sim( wm.ball().pos(), + ( wm.kickableOpponent() ? Vector2D( 0.0, 0.0 ) : wm.ball().vel() ) ); - for ( const PlayerObject * t : M_world.teammatesFromBall() ) + for ( const PlayerObject * t : wm.teammatesFromBall() ) { - if ( t == M_world.kickableTeammate() ) + if ( t == wm.kickableTeammate() ) { M_player_map[ t ] = 0; continue; @@ -492,14 +431,13 @@ InterceptTable::predictTeammate() continue; } - int step = predictor.predict( *t, false ); - int goalie_step = 1000; + int step = sim.simulate( wm, *t, false ); if ( t->goalie() ) { - goalie_step = predictor.predict( *t, true ); - if ( step > goalie_step ) + M_our_goalie_step = sim.simulate( wm, *t, true ); + if ( step > M_our_goalie_step ) { - step = goalie_step; + step = M_our_goalie_step; } } @@ -509,11 +447,6 @@ InterceptTable::predictTeammate() t->pos().x, t->pos().y, step ); - if ( t->goalie() ) - { - M_goalie_reach_step = goalie_step; - } - if ( step < second_min_step ) { second_min_step = step; @@ -522,7 +455,7 @@ InterceptTable::predictTeammate() if ( second_min_step < min_step ) { std::swap( min_step, second_min_step ); - std::swap( M_fastest_teammate, M_second_teammate ); + std::swap( M_first_teammate, M_second_teammate ); } } @@ -531,12 +464,12 @@ InterceptTable::predictTeammate() if ( M_second_teammate && second_min_step < 1000 ) { - M_second_teammate_reach_step = second_min_step; + M_second_teammate_step = second_min_step; } - if ( M_fastest_teammate && min_step < 1000 ) + if ( M_first_teammate && min_step < 1000 ) { - M_teammate_reach_step = min_step; + M_teammate_step = min_step; } } @@ -545,30 +478,31 @@ InterceptTable::predictTeammate() */ void -InterceptTable::predictOpponent() +InterceptTable::predictOpponent( const WorldModel & wm ) { int min_step = 1000; int second_min_step = 1000; - if ( M_world.kickableOpponent() ) + if ( wm.kickableOpponent() ) { - M_opponent_reach_step = 0; + M_opponent_step = 0; min_step = 0; - M_fastest_opponent = M_world.kickableOpponent(); + M_first_opponent = wm.kickableOpponent(); dlog.addText( Logger::INTERCEPT, "Intercept Opponent. exist kickable opponent" ); dlog.addText( Logger::INTERCEPT, "---> set fastest opponent %d (%.1f %.1f)", - M_fastest_opponent->unum(), - M_fastest_opponent->pos().x, M_fastest_opponent->pos().y ); + M_first_opponent->unum(), + M_first_opponent->pos().x, M_first_opponent->pos().y ); } - PlayerIntercept predictor( M_world, M_ball_cache ); + InterceptSimulatorPlayer sim( wm.ball().pos(), + ( wm.kickableOpponent() ? Vector2D( 0.0, 0.0 ) : wm.ball().vel() ) ); - for ( const PlayerObject * o : M_world.opponentsFromBall() ) + for ( const PlayerObject * o : wm.opponentsFromBall() ) { - if ( o == M_world.kickableOpponent() ) + if ( o == wm.kickableOpponent() ) { M_player_map[ o ] = 0; continue; @@ -584,10 +518,10 @@ InterceptTable::predictOpponent() continue; } - int step = predictor.predict( *o, false ); + int step = sim.simulate( wm, *o, false ); if ( o->goalie() ) { - int goalie_step = predictor.predict( *o, true ); + int goalie_step = sim.simulate( wm, *o, true ); if ( goalie_step > 0 && step > goalie_step ) { @@ -609,7 +543,7 @@ InterceptTable::predictOpponent() if ( second_min_step < min_step ) { std::swap( min_step, second_min_step ); - std::swap( M_fastest_opponent, M_second_opponent ); + std::swap( M_first_opponent, M_second_opponent ); } } @@ -618,12 +552,12 @@ InterceptTable::predictOpponent() if ( M_second_opponent && second_min_step < 1000 ) { - M_second_opponent_reach_step = second_min_step; + M_second_opponent_step = second_min_step; } - if ( M_fastest_opponent && min_step < 1000 ) + if ( M_first_opponent && min_step < 1000 ) { - M_opponent_reach_step = min_step; + M_opponent_step = min_step; } } diff --git a/rcsc/player/intercept_table.h b/rcsc/player/intercept_table.h index 4fd70ce..bdeb171 100644 --- a/rcsc/player/intercept_table.h +++ b/rcsc/player/intercept_table.h @@ -32,6 +32,7 @@ #ifndef RCSC_PLAYER_INTERCEPT_TABLE_H #define RCSC_PLAYER_INTERCEPT_TABLE_H +#include #include #include #include @@ -45,197 +46,6 @@ class WorldModel; /*-------------------------------------------------------------------*/ -/*! - \class InterceptInfo - \brief interception data -*/ -class InterceptInfo { -public: - - /*! - \enum StaminaType - \brief stamina type - */ - enum StaminaType { - NORMAL = 0, //!< ball gettable without stamina exhaust - EXHAUST = 100, //!< fastest ball gettable, but recovery may be consumed. - }; - - /*! - \enum ActionType - \brief action type - */ - enum ActionType { - OMNI_DASH = 0, - TURN_FORWARD_DASH = 1, - TURN_BACK_DASH = 2, - UNKNOWN_TYPE = 100, - }; - -private: - StaminaType M_stamina_type; //!< stamina type - ActionType M_action_type; //!< action type - - int M_turn_step; //!< estimated turn step - double M_turn_angle; //!< angle difference between current body angle and dash angle - - int M_dash_step; //!< estimated dash step - double M_dash_power; //!< first dash power - double M_dash_dir; //!< first dash direction (relative to body) - - Vector2D M_self_pos; //!< estimated final self position - double M_ball_dist; //!< estimated final ball distance - double M_stamina; //!< estimated final stamina value - - double M_value; //!< evaluation value - -public: - - /*! - \brief create invalid info - */ - InterceptInfo() - : M_stamina_type( EXHAUST ), - M_action_type( UNKNOWN_TYPE ), - M_turn_step( 10000 ), - M_turn_angle( 0.0 ), - M_dash_step( 10000 ), - M_dash_power( 100000.0 ), - M_dash_dir( 0.0 ), - M_self_pos( -10000.0, 0.0 ), - M_ball_dist( 10000000.0 ), - M_stamina( 0.0 ), - M_value( 0.0 ) - { } - - /*! - \brief construct with all variables - */ - InterceptInfo( const StaminaType stamina_type, - const ActionType action_type, - const int turn_step, - const double turn_angle, - const int dash_step, - const double dash_power, - const double dash_dir, - const Vector2D & self_pos, - const double ball_dist, - const double stamina ) - : M_stamina_type( stamina_type ), - M_action_type( action_type ), - M_turn_step( turn_step ), - M_turn_angle( turn_angle ), - M_dash_step( dash_step ), - M_dash_power( dash_power ), - M_dash_dir( dash_dir ), - M_self_pos( self_pos ), - M_ball_dist( ball_dist ), - M_stamina( stamina ), - M_value( 0.0 ) - { } - - /*! - \brief check if this object is legal one or not. - \return checked result. - */ - bool isValid() const - { - return M_action_type != UNKNOWN_TYPE; - } - - /*! - \brief get stamina type id - \return stamina type id - */ - StaminaType staminaType() const - { - return M_stamina_type; - } - - /*! - \brief get interception action type - \return type id - */ - ActionType actionType() const - { - return M_action_type; - } - - /*! - \brief get estimated total turn steps - \return the number of turn steps - */ - int turnCycle() const { return M_turn_step; } - int turnStep() const { return M_turn_step; } - - /*! - \brief get the estimated turn angle - \return turn angle value - */ - double turnAngle() const { return M_turn_angle; } - - /*! - \brief get estimated total dash cycles - \return the number of dash steps - */ - int dashCycle() const { return M_dash_step; } - int dashStep() const { return M_dash_step; } - - /*! - \brief get esitimated total step to reach - \return the number of total steps - */ - int reachCycle() const { return turnStep() + dashStep(); } - int reachStep() const { return turnStep() + dashStep(); } - - /*! - \brief get dash power for the first dash - \return dash power value - */ - double dashPower() const - { - return M_dash_power; - } - - /*! - \brief ger dash direction for the first dash - \return dash direction value (relative to body) - */ - double dashDir() const - { - return M_dash_dir; - } - - /*! - \brief get the estimated final self position - \return final self position - */ - const Vector2D & selfPos() const - { - return M_self_pos; - } - - /*! - \brief get the estimated final ball distance - \return final ball distance - */ - double ballDist() const - { - return M_ball_dist; - } - - /*! - \brief get the estimated self stamina value - \return final self stamina value - */ - double stamina() const - { - return M_stamina; - } -}; - -/*-------------------------------------------------------------------*/ - /*! \class InterceptTable \brief interception info holder for all players @@ -243,47 +53,40 @@ class InterceptInfo { class InterceptTable { private: - //! reference to the WorldModel instance - const WorldModel & M_world; - //! last updated time GameTime M_update_time; - //! ball inertia movement position cache - std::vector< Vector2D > M_ball_cache; - //! predicted min reach step for self without stamina exhaust - int M_self_reach_step; + int M_self_step; //! predicted min reach step for self with stamina exhaust - int M_self_exhaust_reach_step; + int M_self_exhaust_step; //! predicted min reach step for teammate - int M_teammate_reach_step; + int M_teammate_step; //! predicted reach step for second fastest teammate - int M_second_teammate_reach_step; + int M_second_teammate_step; //! predicted min reach step for teammate goalie - int M_goalie_reach_step; + int M_our_goalie_step; //! predicted min reach step for opponent - int M_opponent_reach_step; + int M_opponent_step; //! predicted reach step for second fastest opponent - int M_second_opponent_reach_step; + int M_second_opponent_step; //! const pointer to the fastest ball gettable teammate player object - const PlayerObject * M_fastest_teammate; + const PlayerObject * M_first_teammate; //! const pointer to the second fastest ball gettable teammate player object const PlayerObject * M_second_teammate; //! const pointer to the fastest ball gettable opponent player object - const PlayerObject * M_fastest_opponent; + const PlayerObject * M_first_opponent; //! const pointer to the second fastest ball gettable opponent player object const PlayerObject * M_second_opponent; //! interception info cache for smart interception - std::vector< InterceptInfo > M_self_cache; + std::vector< Intercept > M_self_results; //! all players' intercept step container. key: pointer, value: step value std::map< const AbstractPlayerObject *, int > M_player_map; // not used - InterceptTable() = delete; InterceptTable( const InterceptTable & ) = delete; InterceptTable & operator=( const InterceptTable & ) = delete; @@ -291,8 +94,7 @@ class InterceptTable { /*! \brief init member variables, reserve cache vector memory */ - explicit - InterceptTable( const WorldModel & world ); + InterceptTable(); /*! \brief destructor. nothing to do @@ -302,82 +104,79 @@ class InterceptTable { { } /*! - \brief recreate all interception info + \brief update table information + \param wm const reference to the world model */ - void update(); + void update( const WorldModel & wm ); /*! - \brief set teammate intercept info mainly by heard info + \brief update teammate intercept information by heard information + \param wm const reference to the world model \param unum uniform number \param step interception step */ - void hearTeammate( const int unum, + void hearTeammate( const WorldModel & wm, + const int unum, const int step ); /*! - \brief set opponent intercept info mainly by heard info + \brief update opponent intercept information by heard information + \param wm const reference to the world model \param unum uniform number \param step interception step */ - void hearOpponent( const int unum, + void hearOpponent( const WorldModel & wm, + const int unum, const int step ); /*! \brief get minimal ball gettable step for self without stamina exhaust \return step value to get the ball */ - int selfReachCycle() const { return M_self_reach_step; } - int selfReachStep() const { return M_self_reach_step; } + int selfStep() const { return M_self_step; } /*! \brief get minimal ball gettable step for self with stamina exhaust \return step value to get the ball */ - int selfExhaustReachCycle() const { return M_self_exhaust_reach_step; } - int selfExhaustReachStep() const { return M_self_exhaust_reach_step; } + int selfExhaustStep() const { return M_self_exhaust_step; } /*! \brief get minimal ball gettable step for teammate \return step value to get the ball */ - int teammateReachCycle() const { return M_teammate_reach_step; } - int teammateReachStep() const { return M_teammate_reach_step; } + int teammateStep() const { return M_teammate_step; } /*! \brief get the ball access step for the second teammate \return step value to get the ball */ - int secondTeammateReachCycle() const { return M_second_teammate_reach_step; } - int secondTeammateReachStep() const { return M_second_teammate_reach_step; } + int secondTeammateStep() const { return M_second_teammate_step; } /*! \brief get the ball access step for the teammate goalie \return step value to get the ball */ - int goalieReachCycle() const { return M_goalie_reach_step; } - int goalieReachStep() const { return M_goalie_reach_step; } + int ourGoalieStep() const { return M_our_goalie_step; } /*! \brief get minimal ball gettable step for opponent \return step value to get the ball */ - int opponentReachCycle() const { return M_opponent_reach_step; } - int opponentReachStep() const { return M_opponent_reach_step; } + int opponentStep() const { return M_opponent_step; } /*! \brief get the ball access step for the second opponent \return step value to get the ball */ - int secondOpponentReachCycle() const { return M_second_opponent_reach_step; } - int secondOpponentReachStep() const { return M_second_opponent_reach_step; } + int secondOpponentStep() const { return M_second_opponent_step; } /*! \brief get the teammate object fastest to the ball \return const pointer to the PlayerObject. if not exist such a player, return NULL */ - const PlayerObject * fastestTeammate() const { return M_fastest_teammate; } - const PlayerObject * firstTeammate() const { return M_fastest_teammate; } + const PlayerObject * firstTeammate() const { return M_first_teammate; } /*! \brief get the teammate object second fastest to the ball @@ -391,8 +190,7 @@ class InterceptTable { \return const pointer to the PlayerObject. if not exist such a player, return NULL */ - const PlayerObject * fastestOpponent() const { return M_fastest_opponent; } - const PlayerObject * firstOpponent() const { return M_fastest_opponent; } + const PlayerObject * firstOpponent() const { return M_first_opponent; } /*! \brief get the oppnent object second fastest to the ball @@ -405,10 +203,10 @@ class InterceptTable { \brief get self interception cache container \return const reference to the interception info container */ - const std::vector< InterceptInfo > & selfCache() const - { - return M_self_cache; - } + const std::vector< Intercept > & selfResults() const + { + return M_self_results; + } /*! \brief get all players' intercept step container. @@ -425,25 +223,23 @@ class InterceptTable { */ void clear(); - /*! - \brief create cache of future ball status - */ - void createBallCache(); - /*! \brief predict self interception + \param wm const reference to the world model */ - void predictSelf(); + void predictSelf( const WorldModel & wm ); /*! \predict teammate interception + \param wm const reference to the world model */ - void predictTeammate(); + void predictTeammate( const WorldModel & wm ); /*! \predict opponent interception + \param wm const reference to the world model */ - void predictOpponent(); + void predictOpponent( const WorldModel & wm ); }; } diff --git a/rcsc/player/localization.h b/rcsc/player/localization.h index ed5363e..8662bd5 100644 --- a/rcsc/player/localization.h +++ b/rcsc/player/localization.h @@ -41,7 +41,7 @@ namespace rcsc { class ActionEffector; class BodySensor; -class PlayerType; +class WorldModel; /*! \class Localization @@ -179,20 +179,23 @@ class Localization { /*! \brief estimate self facing direction. + \param wm world model \param see analyzed see information \param self_face pointer to the result variable \param self_face_err pointer to the result variable \return result */ virtual - bool estimateSelfFace( const VisualSensor & see, + bool estimateSelfFace( const WorldModel & wm, + const VisualSensor & see, double * self_face, double * self_face_err ) = 0; /*! \brief localize self position. + \param wm world model \param see analyzed see info - \param act action effector + \param act the last action info \param self_face localized face angle \param self_face_err localized face angle error \param self_pos pointer to the variable to store the localized self position @@ -200,18 +203,18 @@ class Localization { \return if failed, returns false */ virtual - bool localizeSelf( const VisualSensor & see, + bool localizeSelf( const WorldModel & wm, + const VisualSensor & see, const ActionEffector & act, - const PlayerType * ptype, - const double & self_face, - const double & self_face_err, + const double self_face, + const double self_face_err, Vector2D * self_pos, Vector2D * self_pos_err ) = 0; /*! \brief localze ball relative info + \param wm world model \param see analyzed see info - \param act action effector \param self_face localized self face angle \param self_face_err localized self face angle error \param rpos pointer to the variable to store the localized relative position @@ -221,10 +224,10 @@ class Localization { \return if failed, returns false */ virtual - bool localizeBallRelative( const VisualSensor & see, - const ActionEffector & act, - const double & self_face, - const double & self_face_err, + bool localizeBallRelative( const WorldModel & wm, + const VisualSensor & see, + const double self_face, + const double self_face_err, Vector2D * rpos, Vector2D * rpos_err, Vector2D * rvel, @@ -232,6 +235,7 @@ class Localization { /*! \brief localze other player + \param wm world model \param from seen player info \param self_face localized self face angle \param self_face_err localized self face angle error @@ -241,9 +245,10 @@ class Localization { \return if failed, returns false */ virtual - bool localizePlayer( const VisualSensor::PlayerT & from, - const double & self_face, - const double & self_face_err, + bool localizePlayer( const WorldModel & wm, + const VisualSensor::PlayerT & from, + const double self_face, + const double self_face_err, const Vector2D & self_pos, const Vector2D & self_vel, PlayerT * to ) const = 0; diff --git a/rcsc/player/localization_default.cpp b/rcsc/player/localization_default.cpp index bd7bce5..fd5cdf9 100644 --- a/rcsc/player/localization_default.cpp +++ b/rcsc/player/localization_default.cpp @@ -37,7 +37,9 @@ #include "object_table.h" #include "body_sensor.h" +#include "world_model.h" +#include #include #include #include @@ -54,6 +56,8 @@ using std::max; // #define DEBUG_PRINT // #define DEBUG_PRINT_SHAPE +#define USE_OBJECT_TABLE + namespace { static int g_filter_count = 0; } @@ -110,23 +114,27 @@ class LocalizationDefault::Impl { /*! \brief update points using seen markers + \param wm world model \param markers seen marker container \param self_face agent's global face angle \param self_face_err agent's global face angle error */ - void updatePointsByMarkers( const VisualSensor::MarkerCont & markers, + void updatePointsByMarkers( const WorldModel & wm, + const VisualSensor::MarkerCont & markers, const double & self_face, const double & self_face_err ); /*! \brief update points using seen markers + \param wm world model \param markers seen marker container \param behind_markers behind marker container \param self_pos agent's global position \param self_face agent's global face angle \param self_face_err agent's global face angle error */ - void updatePointsByBehindMarker( const VisualSensor::MarkerCont & markers, + void updatePointsByBehindMarker( const WorldModel & wm, + const VisualSensor::MarkerCont & markers, const VisualSensor::MarkerCont & behind_markers, const Vector2D & self_pos, const double & self_face, @@ -135,12 +143,14 @@ class LocalizationDefault::Impl { /*! \brief update points by one marker + \param wm world model \param marker seen marker info \param id estimated marker's Id \param self_face agent's global face angle \param self_face_err agent's global face angle error */ - void updatePointsBy( const VisualSensor::MarkerT & marker, + void updatePointsBy( const WorldModel & wm, + const VisualSensor::MarkerT & marker, const MarkerID id, const double & self_face, const double & self_face_err ); @@ -154,17 +164,20 @@ class LocalizationDefault::Impl { Vector2D * ave_err ); /*! - \brief generate possible points using nearest marker + \brief generate candidate points using nearest marker + \param wm world model \param marker seen marker object \param self_face agent's global face angle \param self_face_err agent's global face angle error */ - void generatePoints( const VisualSensor::MarkerT & marker, + void generatePoints( const WorldModel & wm, + const VisualSensor::MarkerT & marker, const MarkerID id, const double & self_face, const double & self_face_err ); - void resamplePoints( const VisualSensor::MarkerT & marker, + void resamplePoints( const WorldModel & wm, + const VisualSensor::MarkerT & marker, const MarkerID id, const double & self_face, const double & self_face_err ); @@ -198,6 +211,21 @@ class LocalizationDefault::Impl { double * average, double * err ); + /*! + \brief calculate the unquantized distance information using the inverse algorithm + \param client_version client protocol version + \param view_width client's view width + \param quant_dist the quantized distance information sent by the server + \param qstep the quantize step parameter + \param mean_dist the result value of the mean distance + \param dist_error the result error value + */ + void inverseDistanceRange( const double client_version, + const ViewWidth::Type view_width, + const double quant_dist, + const double qstep, + double * mean_dist, + double * dist_error ) const; // get unquantized dist range // void getDistRange(const double &see_dist, const double &qstep, // double *average, double *range); @@ -208,7 +236,8 @@ class LocalizationDefault::Impl { \param markers seen marker container \return self face angle. if failed, retun VisualSensor::DIR_ERR */ - double getFaceDirByMarkers( const VisualSensor::MarkerCont & markers ) const; + double getFaceDirByMarkers( const WorldModel & wm, + const VisualSensor::MarkerCont & markers ) const; /*! \brief estimate self global face angle from seen lines @@ -329,7 +358,8 @@ LocalizationDefault::Impl::getFaceDirByLines( const VisualSensor::LineCont & lin */ void -LocalizationDefault::Impl::updatePointsByMarkers( const VisualSensor::MarkerCont & markers, +LocalizationDefault::Impl::updatePointsByMarkers( const WorldModel & wm, + const VisualSensor::MarkerCont & markers, const double & self_face, const double & self_face_err ) { @@ -349,8 +379,8 @@ LocalizationDefault::Impl::updatePointsByMarkers( const VisualSensor::MarkerCont ++marker, ++count ) { ++g_filter_count; - updatePointsBy( *marker, marker->id_, self_face, self_face_err ); - resamplePoints( markers.front(), markers.front().id_, self_face, self_face_err ); + updatePointsBy( wm, *marker, marker->id_, self_face, self_face_err ); + resamplePoints( wm, markers.front(), markers.front().id_, self_face, self_face_err ); } #ifdef DEBUG_PRINT @@ -364,7 +394,8 @@ LocalizationDefault::Impl::updatePointsByMarkers( const VisualSensor::MarkerCont */ void -LocalizationDefault::Impl::updatePointsByBehindMarker( const VisualSensor::MarkerCont & markers, +LocalizationDefault::Impl::updatePointsByBehindMarker( const WorldModel & wm, + const VisualSensor::MarkerCont & markers, const VisualSensor::MarkerCont & behind_markers, const Vector2D & self_pos, const double & self_face, @@ -405,7 +436,8 @@ LocalizationDefault::Impl::updatePointsByBehindMarker( const VisualSensor::Marke " update by BEHIND marker" ); #endif - updatePointsBy( behind_markers.front(), + updatePointsBy( wm, + behind_markers.front(), marker_id, self_face, self_face_err ); @@ -419,7 +451,7 @@ LocalizationDefault::Impl::updatePointsByBehindMarker( const VisualSensor::Marke __FILE__" (updatePointsByBehindMarker) re-generate points." ); #endif - generatePoints( behind_markers.front(), marker_id, self_face, self_face_err ); + generatePoints( wm, behind_markers.front(), marker_id, self_face, self_face_err ); if ( points().empty() ) { @@ -439,8 +471,8 @@ LocalizationDefault::Impl::updatePointsByBehindMarker( const VisualSensor::Marke ++marker, ++count ) { ++g_filter_count; - updatePointsBy( *marker, marker->id_, self_face, self_face_err ); - resamplePoints( markers.front(), markers.front().id_, self_face, self_face_err ); + updatePointsBy( wm, *marker, marker->id_, self_face, self_face_err ); + resamplePoints( wm, markers.front(), markers.front().id_, self_face, self_face_err ); } } } @@ -450,7 +482,8 @@ LocalizationDefault::Impl::updatePointsByBehindMarker( const VisualSensor::Marke */ void -LocalizationDefault::Impl::updatePointsBy( const VisualSensor::MarkerT & marker, +LocalizationDefault::Impl::updatePointsBy( const WorldModel & wm, + const VisualSensor::MarkerT & marker, const MarkerID id, const double & self_face, const double & self_face_err ) @@ -476,9 +509,10 @@ LocalizationDefault::Impl::updatePointsBy( const VisualSensor::MarkerT & marker, double ave_dist, dist_error; // get distance range info - if ( ! objectTable().getStaticObjInfo( marker.dist_, - &ave_dist, - &dist_error ) ) +#ifdef USE_OBJECT_TABLE + if ( ! objectTable().getLandmarkDistanceRange( wm.clientVersion(), + wm.self().viewWidth().type(), + marker.dist_, &ave_dist, &dist_error ) ) { std::cerr << __FILE__ << " (updatePointsBy) unexpected marker distance " << marker.dist_ << std::endl; @@ -487,6 +521,10 @@ LocalizationDefault::Impl::updatePointsBy( const VisualSensor::MarkerT & marker, marker.dist_ ); return; } +#else + inverseDistanceRange( wm.clientVersion(), wm.self().viewWidth().type(), + marker.dist_, ServerParam::i().landmarkDistQuantizeStep(), &ave_dist, &dist_error ); +#endif // get dir range info double ave_dir, dir_error; @@ -659,7 +697,8 @@ LocalizationDefault::Impl::averagePoints( Vector2D * ave_pos, */ void -LocalizationDefault::Impl::generatePoints( const VisualSensor::MarkerT & marker, +LocalizationDefault::Impl::generatePoints( const WorldModel & wm, + const VisualSensor::MarkerT & marker, const MarkerID id, const double & self_face, const double & self_face_err ) @@ -689,14 +728,18 @@ LocalizationDefault::Impl::generatePoints( const VisualSensor::MarkerT & marker, // get sector range double ave_dist, dist_error; - - if ( ! objectTable().getStaticObjInfo( marker.dist_, - &ave_dist, &dist_error ) ) +#ifdef USE_OBJECT_TABLE + if ( ! objectTable().getLandmarkDistanceRange( wm.clientVersion(), + wm.self().viewWidth().type(), + marker.dist_, &ave_dist, &dist_error ) ) { - std::cerr << __FILE__ << " (generatePoints) marker dist error" - << std::endl; + std::cerr << __FILE__ << " (generatePoints) marker dist error" << std::endl; return; } +#else + inverseDistanceRange( wm.clientVersion(), wm.self().viewWidth().type(), + marker.dist_, ServerParam::i().landmarkDistQuantizeStep(), &ave_dist, &dist_error ); +#endif double ave_dir, dir_error; getDirRange( marker.dir_, @@ -793,7 +836,8 @@ LocalizationDefault::Impl::generatePoints( const VisualSensor::MarkerT & marker, */ void -LocalizationDefault::Impl::resamplePoints( const VisualSensor::MarkerT & marker, +LocalizationDefault::Impl::resamplePoints( const WorldModel & wm, + const VisualSensor::MarkerT & marker, const MarkerID id, const double & self_face, const double & self_face_err ) @@ -814,7 +858,7 @@ LocalizationDefault::Impl::resamplePoints( const VisualSensor::MarkerT & marker, dlog.addText( Logger::WORLD, __FILE__" (resamplePoints) no points. regenerate..." ); #endif - generatePoints( marker, id, self_face, self_face_err ); + generatePoints( wm, marker, id, self_face, self_face_err ); return; } @@ -880,7 +924,8 @@ LocalizationDefault::Impl::getDirRange( const double & seen_dir, */ double -LocalizationDefault::Impl::getFaceDirByMarkers( const VisualSensor::MarkerCont & markers ) const +LocalizationDefault::Impl::getFaceDirByMarkers( const WorldModel & wm, + const VisualSensor::MarkerCont & markers ) const { double angle = VisualSensor::DIR_ERR; @@ -921,10 +966,12 @@ LocalizationDefault::Impl::getFaceDirByMarkers( const VisualSensor::MarkerCont & } double marker_dist1, marker_dist2, tmperr; - - if ( ! objectTable().getStaticObjInfo( markers.front().dist_, - &marker_dist1, - &tmperr ) ) +#ifdef USE_OBJECT_TABLE + if ( ! objectTable().getLandmarkDistanceRange( wm.clientVersion(), + wm.self().viewWidth().type(), + markers.front().dist_, + &marker_dist1, + &tmperr ) ) { #ifdef DEBUG_PRINT dlog.addText( Logger::WORLD, @@ -932,9 +979,11 @@ LocalizationDefault::Impl::getFaceDirByMarkers( const VisualSensor::MarkerCont & #endif return angle; } - if ( ! objectTable().getStaticObjInfo( markers.back().dist_, - &marker_dist2, - &tmperr ) ) + if ( ! objectTable().getLandmarkDistanceRange( wm.clientVersion(), + wm.self().viewWidth().type(), + markers.back().dist_, + &marker_dist2, + &tmperr ) ) { #ifdef DEBUG_PRINT dlog.addText( Logger::WORLD, @@ -942,6 +991,12 @@ LocalizationDefault::Impl::getFaceDirByMarkers( const VisualSensor::MarkerCont & #endif return angle; } +#else + inverseDistanceRange( wm.clientVersion(), wm.self().viewWidth().type(), + markers.front().dist_, ServerParam::i().landmarkDistQuantizeStep(), &marker_dist1, &tmperr ); + inverseDistanceRange( wm.clientVersion(), wm.self().viewWidth().type(), + markers.back().dist_, ServerParam::i().landmarkDistQuantizeStep(), &marker_dist2, &tmperr ); +#endif Vector2D rpos1 = Vector2D::polar2vector( marker_dist1, markers.front().dir_ ); Vector2D rpos2 = Vector2D::polar2vector( marker_dist2, markers.back().dir_ ); @@ -958,6 +1013,72 @@ LocalizationDefault::Impl::getFaceDirByMarkers( const VisualSensor::MarkerCont & return angle; } +/*-------------------------------------------------------------------*/ +void +LocalizationDefault::Impl::inverseDistanceRange( const double /*client_version*/, + const ViewWidth::Type /*view_width*/, + const double quant_dist, + const double qstep_base, + double * mean_dist, + double * dist_error ) const +{ + /* + === server quantize algorithm === + + d1 = log( unq_dist + EPS ) + d2 = rint( d1 / qstep ) * qstep // quantize( d1, qstep ) + d3 = exp( d2 ) + quant_dist = rint( d3 / 0.1 ) * 0.1 // quantize( d3, 0.1 ) + */ + + /* + === unquantize (inverse quantize) algorithm === + + min_d3 = (rint(quant_dist / 0.1) - 0.5) * 0.1 + max_d3 = (rint(quant_dist / 0.1) + 0.5) * 0.1 + + min_d2 = log( min_d3 ) + max_d2 = log( max_d3 ) + + min_d1 = (rint(min_d2 / qstep) - 0.5) * qstep + max_d1 = (rint(min_d2 / qstep) + 0.5) * qstep + + min_d = exp( min_d1 ) - EPS + max_d = exp( max_d1 ) - EPS + + */ + + // const double qstep = ( client_version < 18.0 + // ? qstep_base + // : view_width == ViewWidth::NARROW + // ? qstep_base * 0.5 + // : view_width == ViewWidth::NORMAL + // ? qstep_base * 0.75 + // : qstep_base * 1.0 ); + const double qstep = qstep_base; + + double min_dist, max_dist; + + if ( quant_dist < ObjectTable::SERVER_EPS ) + { + min_dist = 0.0; + } + else + { + min_dist = ( rint( quant_dist / 0.1 ) - 0.5 ) * 0.1; + min_dist = std::min( std::log( min_dist - 0.05 ), std::log( min_dist + 0.05 ) ); + min_dist = ( rint( min_dist / qstep ) - 0.5 ) * qstep; + min_dist = std::exp( min_dist ); + } + + max_dist = ( rint( quant_dist / 0.1 ) + 0.5 ) * 0.1; + max_dist = std::log( max_dist ); + max_dist = ( rint( max_dist / qstep ) + 0.5 ) * qstep; + max_dist = std::exp( max_dist ); + + *mean_dist = ( max_dist + min_dist ) * 0.5; + *dist_error = ( max_dist - min_dist ) * 0.5; +} #if 0 @@ -1098,7 +1219,8 @@ LocalizationDefault::updateBySenseBody( const BodySensor & ) */ bool -LocalizationDefault::estimateSelfFace( const VisualSensor & see, +LocalizationDefault::estimateSelfFace( const WorldModel & wm, + const VisualSensor & see, double * self_face, double * self_face_err ) { @@ -1106,7 +1228,7 @@ LocalizationDefault::estimateSelfFace( const VisualSensor & see, if ( *self_face == VisualSensor::DIR_ERR ) { - *self_face = M_impl->getFaceDirByMarkers( see.markers() ); + *self_face = M_impl->getFaceDirByMarkers( wm, see.markers() ); if ( *self_face == VisualSensor::DIR_ERR ) { #ifdef DEBUG_PRINT @@ -1131,11 +1253,11 @@ LocalizationDefault::estimateSelfFace( const VisualSensor & see, */ bool -LocalizationDefault::localizeSelf( const VisualSensor & see, - const ActionEffector & /* act */, - const PlayerType * /* ptype */, - const double & self_face, - const double & self_face_err, +LocalizationDefault::localizeSelf( const WorldModel & wm, + const VisualSensor & see, + const ActionEffector & /*act*/, + const double self_face, + const double self_face_err, Vector2D * self_pos, Vector2D * self_pos_err ) { @@ -1164,7 +1286,8 @@ LocalizationDefault::localizeSelf( const VisualSensor & see, //////////////////////////////////////////////////////////////////// // generate points using the nearest marker - M_impl->generatePoints( see.markers().front(), + M_impl->generatePoints( wm, + see.markers().front(), see.markers().front().id_, self_face, self_face_err ); @@ -1184,7 +1307,8 @@ LocalizationDefault::localizeSelf( const VisualSensor & see, #endif //////////////////////////////////////////////////////////////////// // update points by known markers - M_impl->updatePointsByMarkers( see.markers(), + M_impl->updatePointsByMarkers( wm, + see.markers(), self_face, self_face_err ); #ifdef DEBUG_PROFILE @@ -1198,7 +1322,8 @@ LocalizationDefault::localizeSelf( const VisualSensor & see, if ( ! see.behindMarkers().empty() ) { // update points by nearest behind marker - M_impl->updatePointsByBehindMarker( see.markers(), + M_impl->updatePointsByBehindMarker( wm, + see.markers(), see.behindMarkers(), *self_pos, self_face, @@ -1225,10 +1350,10 @@ LocalizationDefault::localizeSelf( const VisualSensor & see, */ bool -LocalizationDefault::localizeBallRelative( const VisualSensor & see, - const ActionEffector & /* act */, - const double & self_face, - const double & self_face_err, +LocalizationDefault::localizeBallRelative( const WorldModel & wm, + const VisualSensor & see, + const double self_face, + const double self_face_err, Vector2D * rpos, Vector2D * rpos_err, Vector2D * rvel, @@ -1244,11 +1369,11 @@ LocalizationDefault::localizeBallRelative( const VisualSensor & see, //////////////////////////////////////////////////////////////////// // get polar range info double average_dist, dist_error; - +#ifdef USE_OBJECT_TABLE // dist range - if ( ! M_impl->objectTable().getMovableObjInfo( ball.dist_, - &average_dist, - &dist_error ) ) + if ( ! M_impl->objectTable().getDistanceRange( wm.clientVersion(), + wm.self().viewWidth().type(), + ball.dist_, &average_dist, &dist_error ) ) { std::cerr << __FILE__ << " (localizeBallRelative) unexpected ball distance " << ball.dist_ << std::endl; @@ -1257,6 +1382,10 @@ LocalizationDefault::localizeBallRelative( const VisualSensor & see, ball.dist_ ); return false; } +#else + M_impl->inverseDistanceRange( wm.clientVersion(), wm.self().viewWidth().type(), + ball.dist_, ServerParam::i().distQuantizeStep(), &average_dist, &dist_error ); +#endif // dlog.addText( Logger::WORLD, // __FILE__" (localizeBallRelative) self_face=%.1f err=%.3f", @@ -1434,9 +1563,10 @@ LocalizationDefault::localizeBallRelative( const VisualSensor & see, */ bool -LocalizationDefault::localizePlayer( const VisualSensor::PlayerT & from, - const double & self_face, - const double & self_face_err, +LocalizationDefault::localizePlayer( const WorldModel & wm, + const VisualSensor::PlayerT & from, + const double self_face, + const double self_face_err, const Vector2D & self_pos, const Vector2D & self_vel, PlayerT * to ) const @@ -1444,10 +1574,10 @@ LocalizationDefault::localizePlayer( const VisualSensor::PlayerT & from, //////////////////////////////////////////////////////////////////// // get polar range info double average_dist, dist_error; - - if ( ! M_impl->objectTable().getMovableObjInfo( from.dist_, - &average_dist, - &dist_error ) ) +#ifdef USE_OBJECT_TABLE + if ( ! M_impl->objectTable().getDistanceRange( wm.clientVersion(), + wm.self().viewWidth(), + from.dist_, &average_dist, &dist_error ) ) { std::cerr << __FILE__ << " (localizePlayer) Unexpected player distance " << from.dist_ << std::endl; @@ -1456,6 +1586,10 @@ LocalizationDefault::localizePlayer( const VisualSensor::PlayerT & from, from.dist_ ); return false; } +#else + M_impl->inverseDistanceRange( wm.clientVersion(), wm.self().viewWidth().type(), + from.dist_, ServerParam::i().distQuantizeStep(), &average_dist, &dist_error ); +#endif double average_dir, dir_error; diff --git a/rcsc/player/localization_default.h b/rcsc/player/localization_default.h index 3f4a7ab..821a626 100644 --- a/rcsc/player/localization_default.h +++ b/rcsc/player/localization_default.h @@ -80,21 +80,23 @@ class LocalizationDefault /*! \brief estimate self facing direction. + \param wm world model \param see analyzed see information \param self_face pointer to the result variable \param self_face_err pointer to the result variable \return result */ virtual - bool estimateSelfFace( const VisualSensor & see, + bool estimateSelfFace( const WorldModel & wm, + const VisualSensor & see, double * self_face, double * self_face_err ) override; /*! \brief localize self position. + \param wm world model \param see analyzed see info - \param act action effector - \param ptype player type of self + \param act the last action info \param self_face localized face angle \param self_face_err localized face angle error \param self_pos pointer to the variable to store the localized self position @@ -102,18 +104,18 @@ class LocalizationDefault \return if failed, returns false */ virtual - bool localizeSelf( const VisualSensor & see, + bool localizeSelf( const WorldModel & wm, + const VisualSensor & see, const ActionEffector & act, - const PlayerType * ptype, - const double & self_face, - const double & self_face_err, + const double self_face, + const double self_face_err, Vector2D * self_pos, Vector2D * self_pos_err ) override; /*! \brief localze ball relative info + \param wm world model \param see analyzed see info - \param act action effector \param self_face localized self face angle \param self_face_err localized self face angle error \param rpos pointer to the variable to store the localized relative position @@ -123,10 +125,10 @@ class LocalizationDefault \return if failed, returns false */ virtual - bool localizeBallRelative( const VisualSensor & see, - const ActionEffector & act, - const double & self_face, - const double & self_face_err, + bool localizeBallRelative( const WorldModel & wm, + const VisualSensor & see, + const double self_face, + const double self_face_err, Vector2D * rpos, Vector2D * rpos_err, Vector2D * rvel, @@ -134,6 +136,7 @@ class LocalizationDefault /*! \brief localze other player + \param wm world model \param from seen player info \param self_face localized self face angle \param self_face_err localized self face angle error @@ -143,9 +146,10 @@ class LocalizationDefault \return if failed, returns false */ virtual - bool localizePlayer( const VisualSensor::PlayerT & from, - const double & self_face, - const double & self_face_err, + bool localizePlayer( const WorldModel & wm, + const VisualSensor::PlayerT & from, + const double self_face, + const double self_face_err, const Vector2D & self_pos, const Vector2D & self_vel, PlayerT * to ) const override; diff --git a/rcsc/player/object_table.cpp b/rcsc/player/object_table.cpp index 17051c9..ca63ada 100644 --- a/rcsc/player/object_table.cpp +++ b/rcsc/player/object_table.cpp @@ -154,7 +154,14 @@ void ObjectTable::createTable() { M_static_table.clear(); + M_static_table_v18_narrow.clear(); + M_static_table_v18_normal.clear(); + M_static_table_v18_wide.clear(); + M_movable_table.clear(); + M_movable_table_v18_narrow.clear(); + M_movable_table_v18_normal.clear(); + M_movable_table_v18_wide.clear(); M_static_table.emplace_back( 0.00, 0.025019, 0.025019 ); M_static_table.emplace_back( 0.10, 0.100178, 0.050142 ); @@ -547,6 +554,1452 @@ ObjectTable::createTable() M_static_table.emplace_back( 177.70, 177.685032, 0.888418 ); M_static_table.emplace_back( 179.50, 179.470796, 0.897347 ); + // -------------------------------------------------------------------- + M_static_table_v18_narrow.emplace_back( 0.00, 0.024956, 0.024956 ); + M_static_table_v18_narrow.emplace_back( 0.10, 0.099928, 0.050016 ); + M_static_table_v18_narrow.emplace_back( 0.20, 0.199822, 0.049878 ); + M_static_table_v18_narrow.emplace_back( 0.30, 0.300256, 0.050557 ); + M_static_table_v18_narrow.emplace_back( 0.40, 0.400634, 0.049820 ); + M_static_table_v18_narrow.emplace_back( 0.50, 0.500320, 0.049866 ); + M_static_table_v18_narrow.emplace_back( 0.60, 0.599535, 0.049350 ); + M_static_table_v18_narrow.emplace_back( 0.70, 0.699511, 0.050626 ); + M_static_table_v18_narrow.emplace_back( 0.80, 0.800077, 0.049940 ); + M_static_table_v18_narrow.emplace_back( 0.90, 0.899436, 0.049419 ); + M_static_table_v18_narrow.emplace_back( 1.00, 0.998751, 0.049896 ); + M_static_table_v18_narrow.emplace_back( 1.10, 1.098024, 0.049377 ); + M_static_table_v18_narrow.emplace_back( 1.20, 1.198299, 0.050897 ); + M_static_table_v18_narrow.emplace_back( 1.30, 1.301217, 0.052021 ); + M_static_table_v18_narrow.emplace_back( 1.40, 1.402298, 0.049060 ); + M_static_table_v18_narrow.emplace_back( 1.50, 1.500095, 0.048736 ); + M_static_table_v18_narrow.emplace_back( 1.60, 1.600840, 0.052009 ); + M_static_table_v18_narrow.emplace_back( 1.70, 1.699575, 0.046726 ); + M_static_table_v18_narrow.emplace_back( 1.80, 1.800294, 0.053992 ); + M_static_table_v18_narrow.emplace_back( 1.90, 1.901822, 0.047535 ); + M_static_table_v18_narrow.emplace_back( 2.00, 1.999331, 0.049973 ); + M_static_table_v18_narrow.emplace_back( 2.10, 2.101839, 0.052535 ); + M_static_table_v18_narrow.emplace_back( 2.20, 2.203954, 0.049581 ); + M_static_table_v18_narrow.emplace_back( 2.30, 2.299519, 0.045985 ); + M_static_table_v18_narrow.emplace_back( 2.40, 2.399483, 0.053979 ); + M_static_table_v18_narrow.emplace_back( 2.50, 2.503526, 0.050064 ); + M_static_table_v18_narrow.emplace_back( 2.60, 2.599069, 0.045479 ); + M_static_table_v18_narrow.emplace_back( 2.70, 2.698511, 0.053963 ); + M_static_table_v18_narrow.emplace_back( 2.80, 2.801495, 0.049021 ); + M_static_table_v18_narrow.emplace_back( 2.90, 2.901284, 0.050768 ); + M_static_table_v18_narrow.emplace_back( 3.00, 3.004627, 0.052576 ); + M_static_table_v18_narrow.emplace_back( 3.10, 3.103755, 0.046553 ); + M_static_table_v18_narrow.emplace_back( 3.20, 3.198279, 0.047971 ); + M_static_table_v18_narrow.emplace_back( 3.30, 3.295681, 0.049432 ); + M_static_table_v18_narrow.emplace_back( 3.40, 3.396049, 0.050937 ); + M_static_table_v18_narrow.emplace_back( 3.50, 3.499474, 0.052488 ); + M_static_table_v18_narrow.emplace_back( 3.60, 3.596921, 0.044959 ); + M_static_table_v18_narrow.emplace_back( 3.70, 3.697336, 0.055456 ); + M_static_table_v18_narrow.emplace_back( 3.80, 3.800294, 0.047502 ); + M_static_table_v18_narrow.emplace_back( 3.90, 3.896499, 0.048704 ); + M_static_table_v18_narrow.emplace_back( 4.00, 3.995139, 0.049937 ); + M_static_table_v18_narrow.emplace_back( 4.10, 4.096276, 0.051201 ); + M_static_table_v18_narrow.emplace_back( 4.20, 4.199974, 0.052497 ); + M_static_table_v18_narrow.emplace_back( 4.30, 4.306297, 0.053826 ); + M_static_table_v18_narrow.emplace_back( 4.40, 4.404163, 0.044041 ); + M_static_table_v18_narrow.emplace_back( 4.50, 4.504506, 0.056303 ); + M_static_table_v18_narrow.emplace_back( 4.60, 4.606877, 0.046068 ); + M_static_table_v18_narrow.emplace_back( 4.70, 4.699942, 0.046998 ); + M_static_table_v18_narrow.emplace_back( 4.80, 4.794887, 0.047947 ); + M_static_table_v18_narrow.emplace_back( 4.90, 4.891750, 0.048916 ); + M_static_table_v18_narrow.emplace_back( 5.00, 4.990570, 0.049904 ); + M_static_table_v18_narrow.emplace_back( 5.10, 5.091386, 0.050912 ); + M_static_table_v18_narrow.emplace_back( 5.20, 5.194239, 0.051941 ); + M_static_table_v18_narrow.emplace_back( 5.30, 5.299169, 0.052990 ); + M_static_table_v18_narrow.emplace_back( 5.40, 5.406220, 0.054061 ); + M_static_table_v18_narrow.emplace_back( 5.50, 5.501541, 0.041261 ); + M_static_table_v18_narrow.emplace_back( 5.60, 5.598788, 0.055986 ); + M_static_table_v18_narrow.emplace_back( 5.70, 5.697505, 0.042731 ); + M_static_table_v18_narrow.emplace_back( 5.80, 5.798215, 0.057980 ); + M_static_table_v18_narrow.emplace_back( 5.90, 5.900448, 0.044253 ); + M_static_table_v18_narrow.emplace_back( 6.00, 6.004746, 0.060046 ); + M_static_table_v18_narrow.emplace_back( 6.10, 6.110620, 0.045829 ); + M_static_table_v18_narrow.emplace_back( 6.20, 6.202970, 0.046521 ); + M_static_table_v18_narrow.emplace_back( 6.30, 6.296716, 0.047225 ); + M_static_table_v18_narrow.emplace_back( 6.40, 6.391879, 0.047939 ); + M_static_table_v18_narrow.emplace_back( 6.50, 6.488480, 0.048663 ); + M_static_table_v18_narrow.emplace_back( 6.60, 6.586540, 0.049398 ); + M_static_table_v18_narrow.emplace_back( 6.70, 6.686083, 0.050145 ); + M_static_table_v18_narrow.emplace_back( 6.80, 6.787131, 0.050903 ); + M_static_table_v18_narrow.emplace_back( 6.90, 6.889705, 0.051672 ); + M_static_table_v18_narrow.emplace_back( 7.00, 6.993829, 0.052453 ); + M_static_table_v18_narrow.emplace_back( 7.10, 7.099528, 0.053246 ); + M_static_table_v18_narrow.emplace_back( 7.20, 7.206823, 0.054050 ); + M_static_table_v18_narrow.emplace_back( 7.30, 7.297360, 0.036487 ); + M_static_table_v18_narrow.emplace_back( 7.40, 7.389265, 0.055419 ); + M_static_table_v18_narrow.emplace_back( 7.50, 7.500939, 0.056256 ); + M_static_table_v18_narrow.emplace_back( 7.60, 7.595171, 0.037976 ); + M_static_table_v18_narrow.emplace_back( 7.70, 7.690826, 0.057680 ); + M_static_table_v18_narrow.emplace_back( 7.80, 7.807058, 0.058552 ); + M_static_table_v18_narrow.emplace_back( 7.90, 7.905135, 0.039525 ); + M_static_table_v18_narrow.emplace_back( 8.00, 8.004695, 0.060034 ); + M_static_table_v18_narrow.emplace_back( 8.10, 8.105255, 0.040525 ); + M_static_table_v18_narrow.emplace_back( 8.20, 8.207334, 0.061554 ); + M_static_table_v18_narrow.emplace_back( 8.30, 8.310440, 0.041552 ); + M_static_table_v18_narrow.emplace_back( 8.40, 8.393962, 0.041969 ); + M_static_table_v18_narrow.emplace_back( 8.50, 8.499678, 0.063746 ); + M_static_table_v18_narrow.emplace_back( 8.60, 8.606456, 0.043031 ); + M_static_table_v18_narrow.emplace_back( 8.70, 8.692952, 0.043464 ); + M_static_table_v18_narrow.emplace_back( 8.80, 8.802433, 0.066017 ); + M_static_table_v18_narrow.emplace_back( 8.90, 8.913015, 0.044565 ); + M_static_table_v18_narrow.emplace_back( 9.00, 9.002593, 0.045012 ); + M_static_table_v18_narrow.emplace_back( 9.10, 9.093070, 0.045465 ); + M_static_table_v18_narrow.emplace_back( 9.20, 9.184456, 0.045921 ); + M_static_table_v18_narrow.emplace_back( 9.30, 9.300128, 0.069750 ); + M_static_table_v18_narrow.emplace_back( 9.40, 9.416962, 0.047084 ); + M_static_table_v18_narrow.emplace_back( 9.50, 9.511604, 0.047557 ); + M_static_table_v18_narrow.emplace_back( 9.60, 9.607197, 0.048035 ); + M_static_table_v18_narrow.emplace_back( 9.70, 9.703751, 0.048518 ); + M_static_table_v18_narrow.emplace_back( 9.80, 9.801276, 0.049006 ); + M_static_table_v18_narrow.emplace_back( 9.90, 9.899780, 0.049498 ); + M_static_table_v18_narrow.emplace_back( 10.00, 9.999275, 0.049996 ); + M_static_table_v18_narrow.emplace_back( 10.10, 10.099769, 0.050498 ); + M_static_table_v18_narrow.emplace_back( 10.20, 10.201273, 0.051006 ); + M_static_table_v18_narrow.emplace_back( 10.30, 10.303797, 0.051518 ); + M_static_table_v18_narrow.emplace_back( 10.40, 10.407352, 0.052036 ); + M_static_table_v18_narrow.emplace_back( 10.50, 10.511948, 0.052559 ); + M_static_table_v18_narrow.emplace_back( 10.60, 10.617595, 0.053087 ); + M_static_table_v18_narrow.emplace_back( 10.70, 10.697426, 0.026743 ); + M_static_table_v18_narrow.emplace_back( 10.80, 10.778059, 0.053889 ); + M_static_table_v18_narrow.emplace_back( 10.90, 10.886380, 0.054431 ); + M_static_table_v18_narrow.emplace_back( 11.00, 10.995790, 0.054978 ); + M_static_table_v18_narrow.emplace_back( 11.10, 11.106300, 0.055531 ); + M_static_table_v18_narrow.emplace_back( 11.20, 11.217920, 0.056089 ); + M_static_table_v18_narrow.emplace_back( 11.30, 11.302265, 0.028255 ); + M_static_table_v18_narrow.emplace_back( 11.40, 11.387457, 0.056936 ); + M_static_table_v18_narrow.emplace_back( 11.50, 11.501903, 0.057509 ); + M_static_table_v18_narrow.emplace_back( 11.60, 11.617500, 0.058087 ); + M_static_table_v18_narrow.emplace_back( 11.70, 11.704849, 0.029262 ); + M_static_table_v18_narrow.emplace_back( 11.80, 11.793075, 0.058964 ); + M_static_table_v18_narrow.emplace_back( 11.90, 11.911597, 0.059557 ); + M_static_table_v18_narrow.emplace_back( 12.00, 12.001158, 0.030003 ); + M_static_table_v18_narrow.emplace_back( 12.10, 12.091618, 0.060457 ); + M_static_table_v18_narrow.emplace_back( 12.20, 12.213141, 0.061065 ); + M_static_table_v18_narrow.emplace_back( 12.30, 12.304969, 0.030762 ); + M_static_table_v18_narrow.emplace_back( 12.40, 12.397719, 0.061988 ); + M_static_table_v18_narrow.emplace_back( 12.50, 12.490935, 0.031227 ); + M_static_table_v18_narrow.emplace_back( 12.60, 12.585087, 0.062925 ); + M_static_table_v18_narrow.emplace_back( 12.70, 12.711569, 0.063557 ); + M_static_table_v18_narrow.emplace_back( 12.80, 12.807144, 0.032017 ); + M_static_table_v18_narrow.emplace_back( 12.90, 12.903680, 0.064518 ); + M_static_table_v18_narrow.emplace_back( 13.00, 13.000699, 0.032501 ); + M_static_table_v18_narrow.emplace_back( 13.10, 13.098694, 0.065493 ); + M_static_table_v18_narrow.emplace_back( 13.20, 13.197180, 0.032993 ); + M_static_table_v18_narrow.emplace_back( 13.30, 13.296655, 0.066482 ); + M_static_table_v18_narrow.emplace_back( 13.40, 13.396629, 0.033491 ); + M_static_table_v18_narrow.emplace_back( 13.50, 13.497608, 0.067487 ); + M_static_table_v18_narrow.emplace_back( 13.60, 13.599094, 0.033998 ); + M_static_table_v18_narrow.emplace_back( 13.70, 13.701599, 0.068507 ); + M_static_table_v18_narrow.emplace_back( 13.80, 13.804617, 0.034511 ); + M_static_table_v18_narrow.emplace_back( 13.90, 13.908672, 0.069543 ); + M_static_table_v18_narrow.emplace_back( 14.00, 14.013248, 0.035033 ); + M_static_table_v18_narrow.emplace_back( 14.10, 14.083489, 0.035208 ); + M_static_table_v18_narrow.emplace_back( 14.20, 14.189646, 0.070948 ); + M_static_table_v18_narrow.emplace_back( 14.30, 14.296334, 0.035740 ); + M_static_table_v18_narrow.emplace_back( 14.40, 14.404095, 0.072020 ); + M_static_table_v18_narrow.emplace_back( 14.50, 14.512396, 0.036281 ); + M_static_table_v18_narrow.emplace_back( 14.60, 14.585139, 0.036462 ); + M_static_table_v18_narrow.emplace_back( 14.70, 14.695077, 0.073475 ); + M_static_table_v18_narrow.emplace_back( 14.80, 14.805565, 0.037013 ); + M_static_table_v18_narrow.emplace_back( 14.90, 14.879778, 0.037199 ); + M_static_table_v18_narrow.emplace_back( 15.00, 14.991937, 0.074959 ); + M_static_table_v18_narrow.emplace_back( 15.10, 15.104657, 0.037761 ); + M_static_table_v18_narrow.emplace_back( 15.20, 15.180370, 0.037951 ); + M_static_table_v18_narrow.emplace_back( 15.30, 15.294794, 0.076473 ); + M_static_table_v18_narrow.emplace_back( 15.40, 15.409792, 0.038524 ); + M_static_table_v18_narrow.emplace_back( 15.50, 15.487034, 0.038718 ); + M_static_table_v18_narrow.emplace_back( 15.60, 15.603770, 0.078018 ); + M_static_table_v18_narrow.emplace_back( 15.70, 15.721090, 0.039302 ); + M_static_table_v18_narrow.emplace_back( 15.80, 15.799892, 0.039499 ); + M_static_table_v18_narrow.emplace_back( 15.90, 15.879090, 0.039698 ); + M_static_table_v18_narrow.emplace_back( 16.00, 15.998781, 0.079993 ); + M_static_table_v18_narrow.emplace_back( 16.10, 16.119071, 0.040298 ); + M_static_table_v18_narrow.emplace_back( 16.20, 16.199869, 0.040500 ); + M_static_table_v18_narrow.emplace_back( 16.30, 16.281071, 0.040703 ); + M_static_table_v18_narrow.emplace_back( 16.40, 16.403792, 0.082018 ); + M_static_table_v18_narrow.emplace_back( 16.50, 16.527128, 0.041318 ); + M_static_table_v18_narrow.emplace_back( 16.60, 16.609970, 0.041525 ); + M_static_table_v18_narrow.emplace_back( 16.70, 16.693228, 0.041733 ); + M_static_table_v18_narrow.emplace_back( 16.80, 16.776903, 0.041943 ); + M_static_table_v18_narrow.emplace_back( 16.90, 16.903362, 0.084516 ); + M_static_table_v18_narrow.emplace_back( 17.00, 17.030454, 0.042576 ); + M_static_table_v18_narrow.emplace_back( 17.10, 17.115819, 0.042790 ); + M_static_table_v18_narrow.emplace_back( 17.20, 17.201613, 0.043004 ); + M_static_table_v18_narrow.emplace_back( 17.30, 17.287836, 0.043220 ); + M_static_table_v18_narrow.emplace_back( 17.40, 17.374492, 0.043436 ); + M_static_table_v18_narrow.emplace_back( 17.50, 17.505454, 0.087527 ); + M_static_table_v18_narrow.emplace_back( 17.60, 17.637073, 0.044093 ); + M_static_table_v18_narrow.emplace_back( 17.70, 17.725480, 0.044314 ); + M_static_table_v18_narrow.emplace_back( 17.80, 17.814329, 0.044536 ); + M_static_table_v18_narrow.emplace_back( 17.90, 17.903624, 0.044759 ); + M_static_table_v18_narrow.emplace_back( 18.00, 17.993366, 0.044984 ); + M_static_table_v18_narrow.emplace_back( 18.10, 18.083558, 0.045209 ); + M_static_table_v18_narrow.emplace_back( 18.20, 18.174202, 0.045436 ); + M_static_table_v18_narrow.emplace_back( 18.30, 18.265301, 0.045663 ); + M_static_table_v18_narrow.emplace_back( 18.40, 18.402978, 0.092015 ); + M_static_table_v18_narrow.emplace_back( 18.50, 18.541346, 0.046353 ); + M_static_table_v18_narrow.emplace_back( 18.60, 18.634284, 0.046586 ); + M_static_table_v18_narrow.emplace_back( 18.70, 18.727689, 0.046820 ); + M_static_table_v18_narrow.emplace_back( 18.80, 18.821562, 0.047054 ); + M_static_table_v18_narrow.emplace_back( 18.90, 18.915906, 0.047290 ); + M_static_table_v18_narrow.emplace_back( 19.00, 19.010722, 0.047527 ); + M_static_table_v18_narrow.emplace_back( 19.10, 19.106014, 0.047765 ); + M_static_table_v18_narrow.emplace_back( 19.20, 19.201783, 0.048005 ); + M_static_table_v18_narrow.emplace_back( 19.30, 19.298033, 0.048245 ); + M_static_table_v18_narrow.emplace_back( 19.40, 19.394764, 0.048487 ); + M_static_table_v18_narrow.emplace_back( 19.50, 19.491981, 0.048730 ); + M_static_table_v18_narrow.emplace_back( 19.60, 19.589685, 0.048974 ); + M_static_table_v18_narrow.emplace_back( 19.70, 19.687878, 0.049220 ); + M_static_table_v18_narrow.emplace_back( 19.80, 19.786564, 0.049467 ); + M_static_table_v18_narrow.emplace_back( 19.90, 19.885745, 0.049714 ); + M_static_table_v18_narrow.emplace_back( 20.00, 19.985422, 0.049964 ); + M_static_table_v18_narrow.emplace_back( 20.10, 20.085600, 0.050214 ); + M_static_table_v18_narrow.emplace_back( 20.20, 20.186279, 0.050466 ); + M_static_table_v18_narrow.emplace_back( 20.30, 20.287463, 0.050719 ); + M_static_table_v18_narrow.emplace_back( 20.40, 20.389155, 0.050973 ); + M_static_table_v18_narrow.emplace_back( 20.50, 20.491356, 0.051229 ); + M_static_table_v18_narrow.emplace_back( 20.60, 20.594070, 0.051485 ); + M_static_table_v18_narrow.emplace_back( 20.70, 20.697298, 0.051743 ); + M_static_table_v18_narrow.emplace_back( 20.80, 20.801043, 0.052003 ); + M_static_table_v18_narrow.emplace_back( 20.90, 20.905309, 0.052263 ); + M_static_table_v18_narrow.emplace_back( 21.00, 21.010097, 0.052525 ); + M_static_table_v18_narrow.emplace_back( 21.10, 21.115411, 0.052789 ); + M_static_table_v18_narrow.emplace_back( 21.20, 21.221252, 0.053053 ); + M_static_table_v18_narrow.emplace_back( 21.30, 21.327624, 0.053319 ); + M_static_table_v18_narrow.emplace_back( 21.40, 21.434530, 0.053587 ); + M_static_table_v18_narrow.emplace_back( 21.50, 21.541971, 0.053855 ); + M_static_table_v18_narrow.emplace_back( 21.60, 21.649950, 0.054125 ); + M_static_table_v18_narrow.emplace_back( 21.80, 21.758471, 0.054396 ); + M_static_table_v18_narrow.emplace_back( 21.90, 21.867536, 0.054669 ); + M_static_table_v18_narrow.emplace_back( 22.00, 21.977147, 0.054943 ); + M_static_table_v18_narrow.emplace_back( 22.10, 22.087308, 0.055218 ); + M_static_table_v18_narrow.emplace_back( 22.20, 22.198021, 0.055495 ); + M_static_table_v18_narrow.emplace_back( 22.30, 22.309289, 0.055773 ); + M_static_table_v18_narrow.emplace_back( 22.40, 22.421115, 0.056053 ); + M_static_table_v18_narrow.emplace_back( 22.50, 22.533502, 0.056334 ); + M_static_table_v18_narrow.emplace_back( 22.60, 22.646451, 0.056616 ); + M_static_table_v18_narrow.emplace_back( 22.80, 22.759967, 0.056900 ); + M_static_table_v18_narrow.emplace_back( 22.90, 22.874052, 0.057185 ); + M_static_table_v18_narrow.emplace_back( 23.00, 22.988709, 0.057472 ); + M_static_table_v18_narrow.emplace_back( 23.10, 23.103940, 0.057760 ); + M_static_table_v18_narrow.emplace_back( 23.20, 23.219749, 0.058050 ); + M_static_table_v18_narrow.emplace_back( 23.30, 23.336138, 0.058340 ); + M_static_table_v18_narrow.emplace_back( 23.50, 23.453111, 0.058633 ); + M_static_table_v18_narrow.emplace_back( 23.60, 23.570671, 0.058927 ); + M_static_table_v18_narrow.emplace_back( 23.70, 23.688819, 0.059222 ); + M_static_table_v18_narrow.emplace_back( 23.80, 23.807559, 0.059519 ); + M_static_table_v18_narrow.emplace_back( 23.90, 23.926895, 0.059817 ); + M_static_table_v18_narrow.emplace_back( 24.00, 24.046829, 0.060117 ); + M_static_table_v18_narrow.emplace_back( 24.20, 24.167365, 0.060419 ); + M_static_table_v18_narrow.emplace_back( 24.30, 24.288504, 0.060721 ); + M_static_table_v18_narrow.emplace_back( 24.40, 24.410251, 0.061026 ); + M_static_table_v18_narrow.emplace_back( 24.50, 24.532608, 0.061332 ); + M_static_table_v18_narrow.emplace_back( 24.70, 24.655578, 0.061639 ); + M_static_table_v18_narrow.emplace_back( 24.80, 24.779164, 0.061948 ); + M_static_table_v18_narrow.emplace_back( 24.90, 24.903371, 0.062259 ); + M_static_table_v18_narrow.emplace_back( 25.00, 25.028199, 0.062570 ); + M_static_table_v18_narrow.emplace_back( 25.20, 25.153653, 0.062884 ); + M_static_table_v18_narrow.emplace_back( 25.30, 25.279737, 0.063200 ); + M_static_table_v18_narrow.emplace_back( 25.40, 25.406452, 0.063516 ); + M_static_table_v18_narrow.emplace_back( 25.50, 25.533802, 0.063834 ); + M_static_table_v18_narrow.emplace_back( 25.70, 25.661791, 0.064155 ); + M_static_table_v18_narrow.emplace_back( 25.80, 25.790421, 0.064476 ); + M_static_table_v18_narrow.emplace_back( 25.90, 25.919696, 0.064799 ); + M_static_table_v18_narrow.emplace_back( 26.00, 26.049619, 0.065124 ); + M_static_table_v18_narrow.emplace_back( 26.20, 26.180194, 0.065451 ); + M_static_table_v18_narrow.emplace_back( 26.30, 26.311422, 0.065778 ); + M_static_table_v18_narrow.emplace_back( 26.40, 26.443309, 0.066109 ); + M_static_table_v18_narrow.emplace_back( 26.60, 26.575857, 0.066440 ); + M_static_table_v18_narrow.emplace_back( 26.70, 26.709069, 0.066773 ); + M_static_table_v18_narrow.emplace_back( 26.80, 26.842948, 0.067107 ); + M_static_table_v18_narrow.emplace_back( 27.00, 26.977499, 0.067444 ); + M_static_table_v18_narrow.emplace_back( 27.10, 27.112724, 0.067782 ); + M_static_table_v18_narrow.emplace_back( 27.20, 27.248628, 0.068122 ); + M_static_table_v18_narrow.emplace_back( 27.40, 27.385212, 0.068463 ); + M_static_table_v18_narrow.emplace_back( 27.50, 27.522481, 0.068807 ); + M_static_table_v18_narrow.emplace_back( 27.70, 27.660438, 0.069151 ); + M_static_table_v18_narrow.emplace_back( 27.80, 27.799086, 0.069498 ); + M_static_table_v18_narrow.emplace_back( 27.90, 27.938430, 0.069846 ); + M_static_table_v18_narrow.emplace_back( 28.10, 28.078471, 0.070196 ); + M_static_table_v18_narrow.emplace_back( 28.20, 28.219215, 0.070548 ); + M_static_table_v18_narrow.emplace_back( 28.40, 28.360665, 0.070902 ); + M_static_table_v18_narrow.emplace_back( 28.50, 28.502823, 0.071257 ); + M_static_table_v18_narrow.emplace_back( 28.60, 28.645694, 0.071614 ); + M_static_table_v18_narrow.emplace_back( 28.80, 28.789281, 0.071973 ); + M_static_table_v18_narrow.emplace_back( 28.90, 28.933588, 0.072334 ); + M_static_table_v18_narrow.emplace_back( 29.10, 29.078619, 0.072697 ); + M_static_table_v18_narrow.emplace_back( 29.20, 29.224376, 0.073061 ); + M_static_table_v18_narrow.emplace_back( 29.40, 29.370863, 0.073427 ); + M_static_table_v18_narrow.emplace_back( 29.50, 29.518086, 0.073796 ); + M_static_table_v18_narrow.emplace_back( 29.70, 29.666046, 0.074165 ); + M_static_table_v18_narrow.emplace_back( 29.80, 29.814747, 0.074537 ); + M_static_table_v18_narrow.emplace_back( 30.00, 29.964195, 0.074911 ); + M_static_table_v18_narrow.emplace_back( 30.10, 30.114391, 0.075286 ); + M_static_table_v18_narrow.emplace_back( 30.30, 30.265340, 0.075664 ); + M_static_table_v18_narrow.emplace_back( 30.40, 30.417045, 0.076042 ); + M_static_table_v18_narrow.emplace_back( 30.60, 30.569511, 0.076424 ); + M_static_table_v18_narrow.emplace_back( 30.70, 30.722742, 0.076807 ); + M_static_table_v18_narrow.emplace_back( 30.90, 30.876740, 0.077192 ); + M_static_table_v18_narrow.emplace_back( 31.00, 31.031510, 0.077579 ); + M_static_table_v18_narrow.emplace_back( 31.20, 31.187057, 0.077968 ); + M_static_table_v18_narrow.emplace_back( 31.30, 31.343382, 0.078358 ); + M_static_table_v18_narrow.emplace_back( 31.50, 31.500491, 0.078751 ); + M_static_table_v18_narrow.emplace_back( 31.70, 31.658388, 0.079146 ); + M_static_table_v18_narrow.emplace_back( 31.80, 31.817077, 0.079543 ); + M_static_table_v18_narrow.emplace_back( 32.00, 31.976560, 0.079941 ); + M_static_table_v18_narrow.emplace_back( 32.10, 32.136843, 0.080342 ); + M_static_table_v18_narrow.emplace_back( 32.30, 32.297930, 0.080745 ); + M_static_table_v18_narrow.emplace_back( 32.50, 32.459824, 0.081149 ); + M_static_table_v18_narrow.emplace_back( 32.60, 32.622530, 0.081556 ); + M_static_table_v18_narrow.emplace_back( 32.80, 32.786051, 0.081965 ); + M_static_table_v18_narrow.emplace_back( 33.00, 32.950392, 0.082375 ); + M_static_table_v18_narrow.emplace_back( 33.10, 33.115556, 0.082789 ); + M_static_table_v18_narrow.emplace_back( 33.30, 33.281549, 0.083203 ); + M_static_table_v18_narrow.emplace_back( 33.40, 33.448373, 0.083621 ); + M_static_table_v18_narrow.emplace_back( 33.60, 33.616034, 0.084039 ); + M_static_table_v18_narrow.emplace_back( 33.80, 33.784535, 0.084461 ); + M_static_table_v18_narrow.emplace_back( 34.00, 33.953881, 0.084884 ); + M_static_table_v18_narrow.emplace_back( 34.10, 34.124075, 0.085310 ); + M_static_table_v18_narrow.emplace_back( 34.30, 34.295123, 0.085737 ); + M_static_table_v18_narrow.emplace_back( 34.50, 34.467028, 0.086167 ); + M_static_table_v18_narrow.emplace_back( 34.60, 34.639794, 0.086599 ); + M_static_table_v18_narrow.emplace_back( 34.80, 34.813427, 0.087033 ); + M_static_table_v18_narrow.emplace_back( 35.00, 34.987930, 0.087469 ); + M_static_table_v18_narrow.emplace_back( 35.20, 35.163308, 0.087908 ); + M_static_table_v18_narrow.emplace_back( 35.30, 35.339565, 0.088348 ); + M_static_table_v18_narrow.emplace_back( 35.50, 35.516705, 0.088791 ); + M_static_table_v18_narrow.emplace_back( 35.70, 35.694733, 0.089237 ); + M_static_table_v18_narrow.emplace_back( 35.90, 35.873654, 0.089683 ); + M_static_table_v18_narrow.emplace_back( 36.10, 36.053471, 0.090133 ); + M_static_table_v18_narrow.emplace_back( 36.20, 36.234190, 0.090585 ); + M_static_table_v18_narrow.emplace_back( 36.40, 36.415815, 0.091039 ); + M_static_table_v18_narrow.emplace_back( 36.60, 36.598349, 0.091495 ); + M_static_table_v18_narrow.emplace_back( 36.80, 36.781799, 0.091954 ); + M_static_table_v18_narrow.emplace_back( 37.00, 36.966169, 0.092415 ); + M_static_table_v18_narrow.emplace_back( 37.20, 37.151462, 0.092878 ); + M_static_table_v18_narrow.emplace_back( 37.30, 37.337685, 0.093344 ); + M_static_table_v18_narrow.emplace_back( 37.50, 37.524841, 0.093812 ); + M_static_table_v18_narrow.emplace_back( 37.70, 37.712935, 0.094282 ); + M_static_table_v18_narrow.emplace_back( 37.90, 37.901972, 0.094755 ); + M_static_table_v18_narrow.emplace_back( 38.10, 38.091956, 0.095229 ); + M_static_table_v18_narrow.emplace_back( 38.30, 38.282893, 0.095707 ); + M_static_table_v18_narrow.emplace_back( 38.50, 38.474787, 0.096187 ); + M_static_table_v18_narrow.emplace_back( 38.70, 38.667642, 0.096668 ); + M_static_table_v18_narrow.emplace_back( 38.90, 38.861464, 0.097153 ); + M_static_table_v18_narrow.emplace_back( 39.10, 39.056258, 0.097640 ); + M_static_table_v18_narrow.emplace_back( 39.30, 39.252029, 0.098130 ); + M_static_table_v18_narrow.emplace_back( 39.40, 39.448780, 0.098621 ); + M_static_table_v18_narrow.emplace_back( 39.60, 39.646518, 0.099116 ); + M_static_table_v18_narrow.emplace_back( 39.80, 39.845247, 0.099612 ); + M_static_table_v18_narrow.emplace_back( 40.00, 40.044972, 0.100112 ); + M_static_table_v18_narrow.emplace_back( 40.20, 40.245699, 0.100614 ); + M_static_table_v18_narrow.emplace_back( 40.40, 40.447431, 0.101118 ); + M_static_table_v18_narrow.emplace_back( 40.70, 40.650175, 0.101625 ); + M_static_table_v18_narrow.emplace_back( 40.90, 40.853934, 0.102134 ); + M_static_table_v18_narrow.emplace_back( 41.10, 41.058715, 0.102646 ); + M_static_table_v18_narrow.emplace_back( 41.30, 41.264523, 0.103161 ); + M_static_table_v18_narrow.emplace_back( 41.50, 41.471363, 0.103678 ); + M_static_table_v18_narrow.emplace_back( 41.70, 41.679239, 0.104198 ); + M_static_table_v18_narrow.emplace_back( 41.90, 41.888157, 0.104720 ); + M_static_table_v18_narrow.emplace_back( 42.10, 42.098122, 0.105245 ); + M_static_table_v18_narrow.emplace_back( 42.30, 42.309140, 0.105773 ); + M_static_table_v18_narrow.emplace_back( 42.50, 42.521215, 0.106302 ); + M_static_table_v18_narrow.emplace_back( 42.70, 42.734354, 0.106836 ); + M_static_table_v18_narrow.emplace_back( 42.90, 42.948561, 0.107371 ); + M_static_table_v18_narrow.emplace_back( 43.20, 43.163841, 0.107909 ); + M_static_table_v18_narrow.emplace_back( 43.40, 43.380201, 0.108450 ); + M_static_table_v18_narrow.emplace_back( 43.60, 43.597645, 0.108994 ); + M_static_table_v18_narrow.emplace_back( 43.80, 43.816179, 0.109540 ); + M_static_table_v18_narrow.emplace_back( 44.00, 44.035808, 0.110089 ); + M_static_table_v18_narrow.emplace_back( 44.30, 44.256539, 0.110641 ); + M_static_table_v18_narrow.emplace_back( 44.50, 44.478376, 0.111196 ); + M_static_table_v18_narrow.emplace_back( 44.70, 44.701325, 0.111753 ); + M_static_table_v18_narrow.emplace_back( 44.90, 44.925391, 0.112313 ); + M_static_table_v18_narrow.emplace_back( 45.20, 45.150580, 0.112876 ); + M_static_table_v18_narrow.emplace_back( 45.40, 45.376899, 0.113442 ); + M_static_table_v18_narrow.emplace_back( 45.60, 45.604351, 0.114010 ); + M_static_table_v18_narrow.emplace_back( 45.80, 45.832944, 0.114582 ); + M_static_table_v18_narrow.emplace_back( 46.10, 46.062682, 0.115156 ); + M_static_table_v18_narrow.emplace_back( 46.30, 46.293573, 0.115734 ); + M_static_table_v18_narrow.emplace_back( 46.50, 46.525620, 0.116313 ); + M_static_table_v18_narrow.emplace_back( 46.80, 46.758831, 0.116897 ); + M_static_table_v18_narrow.emplace_back( 47.00, 46.993210, 0.117482 ); + M_static_table_v18_narrow.emplace_back( 47.20, 47.228765, 0.118072 ); + M_static_table_v18_narrow.emplace_back( 47.50, 47.465500, 0.118663 ); + M_static_table_v18_narrow.emplace_back( 47.70, 47.703422, 0.119258 ); + M_static_table_v18_narrow.emplace_back( 47.90, 47.942536, 0.119856 ); + M_static_table_v18_narrow.emplace_back( 48.20, 48.182849, 0.120456 ); + M_static_table_v18_narrow.emplace_back( 48.40, 48.424367, 0.121061 ); + M_static_table_v18_narrow.emplace_back( 48.70, 48.667095, 0.121667 ); + M_static_table_v18_narrow.emplace_back( 48.90, 48.911040, 0.122277 ); + M_static_table_v18_narrow.emplace_back( 49.20, 49.156207, 0.122890 ); + M_static_table_v18_narrow.emplace_back( 49.40, 49.402604, 0.123506 ); + M_static_table_v18_narrow.emplace_back( 49.70, 49.650235, 0.124125 ); + M_static_table_v18_narrow.emplace_back( 49.90, 49.899108, 0.124747 ); + M_static_table_v18_narrow.emplace_back( 50.10, 50.149229, 0.125373 ); + M_static_table_v18_narrow.emplace_back( 50.40, 50.400603, 0.126001 ); + M_static_table_v18_narrow.emplace_back( 50.70, 50.653237, 0.126633 ); + M_static_table_v18_narrow.emplace_back( 50.90, 50.907137, 0.127267 ); + M_static_table_v18_narrow.emplace_back( 51.20, 51.162310, 0.127905 ); + M_static_table_v18_narrow.emplace_back( 51.40, 51.418762, 0.128546 ); + M_static_table_v18_narrow.emplace_back( 51.70, 51.676500, 0.129191 ); + M_static_table_v18_narrow.emplace_back( 51.90, 51.935529, 0.129838 ); + M_static_table_v18_narrow.emplace_back( 52.20, 52.195857, 0.130489 ); + M_static_table_v18_narrow.emplace_back( 52.50, 52.457490, 0.131143 ); + M_static_table_v18_narrow.emplace_back( 52.70, 52.720434, 0.131800 ); + M_static_table_v18_narrow.emplace_back( 53.00, 52.984696, 0.132461 ); + M_static_table_v18_narrow.emplace_back( 53.30, 53.250283, 0.133125 ); + M_static_table_v18_narrow.emplace_back( 53.50, 53.517202, 0.133793 ); + M_static_table_v18_narrow.emplace_back( 53.80, 53.785458, 0.134463 ); + M_static_table_v18_narrow.emplace_back( 54.10, 54.055058, 0.135137 ); + M_static_table_v18_narrow.emplace_back( 54.30, 54.326011, 0.135815 ); + M_static_table_v18_narrow.emplace_back( 54.60, 54.598321, 0.136495 ); + M_static_table_v18_narrow.emplace_back( 54.90, 54.871996, 0.137179 ); + M_static_table_v18_narrow.emplace_back( 55.10, 55.147043, 0.137867 ); + M_static_table_v18_narrow.emplace_back( 55.40, 55.423469, 0.138558 ); + M_static_table_v18_narrow.emplace_back( 55.70, 55.701280, 0.139252 ); + M_static_table_v18_narrow.emplace_back( 56.00, 55.980484, 0.139951 ); + M_static_table_v18_narrow.emplace_back( 56.30, 56.261087, 0.140652 ); + M_static_table_v18_narrow.emplace_back( 56.50, 56.543097, 0.141357 ); + M_static_table_v18_narrow.emplace_back( 56.80, 56.826521, 0.142066 ); + M_static_table_v18_narrow.emplace_back( 57.10, 57.111365, 0.142778 ); + M_static_table_v18_narrow.emplace_back( 57.40, 57.397637, 0.143494 ); + M_static_table_v18_narrow.emplace_back( 57.70, 57.685344, 0.144213 ); + M_static_table_v18_narrow.emplace_back( 58.00, 57.974493, 0.144936 ); + M_static_table_v18_narrow.emplace_back( 58.30, 58.265091, 0.145662 ); + M_static_table_v18_narrow.emplace_back( 58.60, 58.557146, 0.146392 ); + M_static_table_v18_narrow.emplace_back( 58.90, 58.850665, 0.147126 ); + M_static_table_v18_narrow.emplace_back( 59.10, 59.145655, 0.147864 ); + M_static_table_v18_narrow.emplace_back( 59.40, 59.442124, 0.148605 ); + M_static_table_v18_narrow.emplace_back( 59.70, 59.740079, 0.149350 ); + M_static_table_v18_narrow.emplace_back( 60.00, 60.039527, 0.150098 ); + M_static_table_v18_narrow.emplace_back( 60.30, 60.340477, 0.150851 ); + M_static_table_v18_narrow.emplace_back( 60.60, 60.642935, 0.151607 ); + M_static_table_v18_narrow.emplace_back( 60.90, 60.946909, 0.152367 ); + M_static_table_v18_narrow.emplace_back( 61.30, 61.252406, 0.153130 ); + M_static_table_v18_narrow.emplace_back( 61.60, 61.559435, 0.153898 ); + M_static_table_v18_narrow.emplace_back( 61.90, 61.868003, 0.154670 ); + M_static_table_v18_narrow.emplace_back( 62.20, 62.178118, 0.155445 ); + M_static_table_v18_narrow.emplace_back( 62.50, 62.489787, 0.156224 ); + M_static_table_v18_narrow.emplace_back( 62.80, 62.803018, 0.157007 ); + M_static_table_v18_narrow.emplace_back( 63.10, 63.117819, 0.157794 ); + M_static_table_v18_narrow.emplace_back( 63.40, 63.434199, 0.158585 ); + M_static_table_v18_narrow.emplace_back( 63.80, 63.752164, 0.159380 ); + M_static_table_v18_narrow.emplace_back( 64.10, 64.071723, 0.160179 ); + M_static_table_v18_narrow.emplace_back( 64.40, 64.392884, 0.160982 ); + M_static_table_v18_narrow.emplace_back( 64.70, 64.715655, 0.161789 ); + M_static_table_v18_narrow.emplace_back( 65.00, 65.040043, 0.162599 ); + M_static_table_v18_narrow.emplace_back( 65.40, 65.366058, 0.163415 ); + M_static_table_v18_narrow.emplace_back( 65.70, 65.693707, 0.164234 ); + M_static_table_v18_narrow.emplace_back( 66.00, 66.022998, 0.165057 ); + M_static_table_v18_narrow.emplace_back( 66.40, 66.353939, 0.165884 ); + M_static_table_v18_narrow.emplace_back( 66.70, 66.686540, 0.166716 ); + M_static_table_v18_narrow.emplace_back( 67.00, 67.020807, 0.167551 ); + M_static_table_v18_narrow.emplace_back( 67.40, 67.356750, 0.168391 ); + M_static_table_v18_narrow.emplace_back( 67.70, 67.694378, 0.169236 ); + M_static_table_v18_narrow.emplace_back( 68.00, 68.033697, 0.170083 ); + M_static_table_v18_narrow.emplace_back( 68.40, 68.374717, 0.170936 ); + M_static_table_v18_narrow.emplace_back( 68.70, 68.717447, 0.171793 ); + M_static_table_v18_narrow.emplace_back( 69.10, 69.061895, 0.172654 ); + M_static_table_v18_narrow.emplace_back( 69.40, 69.408069, 0.173519 ); + M_static_table_v18_narrow.emplace_back( 69.80, 69.755978, 0.174389 ); + M_static_table_v18_narrow.emplace_back( 70.10, 70.105632, 0.175264 ); + M_static_table_v18_narrow.emplace_back( 70.50, 70.457038, 0.176142 ); + M_static_table_v18_narrow.emplace_back( 70.80, 70.810205, 0.177025 ); + M_static_table_v18_narrow.emplace_back( 71.20, 71.165142, 0.177912 ); + M_static_table_v18_narrow.emplace_back( 71.50, 71.521859, 0.178804 ); + M_static_table_v18_narrow.emplace_back( 71.90, 71.880364, 0.179700 ); + M_static_table_v18_narrow.emplace_back( 72.20, 72.240666, 0.180601 ); + M_static_table_v18_narrow.emplace_back( 72.60, 72.602774, 0.181506 ); + M_static_table_v18_narrow.emplace_back( 73.00, 72.966697, 0.182416 ); + M_static_table_v18_narrow.emplace_back( 73.30, 73.332444, 0.183331 ); + M_static_table_v18_narrow.emplace_back( 73.70, 73.700024, 0.184249 ); + M_static_table_v18_narrow.emplace_back( 74.10, 74.069447, 0.185173 ); + M_static_table_v18_narrow.emplace_back( 74.40, 74.440722, 0.186101 ); + M_static_table_v18_narrow.emplace_back( 74.80, 74.813858, 0.187034 ); + M_static_table_v18_narrow.emplace_back( 75.20, 75.188864, 0.187972 ); + M_static_table_v18_narrow.emplace_back( 75.60, 75.565750, 0.188914 ); + M_static_table_v18_narrow.emplace_back( 75.90, 75.944524, 0.189860 ); + M_static_table_v18_narrow.emplace_back( 76.30, 76.325198, 0.190813 ); + M_static_table_v18_narrow.emplace_back( 76.70, 76.707780, 0.191769 ); + M_static_table_v18_narrow.emplace_back( 77.10, 77.092279, 0.192730 ); + M_static_table_v18_narrow.emplace_back( 77.50, 77.478705, 0.193696 ); + M_static_table_v18_narrow.emplace_back( 77.90, 77.867069, 0.194667 ); + M_static_table_v18_narrow.emplace_back( 78.30, 78.257380, 0.195643 ); + M_static_table_v18_narrow.emplace_back( 78.60, 78.649646, 0.196623 ); + M_static_table_v18_narrow.emplace_back( 79.00, 79.043879, 0.197609 ); + M_static_table_v18_narrow.emplace_back( 79.40, 79.440088, 0.198599 ); + M_static_table_v18_narrow.emplace_back( 79.80, 79.838283, 0.199595 ); + M_static_table_v18_narrow.emplace_back( 80.20, 80.238474, 0.200595 ); + M_static_table_v18_narrow.emplace_back( 80.60, 80.640671, 0.201601 ); + M_static_table_v18_narrow.emplace_back( 81.00, 81.044884, 0.202611 ); + M_static_table_v18_narrow.emplace_back( 81.50, 81.451123, 0.203627 ); + M_static_table_v18_narrow.emplace_back( 81.90, 81.859399, 0.204648 ); + M_static_table_v18_narrow.emplace_back( 82.30, 82.269721, 0.205674 ); + M_static_table_v18_narrow.emplace_back( 82.70, 82.682100, 0.206705 ); + M_static_table_v18_narrow.emplace_back( 83.10, 83.096546, 0.207741 ); + M_static_table_v18_narrow.emplace_back( 83.50, 83.513069, 0.208782 ); + M_static_table_v18_narrow.emplace_back( 83.90, 83.931680, 0.209829 ); + M_static_table_v18_narrow.emplace_back( 84.40, 84.352389, 0.210880 ); + M_static_table_v18_narrow.emplace_back( 84.80, 84.775207, 0.211937 ); + M_static_table_v18_narrow.emplace_back( 85.20, 85.200145, 0.213000 ); + M_static_table_v18_narrow.emplace_back( 85.60, 85.627212, 0.214067 ); + M_static_table_v18_narrow.emplace_back( 86.10, 86.056420, 0.215140 ); + M_static_table_v18_narrow.emplace_back( 86.50, 86.487780, 0.216219 ); + M_static_table_v18_narrow.emplace_back( 86.90, 86.921302, 0.217303 ); + M_static_table_v18_narrow.emplace_back( 87.40, 87.356997, 0.218392 ); + M_static_table_v18_narrow.emplace_back( 87.80, 87.794875, 0.219486 ); + M_static_table_v18_narrow.emplace_back( 88.20, 88.234949, 0.220587 ); + M_static_table_v18_narrow.emplace_back( 88.70, 88.677228, 0.221692 ); + M_static_table_v18_narrow.emplace_back( 89.10, 89.121725, 0.222804 ); + M_static_table_v18_narrow.emplace_back( 89.60, 89.568449, 0.223920 ); + M_static_table_v18_narrow.emplace_back( 90.00, 90.017413, 0.225043 ); + M_static_table_v18_narrow.emplace_back( 90.50, 90.468627, 0.226171 ); + M_static_table_v18_narrow.emplace_back( 90.90, 90.922103, 0.227305 ); + M_static_table_v18_narrow.emplace_back( 91.40, 91.377852, 0.228444 ); + M_static_table_v18_narrow.emplace_back( 91.80, 91.835885, 0.229589 ); + M_static_table_v18_narrow.emplace_back( 92.30, 92.296215, 0.230740 ); + M_static_table_v18_narrow.emplace_back( 92.80, 92.758851, 0.231896 ); + M_static_table_v18_narrow.emplace_back( 93.20, 93.223807, 0.233059 ); + M_static_table_v18_narrow.emplace_back( 93.70, 93.691093, 0.234227 ); + M_static_table_v18_narrow.emplace_back( 94.20, 94.160722, 0.235401 ); + M_static_table_v18_narrow.emplace_back( 94.60, 94.632704, 0.236581 ); + M_static_table_v18_narrow.emplace_back( 95.10, 95.107053, 0.237767 ); + M_static_table_v18_narrow.emplace_back( 95.60, 95.583779, 0.238959 ); + M_static_table_v18_narrow.emplace_back( 96.10, 96.062895, 0.240157 ); + M_static_table_v18_narrow.emplace_back( 96.50, 96.544412, 0.241360 ); + M_static_table_v18_narrow.emplace_back( 97.00, 97.028343, 0.242570 ); + M_static_table_v18_narrow.emplace_back( 97.50, 97.514699, 0.243786 ); + M_static_table_v18_narrow.emplace_back( 98.00, 98.003494, 0.245008 ); + M_static_table_v18_narrow.emplace_back( 98.50, 98.494738, 0.246236 ); + M_static_table_v18_narrow.emplace_back( 99.00, 98.988445, 0.247470 ); + M_static_table_v18_narrow.emplace_back( 99.50, 99.484627, 0.248711 ); + M_static_table_v18_narrow.emplace_back( 100.00, 99.983296, 0.249958 ); + M_static_table_v18_narrow.emplace_back( 100.50, 100.484464, 0.251210 ); + M_static_table_v18_narrow.emplace_back( 101.00, 100.988145, 0.252470 ); + M_static_table_v18_narrow.emplace_back( 101.50, 101.494350, 0.253735 ); + M_static_table_v18_narrow.emplace_back( 102.00, 102.003092, 0.255007 ); + M_static_table_v18_narrow.emplace_back( 102.50, 102.514385, 0.256285 ); + M_static_table_v18_narrow.emplace_back( 103.00, 103.028241, 0.257570 ); + M_static_table_v18_narrow.emplace_back( 103.50, 103.544672, 0.258861 ); + M_static_table_v18_narrow.emplace_back( 104.10, 104.063691, 0.260158 ); + M_static_table_v18_narrow.emplace_back( 104.60, 104.585313, 0.261463 ); + M_static_table_v18_narrow.emplace_back( 105.10, 105.109549, 0.262773 ); + M_static_table_v18_narrow.emplace_back( 105.60, 105.636412, 0.264090 ); + M_static_table_v18_narrow.emplace_back( 106.20, 106.165917, 0.265414 ); + M_static_table_v18_narrow.emplace_back( 106.70, 106.698076, 0.266744 ); + M_static_table_v18_narrow.emplace_back( 107.20, 107.232903, 0.268082 ); + M_static_table_v18_narrow.emplace_back( 107.80, 107.770410, 0.269425 ); + M_static_table_v18_narrow.emplace_back( 108.30, 108.310611, 0.270776 ); + M_static_table_v18_narrow.emplace_back( 108.90, 108.853520, 0.272133 ); + M_static_table_v18_narrow.emplace_back( 109.40, 109.399151, 0.273497 ); + M_static_table_v18_narrow.emplace_back( 109.90, 109.947517, 0.274868 ); + M_static_table_v18_narrow.emplace_back( 110.50, 110.498631, 0.276246 ); + M_static_table_v18_narrow.emplace_back( 111.10, 111.052507, 0.277630 ); + M_static_table_v18_narrow.emplace_back( 111.60, 111.609160, 0.279022 ); + M_static_table_v18_narrow.emplace_back( 112.20, 112.168604, 0.280421 ); + M_static_table_v18_narrow.emplace_back( 112.70, 112.730851, 0.281826 ); + M_static_table_v18_narrow.emplace_back( 113.30, 113.295917, 0.283239 ); + M_static_table_v18_narrow.emplace_back( 113.90, 113.863815, 0.284659 ); + M_static_table_v18_narrow.emplace_back( 114.40, 114.434560, 0.286086 ); + M_static_table_v18_narrow.emplace_back( 115.00, 115.008165, 0.287519 ); + M_static_table_v18_narrow.emplace_back( 115.60, 115.584646, 0.288961 ); + M_static_table_v18_narrow.emplace_back( 116.20, 116.164016, 0.290409 ); + M_static_table_v18_narrow.emplace_back( 116.70, 116.746291, 0.291865 ); + M_static_table_v18_narrow.emplace_back( 117.30, 117.331485, 0.293328 ); + M_static_table_v18_narrow.emplace_back( 117.90, 117.919611, 0.294798 ); + M_static_table_v18_narrow.emplace_back( 118.50, 118.510686, 0.296276 ); + M_static_table_v18_narrow.emplace_back( 119.10, 119.104723, 0.297761 ); + M_static_table_v18_narrow.emplace_back( 119.70, 119.701738, 0.299254 ); + M_static_table_v18_narrow.emplace_back( 120.30, 120.301745, 0.300753 ); + M_static_table_v18_narrow.emplace_back( 120.90, 120.904760, 0.302261 ); + M_static_table_v18_narrow.emplace_back( 121.50, 121.510798, 0.303776 ); + M_static_table_v18_narrow.emplace_back( 122.10, 122.119873, 0.305299 ); + M_static_table_v18_narrow.emplace_back( 122.70, 122.732001, 0.306829 ); + M_static_table_v18_narrow.emplace_back( 123.30, 123.347198, 0.308367 ); + M_static_table_v18_narrow.emplace_back( 124.00, 123.965479, 0.309913 ); + M_static_table_v18_narrow.emplace_back( 124.60, 124.586858, 0.311466 ); + M_static_table_v18_narrow.emplace_back( 125.20, 125.211352, 0.313027 ); + M_static_table_v18_narrow.emplace_back( 125.80, 125.838977, 0.314597 ); + M_static_table_v18_narrow.emplace_back( 126.50, 126.469747, 0.316173 ); + M_static_table_v18_narrow.emplace_back( 127.10, 127.103679, 0.317758 ); + M_static_table_v18_narrow.emplace_back( 127.70, 127.740789, 0.319351 ); + M_static_table_v18_narrow.emplace_back( 128.40, 128.381093, 0.320952 ); + M_static_table_v18_narrow.emplace_back( 129.00, 129.024606, 0.322561 ); + M_static_table_v18_narrow.emplace_back( 129.70, 129.671344, 0.324177 ); + M_static_table_v18_narrow.emplace_back( 130.30, 130.321325, 0.325803 ); + M_static_table_v18_narrow.emplace_back( 131.00, 130.974563, 0.327435 ); + M_static_table_v18_narrow.emplace_back( 131.60, 131.631076, 0.329077 ); + M_static_table_v18_narrow.emplace_back( 132.30, 132.290879, 0.330726 ); + M_static_table_v18_narrow.emplace_back( 133.00, 132.953990, 0.332384 ); + M_static_table_v18_narrow.emplace_back( 133.60, 133.620425, 0.334050 ); + M_static_table_v18_narrow.emplace_back( 134.30, 134.290200, 0.335725 ); + M_static_table_v18_narrow.emplace_back( 135.00, 134.963332, 0.337407 ); + M_static_table_v18_narrow.emplace_back( 135.60, 135.639839, 0.339099 ); + M_static_table_v18_narrow.emplace_back( 136.30, 136.319736, 0.340798 ); + M_static_table_v18_narrow.emplace_back( 137.00, 137.003042, 0.342507 ); + M_static_table_v18_narrow.emplace_back( 137.70, 137.689772, 0.344223 ); + M_static_table_v18_narrow.emplace_back( 138.40, 138.379945, 0.345949 ); + M_static_table_v18_narrow.emplace_back( 139.10, 139.073578, 0.347683 ); + M_static_table_v18_narrow.emplace_back( 139.80, 139.770687, 0.349426 ); + M_static_table_v18_narrow.emplace_back( 140.50, 140.471290, 0.351177 ); + M_static_table_v18_narrow.emplace_back( 141.20, 141.175406, 0.352938 ); + M_static_table_v18_narrow.emplace_back( 141.90, 141.883050, 0.354706 ); + M_static_table_v18_narrow.emplace_back( 142.60, 142.594242, 0.356485 ); + M_static_table_v18_narrow.emplace_back( 143.30, 143.308999, 0.358272 ); + M_static_table_v18_narrow.emplace_back( 144.00, 144.027338, 0.360067 ); + M_static_table_v18_narrow.emplace_back( 144.70, 144.749278, 0.361872 ); + M_static_table_v18_narrow.emplace_back( 145.50, 145.474837, 0.363686 ); + M_static_table_v18_narrow.emplace_back( 146.20, 146.204032, 0.365509 ); + M_static_table_v18_narrow.emplace_back( 146.90, 146.936883, 0.367341 ); + M_static_table_v18_narrow.emplace_back( 147.70, 147.673407, 0.369182 ); + M_static_table_v18_narrow.emplace_back( 148.40, 148.413623, 0.371033 ); + M_static_table_v18_narrow.emplace_back( 149.20, 149.157550, 0.372893 ); + M_static_table_v18_narrow.emplace_back( 149.90, 149.905205, 0.374762 ); + M_static_table_v18_narrow.emplace_back( 150.70, 150.656608, 0.376640 ); + M_static_table_v18_narrow.emplace_back( 151.40, 151.411777, 0.378528 ); + M_static_table_v18_narrow.emplace_back( 152.20, 152.170732, 0.380426 ); + + // -------------------------------------------------------------------- + M_static_table_v18_normal.emplace_back( 0.00, 0.024988, 0.024988 ); + M_static_table_v18_normal.emplace_back( 0.10, 0.100241, 0.050266 ); + M_static_table_v18_normal.emplace_back( 0.20, 0.200572, 0.050065 ); + M_static_table_v18_normal.emplace_back( 0.30, 0.300945, 0.050308 ); + M_static_table_v18_normal.emplace_back( 0.40, 0.400572, 0.049319 ); + M_static_table_v18_normal.emplace_back( 0.50, 0.500382, 0.050492 ); + M_static_table_v18_normal.emplace_back( 0.60, 0.600285, 0.049412 ); + M_static_table_v18_normal.emplace_back( 0.70, 0.699448, 0.049752 ); + M_static_table_v18_normal.emplace_back( 0.80, 0.800140, 0.050940 ); + M_static_table_v18_normal.emplace_back( 0.90, 0.901750, 0.050670 ); + M_static_table_v18_normal.emplace_back( 1.00, 1.001189, 0.048769 ); + M_static_table_v18_normal.emplace_back( 1.10, 1.099397, 0.049439 ); + M_static_table_v18_normal.emplace_back( 1.20, 1.198236, 0.049399 ); + M_static_table_v18_normal.emplace_back( 1.30, 1.301283, 0.053647 ); + M_static_table_v18_normal.emplace_back( 1.40, 1.402238, 0.047307 ); + M_static_table_v18_normal.emplace_back( 1.50, 1.500157, 0.050611 ); + M_static_table_v18_normal.emplace_back( 1.60, 1.598715, 0.047947 ); + M_static_table_v18_normal.emplace_back( 1.70, 1.697574, 0.050912 ); + M_static_table_v18_normal.emplace_back( 1.80, 1.802546, 0.054060 ); + M_static_table_v18_normal.emplace_back( 1.90, 1.906644, 0.050038 ); + M_static_table_v18_normal.emplace_back( 2.00, 2.001713, 0.045031 ); + M_static_table_v18_normal.emplace_back( 2.10, 2.101906, 0.055163 ); + M_static_table_v18_normal.emplace_back( 2.20, 2.206711, 0.049643 ); + M_static_table_v18_normal.emplace_back( 2.30, 2.299464, 0.043110 ); + M_static_table_v18_normal.emplace_back( 2.40, 2.396485, 0.053912 ); + M_static_table_v18_normal.emplace_back( 2.50, 2.497214, 0.046818 ); + M_static_table_v18_normal.emplace_back( 2.60, 2.592638, 0.048606 ); + M_static_table_v18_normal.emplace_back( 2.70, 2.691708, 0.050464 ); + M_static_table_v18_normal.emplace_back( 2.80, 2.794564, 0.052392 ); + M_static_table_v18_normal.emplace_back( 2.90, 2.901349, 0.054394 ); + M_static_table_v18_normal.emplace_back( 3.00, 3.000751, 0.045008 ); + M_static_table_v18_normal.emplace_back( 3.10, 3.092138, 0.046379 ); + M_static_table_v18_normal.emplace_back( 3.20, 3.198481, 0.059965 ); + M_static_table_v18_normal.emplace_back( 3.30, 3.308063, 0.049618 ); + M_static_table_v18_normal.emplace_back( 3.40, 3.408808, 0.051128 ); + M_static_table_v18_normal.emplace_back( 3.50, 3.499302, 0.039366 ); + M_static_table_v18_normal.emplace_back( 3.60, 3.592552, 0.053885 ); + M_static_table_v18_normal.emplace_back( 3.70, 3.701961, 0.055525 ); + M_static_table_v18_normal.emplace_back( 3.80, 3.800237, 0.042751 ); + M_static_table_v18_normal.emplace_back( 3.90, 3.901506, 0.058518 ); + M_static_table_v18_normal.emplace_back( 4.00, 4.005080, 0.045056 ); + M_static_table_v18_normal.emplace_back( 4.10, 4.096216, 0.046081 ); + M_static_table_v18_normal.emplace_back( 4.20, 4.189425, 0.047129 ); + M_static_table_v18_normal.emplace_back( 4.30, 4.301065, 0.064511 ); + M_static_table_v18_normal.emplace_back( 4.40, 4.415246, 0.049670 ); + M_static_table_v18_normal.emplace_back( 4.50, 4.515715, 0.050800 ); + M_static_table_v18_normal.emplace_back( 4.60, 4.601021, 0.034507 ); + M_static_table_v18_normal.emplace_back( 4.70, 4.688269, 0.052741 ); + M_static_table_v18_normal.emplace_back( 4.80, 4.794951, 0.053941 ); + M_static_table_v18_normal.emplace_back( 4.90, 4.904060, 0.055169 ); + M_static_table_v18_normal.emplace_back( 5.00, 4.996703, 0.037475 ); + M_static_table_v18_normal.emplace_back( 5.10, 5.091454, 0.057277 ); + M_static_table_v18_normal.emplace_back( 5.20, 5.207310, 0.058580 ); + M_static_table_v18_normal.emplace_back( 5.30, 5.305682, 0.039792 ); + M_static_table_v18_normal.emplace_back( 5.40, 5.406292, 0.060819 ); + M_static_table_v18_normal.emplace_back( 5.50, 5.508423, 0.041313 ); + M_static_table_v18_normal.emplace_back( 5.60, 5.591672, 0.041937 ); + M_static_table_v18_normal.emplace_back( 5.70, 5.697705, 0.064097 ); + M_static_table_v18_normal.emplace_back( 5.80, 5.805340, 0.043539 ); + M_static_table_v18_normal.emplace_back( 5.90, 5.893077, 0.044198 ); + M_static_table_v18_normal.emplace_back( 6.00, 6.004826, 0.067552 ); + M_static_table_v18_normal.emplace_back( 6.10, 6.118263, 0.045886 ); + M_static_table_v18_normal.emplace_back( 6.20, 6.210729, 0.046580 ); + M_static_table_v18_normal.emplace_back( 6.30, 6.304592, 0.047284 ); + M_static_table_v18_normal.emplace_back( 6.40, 6.399874, 0.047999 ); + M_static_table_v18_normal.emplace_back( 6.50, 6.496596, 0.048724 ); + M_static_table_v18_normal.emplace_back( 6.60, 6.594779, 0.049460 ); + M_static_table_v18_normal.emplace_back( 6.70, 6.694446, 0.050208 ); + M_static_table_v18_normal.emplace_back( 6.80, 6.795620, 0.050967 ); + M_static_table_v18_normal.emplace_back( 6.90, 6.898322, 0.051736 ); + M_static_table_v18_normal.emplace_back( 7.00, 7.002577, 0.052519 ); + M_static_table_v18_normal.emplace_back( 7.10, 7.108407, 0.053312 ); + M_static_table_v18_normal.emplace_back( 7.20, 7.215837, 0.054118 ); + M_static_table_v18_normal.emplace_back( 7.30, 7.297320, 0.027365 ); + M_static_table_v18_normal.emplace_back( 7.40, 7.380034, 0.055350 ); + M_static_table_v18_normal.emplace_back( 7.50, 7.491569, 0.056186 ); + M_static_table_v18_normal.emplace_back( 7.60, 7.604789, 0.057035 ); + M_static_table_v18_normal.emplace_back( 7.70, 7.719721, 0.057897 ); + M_static_table_v18_normal.emplace_back( 7.80, 7.806894, 0.029276 ); + M_static_table_v18_normal.emplace_back( 7.90, 7.895383, 0.059214 ); + M_static_table_v18_normal.emplace_back( 8.00, 8.014707, 0.060109 ); + M_static_table_v18_normal.emplace_back( 8.10, 8.105211, 0.030394 ); + M_static_table_v18_normal.emplace_back( 8.20, 8.197082, 0.061477 ); + M_static_table_v18_normal.emplace_back( 8.30, 8.289645, 0.031086 ); + M_static_table_v18_normal.emplace_back( 8.40, 8.383607, 0.062875 ); + M_static_table_v18_normal.emplace_back( 8.50, 8.510309, 0.063826 ); + M_static_table_v18_normal.emplace_back( 8.60, 8.606409, 0.032273 ); + M_static_table_v18_normal.emplace_back( 8.70, 8.703961, 0.065278 ); + M_static_table_v18_normal.emplace_back( 8.80, 8.802248, 0.033008 ); + M_static_table_v18_normal.emplace_back( 8.90, 8.902020, 0.066764 ); + M_static_table_v18_normal.emplace_back( 9.00, 9.002543, 0.033759 ); + M_static_table_v18_normal.emplace_back( 9.10, 9.104585, 0.068283 ); + M_static_table_v18_normal.emplace_back( 9.20, 9.207396, 0.034527 ); + M_static_table_v18_normal.emplace_back( 9.30, 9.311760, 0.069836 ); + M_static_table_v18_normal.emplace_back( 9.40, 9.416910, 0.035313 ); + M_static_table_v18_normal.emplace_back( 9.50, 9.487803, 0.035579 ); + M_static_table_v18_normal.emplace_back( 9.60, 9.595346, 0.071964 ); + M_static_table_v18_normal.emplace_back( 9.70, 9.703698, 0.036388 ); + M_static_table_v18_normal.emplace_back( 9.80, 9.776749, 0.036662 ); + M_static_table_v18_normal.emplace_back( 9.90, 9.887567, 0.074155 ); + M_static_table_v18_normal.emplace_back( 10.00, 9.999220, 0.037497 ); + M_static_table_v18_normal.emplace_back( 10.10, 10.074496, 0.037779 ); + M_static_table_v18_normal.emplace_back( 10.20, 10.188689, 0.076414 ); + M_static_table_v18_normal.emplace_back( 10.30, 10.303741, 0.038638 ); + M_static_table_v18_normal.emplace_back( 10.40, 10.381310, 0.038930 ); + M_static_table_v18_normal.emplace_back( 10.50, 10.498981, 0.078741 ); + M_static_table_v18_normal.emplace_back( 10.60, 10.617537, 0.039815 ); + M_static_table_v18_normal.emplace_back( 10.70, 10.697468, 0.040115 ); + M_static_table_v18_normal.emplace_back( 10.80, 10.778000, 0.040417 ); + M_static_table_v18_normal.emplace_back( 10.90, 10.900167, 0.081749 ); + M_static_table_v18_normal.emplace_back( 11.00, 11.023254, 0.041337 ); + M_static_table_v18_normal.emplace_back( 11.10, 11.106239, 0.041648 ); + M_static_table_v18_normal.emplace_back( 11.20, 11.189849, 0.041961 ); + M_static_table_v18_normal.emplace_back( 11.30, 11.274089, 0.042278 ); + M_static_table_v18_normal.emplace_back( 11.40, 11.401879, 0.085512 ); + M_static_table_v18_normal.emplace_back( 11.50, 11.530631, 0.043239 ); + M_static_table_v18_normal.emplace_back( 11.60, 11.617436, 0.043565 ); + M_static_table_v18_normal.emplace_back( 11.70, 11.704894, 0.043893 ); + M_static_table_v18_normal.emplace_back( 11.80, 11.793011, 0.044224 ); + M_static_table_v18_normal.emplace_back( 11.90, 11.881791, 0.044556 ); + M_static_table_v18_normal.emplace_back( 12.00, 11.971240, 0.044892 ); + M_static_table_v18_normal.emplace_back( 12.10, 12.061361, 0.045229 ); + M_static_table_v18_normal.emplace_back( 12.20, 12.198075, 0.091484 ); + M_static_table_v18_normal.emplace_back( 12.30, 12.335818, 0.046259 ); + M_static_table_v18_normal.emplace_back( 12.40, 12.428684, 0.046607 ); + M_static_table_v18_normal.emplace_back( 12.50, 12.522250, 0.046958 ); + M_static_table_v18_normal.emplace_back( 12.60, 12.616520, 0.047312 ); + M_static_table_v18_normal.emplace_back( 12.70, 12.711500, 0.047668 ); + M_static_table_v18_normal.emplace_back( 12.80, 12.807194, 0.048026 ); + M_static_table_v18_normal.emplace_back( 12.90, 12.903609, 0.048388 ); + M_static_table_v18_normal.emplace_back( 13.00, 13.000750, 0.048752 ); + M_static_table_v18_normal.emplace_back( 13.10, 13.098622, 0.049119 ); + M_static_table_v18_normal.emplace_back( 13.20, 13.197231, 0.049489 ); + M_static_table_v18_normal.emplace_back( 13.30, 13.296583, 0.049862 ); + M_static_table_v18_normal.emplace_back( 13.40, 13.396682, 0.050237 ); + M_static_table_v18_normal.emplace_back( 13.50, 13.497534, 0.050615 ); + M_static_table_v18_normal.emplace_back( 13.60, 13.599147, 0.050997 ); + M_static_table_v18_normal.emplace_back( 13.70, 13.701524, 0.051380 ); + M_static_table_v18_normal.emplace_back( 13.80, 13.804671, 0.051767 ); + M_static_table_v18_normal.emplace_back( 13.90, 13.908596, 0.052157 ); + M_static_table_v18_normal.emplace_back( 14.00, 14.013302, 0.052549 ); + M_static_table_v18_normal.emplace_back( 14.10, 14.118797, 0.052945 ); + M_static_table_v18_normal.emplace_back( 14.20, 14.225086, 0.053343 ); + M_static_table_v18_normal.emplace_back( 14.30, 14.332175, 0.053745 ); + M_static_table_v18_normal.emplace_back( 14.40, 14.440071, 0.054150 ); + M_static_table_v18_normal.emplace_back( 14.50, 14.548779, 0.054558 ); + M_static_table_v18_normal.emplace_back( 14.70, 14.658305, 0.054968 ); + M_static_table_v18_normal.emplace_back( 14.80, 14.768655, 0.055382 ); + M_static_table_v18_normal.emplace_back( 14.90, 14.879837, 0.055799 ); + M_static_table_v18_normal.emplace_back( 15.00, 14.991855, 0.056219 ); + M_static_table_v18_normal.emplace_back( 15.10, 15.104716, 0.056642 ); + M_static_table_v18_normal.emplace_back( 15.20, 15.218428, 0.057069 ); + M_static_table_v18_normal.emplace_back( 15.30, 15.332995, 0.057498 ); + M_static_table_v18_normal.emplace_back( 15.40, 15.448425, 0.057931 ); + M_static_table_v18_normal.emplace_back( 15.60, 15.564723, 0.058367 ); + M_static_table_v18_normal.emplace_back( 15.70, 15.681898, 0.058807 ); + M_static_table_v18_normal.emplace_back( 15.80, 15.799954, 0.059249 ); + M_static_table_v18_normal.emplace_back( 15.90, 15.918899, 0.059695 ); + M_static_table_v18_normal.emplace_back( 16.00, 16.038740, 0.060145 ); + M_static_table_v18_normal.emplace_back( 16.20, 16.159483, 0.060598 ); + M_static_table_v18_normal.emplace_back( 16.30, 16.281135, 0.061054 ); + M_static_table_v18_normal.emplace_back( 16.40, 16.403702, 0.061514 ); + M_static_table_v18_normal.emplace_back( 16.50, 16.527192, 0.061977 ); + M_static_table_v18_normal.emplace_back( 16.70, 16.651612, 0.062444 ); + M_static_table_v18_normal.emplace_back( 16.80, 16.776969, 0.062913 ); + M_static_table_v18_normal.emplace_back( 16.90, 16.903269, 0.063387 ); + M_static_table_v18_normal.emplace_back( 17.00, 17.030520, 0.063865 ); + M_static_table_v18_normal.emplace_back( 17.20, 17.158730, 0.064345 ); + M_static_table_v18_normal.emplace_back( 17.30, 17.287904, 0.064829 ); + M_static_table_v18_normal.emplace_back( 17.40, 17.418050, 0.065318 ); + M_static_table_v18_normal.emplace_back( 17.50, 17.549177, 0.065809 ); + M_static_table_v18_normal.emplace_back( 17.70, 17.681290, 0.066305 ); + M_static_table_v18_normal.emplace_back( 17.80, 17.814399, 0.066804 ); + M_static_table_v18_normal.emplace_back( 17.90, 17.948509, 0.067307 ); + M_static_table_v18_normal.emplace_back( 18.10, 18.083629, 0.067813 ); + M_static_table_v18_normal.emplace_back( 18.20, 18.219766, 0.068324 ); + M_static_table_v18_normal.emplace_back( 18.40, 18.356928, 0.068838 ); + M_static_table_v18_normal.emplace_back( 18.50, 18.495122, 0.069357 ); + M_static_table_v18_normal.emplace_back( 18.60, 18.634357, 0.069879 ); + M_static_table_v18_normal.emplace_back( 18.80, 18.774640, 0.070405 ); + M_static_table_v18_normal.emplace_back( 18.90, 18.915979, 0.070935 ); + M_static_table_v18_normal.emplace_back( 19.10, 19.058383, 0.071469 ); + M_static_table_v18_normal.emplace_back( 19.20, 19.201858, 0.072007 ); + M_static_table_v18_normal.emplace_back( 19.30, 19.346413, 0.072549 ); + M_static_table_v18_normal.emplace_back( 19.50, 19.492057, 0.073095 ); + M_static_table_v18_normal.emplace_back( 19.60, 19.638797, 0.073645 ); + M_static_table_v18_normal.emplace_back( 19.80, 19.786641, 0.074200 ); + M_static_table_v18_normal.emplace_back( 19.90, 19.935599, 0.074759 ); + M_static_table_v18_normal.emplace_back( 20.10, 20.085679, 0.075321 ); + M_static_table_v18_normal.emplace_back( 20.20, 20.236888, 0.075888 ); + M_static_table_v18_normal.emplace_back( 20.40, 20.389235, 0.076459 ); + M_static_table_v18_normal.emplace_back( 20.50, 20.542729, 0.077035 ); + M_static_table_v18_normal.emplace_back( 20.70, 20.697378, 0.077615 ); + M_static_table_v18_normal.emplace_back( 20.90, 20.853192, 0.078200 ); + M_static_table_v18_normal.emplace_back( 21.00, 21.010179, 0.078788 ); + M_static_table_v18_normal.emplace_back( 21.20, 21.168348, 0.079381 ); + M_static_table_v18_normal.emplace_back( 21.30, 21.327708, 0.079979 ); + M_static_table_v18_normal.emplace_back( 21.50, 21.488267, 0.080581 ); + M_static_table_v18_normal.emplace_back( 21.60, 21.650035, 0.081188 ); + M_static_table_v18_normal.emplace_back( 21.80, 21.813021, 0.081799 ); + M_static_table_v18_normal.emplace_back( 22.00, 21.977233, 0.082414 ); + M_static_table_v18_normal.emplace_back( 22.10, 22.142682, 0.083035 ); + M_static_table_v18_normal.emplace_back( 22.30, 22.309377, 0.083660 ); + M_static_table_v18_normal.emplace_back( 22.50, 22.477326, 0.084290 ); + M_static_table_v18_normal.emplace_back( 22.60, 22.646539, 0.084924 ); + M_static_table_v18_normal.emplace_back( 22.80, 22.817027, 0.085564 ); + M_static_table_v18_normal.emplace_back( 23.00, 22.988798, 0.086208 ); + M_static_table_v18_normal.emplace_back( 23.20, 23.161863, 0.086857 ); + M_static_table_v18_normal.emplace_back( 23.30, 23.336230, 0.087511 ); + M_static_table_v18_normal.emplace_back( 23.50, 23.511909, 0.088169 ); + M_static_table_v18_normal.emplace_back( 23.70, 23.688911, 0.088833 ); + M_static_table_v18_normal.emplace_back( 23.90, 23.867246, 0.089502 ); + M_static_table_v18_normal.emplace_back( 24.00, 24.046924, 0.090176 ); + M_static_table_v18_normal.emplace_back( 24.20, 24.227953, 0.090854 ); + M_static_table_v18_normal.emplace_back( 24.40, 24.410346, 0.091539 ); + M_static_table_v18_normal.emplace_back( 24.60, 24.594112, 0.092228 ); + M_static_table_v18_normal.emplace_back( 24.80, 24.779261, 0.092922 ); + M_static_table_v18_normal.emplace_back( 25.00, 24.965804, 0.093621 ); + M_static_table_v18_normal.emplace_back( 25.20, 25.153752, 0.094327 ); + M_static_table_v18_normal.emplace_back( 25.30, 25.343114, 0.095036 ); + M_static_table_v18_normal.emplace_back( 25.50, 25.533902, 0.095752 ); + M_static_table_v18_normal.emplace_back( 25.70, 25.726126, 0.096473 ); + M_static_table_v18_normal.emplace_back( 25.90, 25.919797, 0.097199 ); + M_static_table_v18_normal.emplace_back( 26.10, 26.114927, 0.097931 ); + M_static_table_v18_normal.emplace_back( 26.30, 26.311525, 0.098668 ); + M_static_table_v18_normal.emplace_back( 26.50, 26.509604, 0.099411 ); + M_static_table_v18_normal.emplace_back( 26.70, 26.709173, 0.100159 ); + M_static_table_v18_normal.emplace_back( 26.90, 26.910245, 0.100913 ); + M_static_table_v18_normal.emplace_back( 27.10, 27.112830, 0.101673 ); + M_static_table_v18_normal.emplace_back( 27.30, 27.316941, 0.102438 ); + M_static_table_v18_normal.emplace_back( 27.50, 27.522588, 0.103209 ); + M_static_table_v18_normal.emplace_back( 27.70, 27.729784, 0.103987 ); + M_static_table_v18_normal.emplace_back( 27.90, 27.938539, 0.104769 ); + M_static_table_v18_normal.emplace_back( 28.10, 28.148866, 0.105558 ); + M_static_table_v18_normal.emplace_back( 28.40, 28.360776, 0.106353 ); + M_static_table_v18_normal.emplace_back( 28.60, 28.574281, 0.107153 ); + M_static_table_v18_normal.emplace_back( 28.80, 28.789394, 0.107960 ); + M_static_table_v18_normal.emplace_back( 29.00, 29.006126, 0.108772 ); + M_static_table_v18_normal.emplace_back( 29.20, 29.224490, 0.109592 ); + M_static_table_v18_normal.emplace_back( 29.40, 29.444498, 0.110417 ); + M_static_table_v18_normal.emplace_back( 29.70, 29.666162, 0.111248 ); + M_static_table_v18_normal.emplace_back( 29.90, 29.889494, 0.112085 ); + M_static_table_v18_normal.emplace_back( 30.10, 30.114508, 0.112929 ); + M_static_table_v18_normal.emplace_back( 30.30, 30.341216, 0.113779 ); + M_static_table_v18_normal.emplace_back( 30.60, 30.569631, 0.114636 ); + M_static_table_v18_normal.emplace_back( 30.80, 30.799765, 0.115499 ); + M_static_table_v18_normal.emplace_back( 31.00, 31.031631, 0.116368 ); + M_static_table_v18_normal.emplace_back( 31.30, 31.265244, 0.117245 ); + M_static_table_v18_normal.emplace_back( 31.50, 31.500615, 0.118127 ); + M_static_table_v18_normal.emplace_back( 31.70, 31.737757, 0.119016 ); + M_static_table_v18_normal.emplace_back( 32.00, 31.976685, 0.119912 ); + M_static_table_v18_normal.emplace_back( 32.20, 32.217412, 0.120815 ); + M_static_table_v18_normal.emplace_back( 32.50, 32.459951, 0.121724 ); + M_static_table_v18_normal.emplace_back( 32.70, 32.704316, 0.122640 ); + M_static_table_v18_normal.emplace_back( 33.00, 32.950520, 0.123564 ); + M_static_table_v18_normal.emplace_back( 33.20, 33.198578, 0.124494 ); + M_static_table_v18_normal.emplace_back( 33.40, 33.448504, 0.125431 ); + M_static_table_v18_normal.emplace_back( 33.70, 33.700311, 0.126375 ); + M_static_table_v18_normal.emplace_back( 34.00, 33.954013, 0.127327 ); + M_static_table_v18_normal.emplace_back( 34.20, 34.209626, 0.128285 ); + M_static_table_v18_normal.emplace_back( 34.50, 34.467162, 0.129251 ); + M_static_table_v18_normal.emplace_back( 34.70, 34.726638, 0.130224 ); + M_static_table_v18_normal.emplace_back( 35.00, 34.988067, 0.131204 ); + M_static_table_v18_normal.emplace_back( 35.30, 35.251464, 0.132192 ); + M_static_table_v18_normal.emplace_back( 35.50, 35.516844, 0.133187 ); + M_static_table_v18_normal.emplace_back( 35.80, 35.784221, 0.134190 ); + M_static_table_v18_normal.emplace_back( 36.10, 36.053612, 0.135200 ); + M_static_table_v18_normal.emplace_back( 36.30, 36.325031, 0.136218 ); + M_static_table_v18_normal.emplace_back( 36.60, 36.598492, 0.137243 ); + M_static_table_v18_normal.emplace_back( 36.90, 36.874013, 0.138277 ); + M_static_table_v18_normal.emplace_back( 37.20, 37.151608, 0.139318 ); + M_static_table_v18_normal.emplace_back( 37.40, 37.431292, 0.140366 ); + M_static_table_v18_normal.emplace_back( 37.70, 37.713082, 0.141423 ); + M_static_table_v18_normal.emplace_back( 38.00, 37.996994, 0.142488 ); + M_static_table_v18_normal.emplace_back( 38.30, 38.283042, 0.143560 ); + M_static_table_v18_normal.emplace_back( 38.60, 38.571244, 0.144641 ); + M_static_table_v18_normal.emplace_back( 38.90, 38.861616, 0.145730 ); + M_static_table_v18_normal.emplace_back( 39.20, 39.154174, 0.146827 ); + M_static_table_v18_normal.emplace_back( 39.40, 39.448935, 0.147933 ); + M_static_table_v18_normal.emplace_back( 39.70, 39.745914, 0.149046 ); + M_static_table_v18_normal.emplace_back( 40.00, 40.045129, 0.150168 ); + M_static_table_v18_normal.emplace_back( 40.30, 40.346597, 0.151299 ); + M_static_table_v18_normal.emplace_back( 40.70, 40.650334, 0.152438 ); + M_static_table_v18_normal.emplace_back( 41.00, 40.956357, 0.153585 ); + M_static_table_v18_normal.emplace_back( 41.30, 41.264685, 0.154742 ); + M_static_table_v18_normal.emplace_back( 41.60, 41.575333, 0.155906 ); + M_static_table_v18_normal.emplace_back( 41.90, 41.888320, 0.157080 ); + M_static_table_v18_normal.emplace_back( 42.20, 42.203664, 0.158263 ); + M_static_table_v18_normal.emplace_back( 42.50, 42.521381, 0.159454 ); + M_static_table_v18_normal.emplace_back( 42.80, 42.841491, 0.160655 ); + M_static_table_v18_normal.emplace_back( 43.20, 43.164010, 0.161864 ); + M_static_table_v18_normal.emplace_back( 43.50, 43.488957, 0.163083 ); + M_static_table_v18_normal.emplace_back( 43.80, 43.816350, 0.164310 ); + M_static_table_v18_normal.emplace_back( 44.10, 44.146208, 0.165547 ); + M_static_table_v18_normal.emplace_back( 44.50, 44.478549, 0.166793 ); + M_static_table_v18_normal.emplace_back( 44.80, 44.813392, 0.168049 ); + M_static_table_v18_normal.emplace_back( 45.20, 45.150756, 0.169314 ); + M_static_table_v18_normal.emplace_back( 45.50, 45.490660, 0.170589 ); + M_static_table_v18_normal.emplace_back( 45.80, 45.833123, 0.171873 ); + M_static_table_v18_normal.emplace_back( 46.20, 46.178164, 0.173167 ); + M_static_table_v18_normal.emplace_back( 46.50, 46.525802, 0.174471 ); + M_static_table_v18_normal.emplace_back( 46.90, 46.876057, 0.175784 ); + M_static_table_v18_normal.emplace_back( 47.20, 47.228949, 0.177107 ); + M_static_table_v18_normal.emplace_back( 47.60, 47.584498, 0.178441 ); + M_static_table_v18_normal.emplace_back( 47.90, 47.942723, 0.179784 ); + M_static_table_v18_normal.emplace_back( 48.30, 48.303646, 0.181138 ); + M_static_table_v18_normal.emplace_back( 48.70, 48.667285, 0.182501 ); + M_static_table_v18_normal.emplace_back( 49.00, 49.033662, 0.183875 ); + M_static_table_v18_normal.emplace_back( 49.40, 49.402797, 0.185260 ); + M_static_table_v18_normal.emplace_back( 49.80, 49.774711, 0.186654 ); + M_static_table_v18_normal.emplace_back( 50.10, 50.149424, 0.188059 ); + M_static_table_v18_normal.emplace_back( 50.50, 50.526959, 0.189475 ); + M_static_table_v18_normal.emplace_back( 50.90, 50.907336, 0.190901 ); + M_static_table_v18_normal.emplace_back( 51.30, 51.290576, 0.192338 ); + M_static_table_v18_normal.emplace_back( 51.70, 51.676702, 0.193787 ); + M_static_table_v18_normal.emplace_back( 52.10, 52.065734, 0.195245 ); + M_static_table_v18_normal.emplace_back( 52.50, 52.457695, 0.196715 ); + M_static_table_v18_normal.emplace_back( 52.90, 52.852607, 0.198196 ); + M_static_table_v18_normal.emplace_back( 53.30, 53.250491, 0.199688 ); + M_static_table_v18_normal.emplace_back( 53.70, 53.651372, 0.201192 ); + M_static_table_v18_normal.emplace_back( 54.10, 54.055270, 0.202706 ); + M_static_table_v18_normal.emplace_back( 54.50, 54.462208, 0.204232 ); + M_static_table_v18_normal.emplace_back( 54.90, 54.872211, 0.205770 ); + M_static_table_v18_normal.emplace_back( 55.30, 55.285299, 0.207318 ); + M_static_table_v18_normal.emplace_back( 55.70, 55.701498, 0.208880 ); + M_static_table_v18_normal.emplace_back( 56.10, 56.120830, 0.210452 ); + M_static_table_v18_normal.emplace_back( 56.50, 56.543318, 0.212036 ); + M_static_table_v18_normal.emplace_back( 57.00, 56.968987, 0.213632 ); + M_static_table_v18_normal.emplace_back( 57.40, 57.397861, 0.215241 ); + M_static_table_v18_normal.emplace_back( 57.80, 57.829963, 0.216861 ); + M_static_table_v18_normal.emplace_back( 58.30, 58.265319, 0.218494 ); + M_static_table_v18_normal.emplace_back( 58.70, 58.703951, 0.220138 ); + M_static_table_v18_normal.emplace_back( 59.10, 59.145886, 0.221796 ); + M_static_table_v18_normal.emplace_back( 59.60, 59.591148, 0.223466 ); + M_static_table_v18_normal.emplace_back( 60.00, 60.039762, 0.225148 ); + M_static_table_v18_normal.emplace_back( 60.50, 60.491753, 0.226843 ); + M_static_table_v18_normal.emplace_back( 60.90, 60.947146, 0.228550 ); + M_static_table_v18_normal.emplace_back( 61.40, 61.405968, 0.230271 ); + M_static_table_v18_normal.emplace_back( 61.90, 61.868245, 0.232005 ); + M_static_table_v18_normal.emplace_back( 62.30, 62.334001, 0.233751 ); + M_static_table_v18_normal.emplace_back( 62.80, 62.803263, 0.235511 ); + M_static_table_v18_normal.emplace_back( 63.30, 63.276059, 0.237284 ); + M_static_table_v18_normal.emplace_back( 63.80, 63.752413, 0.239070 ); + M_static_table_v18_normal.emplace_back( 64.20, 64.232354, 0.240870 ); + M_static_table_v18_normal.emplace_back( 64.70, 64.715907, 0.242683 ); + M_static_table_v18_normal.emplace_back( 65.20, 65.203101, 0.244510 ); + M_static_table_v18_normal.emplace_back( 65.70, 65.693963, 0.246351 ); + M_static_table_v18_normal.emplace_back( 66.20, 66.188520, 0.248205 ); + M_static_table_v18_normal.emplace_back( 66.70, 66.686800, 0.250074 ); + M_static_table_v18_normal.emplace_back( 67.20, 67.188832, 0.251957 ); + M_static_table_v18_normal.emplace_back( 67.70, 67.694642, 0.253853 ); + M_static_table_v18_normal.emplace_back( 68.20, 68.204261, 0.255765 ); + M_static_table_v18_normal.emplace_back( 68.70, 68.717716, 0.257690 ); + M_static_table_v18_normal.emplace_back( 69.20, 69.235036, 0.259630 ); + M_static_table_v18_normal.emplace_back( 69.80, 69.756251, 0.261585 ); + M_static_table_v18_normal.emplace_back( 70.30, 70.281390, 0.263554 ); + M_static_table_v18_normal.emplace_back( 70.80, 70.810482, 0.265538 ); + M_static_table_v18_normal.emplace_back( 71.30, 71.343557, 0.267537 ); + M_static_table_v18_normal.emplace_back( 71.90, 71.880645, 0.269551 ); + M_static_table_v18_normal.emplace_back( 72.40, 72.421776, 0.271580 ); + M_static_table_v18_normal.emplace_back( 73.00, 72.966982, 0.273625 ); + M_static_table_v18_normal.emplace_back( 73.50, 73.516292, 0.275685 ); + M_static_table_v18_normal.emplace_back( 74.10, 74.069737, 0.277760 ); + M_static_table_v18_normal.emplace_back( 74.60, 74.627348, 0.279851 ); + M_static_table_v18_normal.emplace_back( 75.20, 75.189158, 0.281958 ); + M_static_table_v18_normal.emplace_back( 75.80, 75.755196, 0.284080 ); + M_static_table_v18_normal.emplace_back( 76.30, 76.325496, 0.286219 ); + M_static_table_v18_normal.emplace_back( 76.90, 76.900089, 0.288374 ); + M_static_table_v18_normal.emplace_back( 77.50, 77.479008, 0.290545 ); + M_static_table_v18_normal.emplace_back( 78.10, 78.062285, 0.292732 ); + M_static_table_v18_normal.emplace_back( 78.60, 78.649953, 0.294935 ); + M_static_table_v18_normal.emplace_back( 79.20, 79.242045, 0.297156 ); + M_static_table_v18_normal.emplace_back( 79.80, 79.838595, 0.299393 ); + M_static_table_v18_normal.emplace_back( 80.40, 80.439636, 0.301647 ); + M_static_table_v18_normal.emplace_back( 81.00, 81.045201, 0.303918 ); + M_static_table_v18_normal.emplace_back( 81.70, 81.655325, 0.306206 ); + M_static_table_v18_normal.emplace_back( 82.30, 82.270042, 0.308511 ); + M_static_table_v18_normal.emplace_back( 82.90, 82.889387, 0.310833 ); + M_static_table_v18_normal.emplace_back( 83.50, 83.513395, 0.313174 ); + M_static_table_v18_normal.emplace_back( 84.10, 84.142100, 0.315531 ); + M_static_table_v18_normal.emplace_back( 84.80, 84.775538, 0.317906 ); + M_static_table_v18_normal.emplace_back( 85.40, 85.413745, 0.320300 ); + M_static_table_v18_normal.emplace_back( 86.10, 86.056756, 0.322711 ); + M_static_table_v18_normal.emplace_back( 86.70, 86.704608, 0.325140 ); + M_static_table_v18_normal.emplace_back( 87.40, 87.357337, 0.327588 ); + M_static_table_v18_normal.emplace_back( 88.00, 88.014981, 0.330055 ); + M_static_table_v18_normal.emplace_back( 88.70, 88.677575, 0.332539 ); + M_static_table_v18_normal.emplace_back( 89.30, 89.345157, 0.335043 ); + M_static_table_v18_normal.emplace_back( 90.00, 90.017765, 0.337565 ); + M_static_table_v18_normal.emplace_back( 90.70, 90.695436, 0.340106 ); + M_static_table_v18_normal.emplace_back( 91.40, 91.378209, 0.342667 ); + M_static_table_v18_normal.emplace_back( 92.10, 92.066122, 0.345246 ); + M_static_table_v18_normal.emplace_back( 92.80, 92.759214, 0.347845 ); + M_static_table_v18_normal.emplace_back( 93.50, 93.457523, 0.350464 ); + M_static_table_v18_normal.emplace_back( 94.20, 94.161089, 0.353102 ); + M_static_table_v18_normal.emplace_back( 94.90, 94.869953, 0.355761 ); + M_static_table_v18_normal.emplace_back( 95.60, 95.584152, 0.358438 ); + M_static_table_v18_normal.emplace_back( 96.30, 96.303728, 0.361137 ); + M_static_table_v18_normal.emplace_back( 97.00, 97.028722, 0.363856 ); + M_static_table_v18_normal.emplace_back( 97.80, 97.759173, 0.366595 ); + M_static_table_v18_normal.emplace_back( 98.50, 98.495123, 0.369355 ); + M_static_table_v18_normal.emplace_back( 99.20, 99.236613, 0.372135 ); + M_static_table_v18_normal.emplace_back( 100.00, 99.983686, 0.374937 ); + M_static_table_v18_normal.emplace_back( 100.70, 100.736383, 0.377759 ); + M_static_table_v18_normal.emplace_back( 101.50, 101.494746, 0.380603 ); + M_static_table_v18_normal.emplace_back( 102.30, 102.258818, 0.383468 ); + M_static_table_v18_normal.emplace_back( 103.00, 103.028643, 0.386356 ); + M_static_table_v18_normal.emplace_back( 103.80, 103.804263, 0.389264 ); + M_static_table_v18_normal.emplace_back( 104.60, 104.585721, 0.392194 ); + M_static_table_v18_normal.emplace_back( 105.40, 105.373063, 0.395147 ); + M_static_table_v18_normal.emplace_back( 106.20, 106.166332, 0.398122 ); + M_static_table_v18_normal.emplace_back( 107.00, 106.965573, 0.401119 ); + M_static_table_v18_normal.emplace_back( 107.80, 107.770831, 0.404139 ); + M_static_table_v18_normal.emplace_back( 108.60, 108.582151, 0.407181 ); + M_static_table_v18_normal.emplace_back( 109.40, 109.399578, 0.410246 ); + M_static_table_v18_normal.emplace_back( 110.20, 110.223160, 0.413335 ); + M_static_table_v18_normal.emplace_back( 111.10, 111.052941, 0.416446 ); + M_static_table_v18_normal.emplace_back( 111.90, 111.888969, 0.419581 ); + M_static_table_v18_normal.emplace_back( 112.70, 112.731291, 0.422740 ); + M_static_table_v18_normal.emplace_back( 113.60, 113.579955, 0.425923 ); + M_static_table_v18_normal.emplace_back( 114.40, 114.435007, 0.429129 ); + M_static_table_v18_normal.emplace_back( 115.30, 115.296496, 0.432360 ); + M_static_table_v18_normal.emplace_back( 116.20, 116.164470, 0.435614 ); + M_static_table_v18_normal.emplace_back( 117.00, 117.038979, 0.438894 ); + M_static_table_v18_normal.emplace_back( 117.90, 117.920072, 0.442198 ); + M_static_table_v18_normal.emplace_back( 118.80, 118.807797, 0.445527 ); + M_static_table_v18_normal.emplace_back( 119.70, 119.702205, 0.448881 ); + M_static_table_v18_normal.emplace_back( 120.60, 120.603347, 0.452260 ); + M_static_table_v18_normal.emplace_back( 121.50, 121.511272, 0.455665 ); + M_static_table_v18_normal.emplace_back( 122.40, 122.426033, 0.459095 ); + M_static_table_v18_normal.emplace_back( 123.30, 123.347680, 0.462551 ); + M_static_table_v18_normal.emplace_back( 124.30, 124.276266, 0.466034 ); + M_static_table_v18_normal.emplace_back( 125.20, 125.211842, 0.469542 ); + M_static_table_v18_normal.emplace_back( 126.20, 126.154461, 0.473077 ); + M_static_table_v18_normal.emplace_back( 127.10, 127.104176, 0.476638 ); + M_static_table_v18_normal.emplace_back( 128.10, 128.061041, 0.480226 ); + M_static_table_v18_normal.emplace_back( 129.00, 129.025110, 0.483842 ); + M_static_table_v18_normal.emplace_back( 130.00, 129.996436, 0.487484 ); + M_static_table_v18_normal.emplace_back( 131.00, 130.975075, 0.491154 ); + M_static_table_v18_normal.emplace_back( 132.00, 131.961081, 0.494852 ); + M_static_table_v18_normal.emplace_back( 133.00, 132.954510, 0.498577 ); + M_static_table_v18_normal.emplace_back( 134.00, 133.955417, 0.502330 ); + M_static_table_v18_normal.emplace_back( 135.00, 134.963860, 0.506112 ); + M_static_table_v18_normal.emplace_back( 136.00, 135.979894, 0.509922 ); + M_static_table_v18_normal.emplace_back( 137.00, 137.003577, 0.513761 ); + M_static_table_v18_normal.emplace_back( 138.00, 138.034967, 0.517629 ); + M_static_table_v18_normal.emplace_back( 139.10, 139.074121, 0.521525 ); + M_static_table_v18_normal.emplace_back( 140.10, 140.121098, 0.525451 ); + M_static_table_v18_normal.emplace_back( 141.20, 141.175957, 0.529407 ); + M_static_table_v18_normal.emplace_back( 142.20, 142.238757, 0.533392 ); + M_static_table_v18_normal.emplace_back( 143.30, 143.309558, 0.537408 ); + M_static_table_v18_normal.emplace_back( 144.40, 144.388421, 0.541454 ); + M_static_table_v18_normal.emplace_back( 145.50, 145.475405, 0.545530 ); + M_static_table_v18_normal.emplace_back( 146.60, 146.570573, 0.549637 ); + M_static_table_v18_normal.emplace_back( 147.70, 147.673984, 0.553774 ); + M_static_table_v18_normal.emplace_back( 148.80, 148.785703, 0.557944 ); + M_static_table_v18_normal.emplace_back( 149.90, 149.905791, 0.562144 ); + M_static_table_v18_normal.emplace_back( 151.00, 151.034311, 0.566376 ); + M_static_table_v18_normal.emplace_back( 152.20, 152.171327, 0.570640 ); + + // + M_static_table_v18_wide.emplace_back( 0.00, 0.025019, 0.025019 ); + M_static_table_v18_wide.emplace_back( 0.10, 0.100178, 0.050141 ); + M_static_table_v18_wide.emplace_back( 0.20, 0.200322, 0.050003 ); + M_static_table_v18_wide.emplace_back( 0.30, 0.301008, 0.050684 ); + M_static_table_v18_wide.emplace_back( 0.40, 0.401637, 0.049945 ); + M_static_table_v18_wide.emplace_back( 0.50, 0.501572, 0.049991 ); + M_static_table_v18_wide.emplace_back( 0.60, 0.599414, 0.047851 ); + M_static_table_v18_wide.emplace_back( 0.70, 0.699640, 0.052375 ); + M_static_table_v18_wide.emplace_back( 0.80, 0.799955, 0.047940 ); + M_static_table_v18_wide.emplace_back( 0.90, 0.897190, 0.049296 ); + M_static_table_v18_wide.emplace_back( 1.00, 0.996257, 0.049771 ); + M_static_table_v18_wide.emplace_back( 1.10, 1.095283, 0.049254 ); + M_static_table_v18_wide.emplace_back( 1.20, 1.198430, 0.053893 ); + M_static_table_v18_wide.emplace_back( 1.30, 1.304474, 0.052151 ); + M_static_table_v18_wide.emplace_back( 1.40, 1.405809, 0.049183 ); + M_static_table_v18_wide.emplace_back( 1.50, 1.499978, 0.044986 ); + M_static_table_v18_wide.emplace_back( 1.60, 1.600975, 0.056011 ); + M_static_table_v18_wide.emplace_back( 1.70, 1.699463, 0.042477 ); + M_static_table_v18_wide.emplace_back( 1.80, 1.795799, 0.053858 ); + M_static_table_v18_wide.emplace_back( 1.90, 1.897074, 0.047417 ); + M_static_table_v18_wide.emplace_back( 2.00, 1.994339, 0.049848 ); + M_static_table_v18_wide.emplace_back( 2.10, 2.096591, 0.052404 ); + M_static_table_v18_wide.emplace_back( 2.20, 2.204085, 0.055091 ); + M_static_table_v18_wide.emplace_back( 2.30, 2.305275, 0.046100 ); + M_static_table_v18_wide.emplace_back( 2.40, 2.399355, 0.047981 ); + M_static_table_v18_wide.emplace_back( 2.50, 2.497275, 0.049939 ); + M_static_table_v18_wide.emplace_back( 2.60, 2.599191, 0.051977 ); + M_static_table_v18_wide.emplace_back( 2.70, 2.705266, 0.054098 ); + M_static_table_v18_wide.emplace_back( 2.80, 2.801382, 0.042018 ); + M_static_table_v18_wide.emplace_back( 2.90, 2.901420, 0.058021 ); + M_static_table_v18_wide.emplace_back( 3.00, 3.004505, 0.045065 ); + M_static_table_v18_wide.emplace_back( 3.10, 3.096006, 0.046437 ); + M_static_table_v18_wide.emplace_back( 3.20, 3.190293, 0.047851 ); + M_static_table_v18_wide.emplace_back( 3.30, 3.287452, 0.049309 ); + M_static_table_v18_wide.emplace_back( 3.40, 3.387570, 0.050810 ); + M_static_table_v18_wide.emplace_back( 3.50, 3.490736, 0.052357 ); + M_static_table_v18_wide.emplace_back( 3.60, 3.597045, 0.053952 ); + M_static_table_v18_wide.emplace_back( 3.70, 3.706591, 0.055595 ); + M_static_table_v18_wide.emplace_back( 3.80, 3.800187, 0.038001 ); + M_static_table_v18_wide.emplace_back( 3.90, 3.896632, 0.058445 ); + M_static_table_v18_wide.emplace_back( 4.00, 3.995026, 0.039949 ); + M_static_table_v18_wide.emplace_back( 4.10, 4.096417, 0.061442 ); + M_static_table_v18_wide.emplace_back( 4.20, 4.199856, 0.041998 ); + M_static_table_v18_wide.emplace_back( 4.30, 4.306445, 0.064592 ); + M_static_table_v18_wide.emplace_back( 4.40, 4.415187, 0.044151 ); + M_static_table_v18_wide.emplace_back( 4.50, 4.504380, 0.045043 ); + M_static_table_v18_wide.emplace_back( 4.60, 4.595374, 0.045952 ); + M_static_table_v18_wide.emplace_back( 4.70, 4.688207, 0.046881 ); + M_static_table_v18_wide.emplace_back( 4.80, 4.782915, 0.047828 ); + M_static_table_v18_wide.emplace_back( 4.90, 4.879536, 0.048794 ); + M_static_table_v18_wide.emplace_back( 5.00, 4.978109, 0.049779 ); + M_static_table_v18_wide.emplace_back( 5.10, 5.078673, 0.050785 ); + M_static_table_v18_wide.emplace_back( 5.20, 5.181269, 0.051811 ); + M_static_table_v18_wide.emplace_back( 5.30, 5.285938, 0.052858 ); + M_static_table_v18_wide.emplace_back( 5.40, 5.392721, 0.053925 ); + M_static_table_v18_wide.emplace_back( 5.50, 5.501661, 0.055015 ); + M_static_table_v18_wide.emplace_back( 5.60, 5.612802, 0.056126 ); + M_static_table_v18_wide.emplace_back( 5.70, 5.697415, 0.028487 ); + M_static_table_v18_wide.emplace_back( 5.80, 5.783738, 0.057836 ); + M_static_table_v18_wide.emplace_back( 5.90, 5.900577, 0.059004 ); + M_static_table_v18_wide.emplace_back( 6.00, 6.019776, 0.060196 ); + M_static_table_v18_wide.emplace_back( 6.10, 6.110525, 0.030553 ); + M_static_table_v18_wide.emplace_back( 6.20, 6.203106, 0.062029 ); + M_static_table_v18_wide.emplace_back( 6.30, 6.296618, 0.031483 ); + M_static_table_v18_wide.emplace_back( 6.40, 6.392018, 0.063918 ); + M_static_table_v18_wide.emplace_back( 6.50, 6.488378, 0.032442 ); + M_static_table_v18_wide.emplace_back( 6.60, 6.586685, 0.065865 ); + M_static_table_v18_wide.emplace_back( 6.70, 6.685979, 0.033430 ); + M_static_table_v18_wide.emplace_back( 6.80, 6.787279, 0.067871 ); + M_static_table_v18_wide.emplace_back( 6.90, 6.889597, 0.034448 ); + M_static_table_v18_wide.emplace_back( 7.00, 6.993983, 0.069938 ); + M_static_table_v18_wide.emplace_back( 7.10, 7.099417, 0.035497 ); + M_static_table_v18_wide.emplace_back( 7.20, 7.206981, 0.072068 ); + M_static_table_v18_wide.emplace_back( 7.30, 7.315626, 0.036578 ); + M_static_table_v18_wide.emplace_back( 7.40, 7.389149, 0.036945 ); + M_static_table_v18_wide.emplace_back( 7.50, 7.501103, 0.075009 ); + M_static_table_v18_wide.emplace_back( 7.60, 7.614182, 0.038071 ); + M_static_table_v18_wide.emplace_back( 7.70, 7.690706, 0.038453 ); + M_static_table_v18_wide.emplace_back( 7.80, 7.807229, 0.078070 ); + M_static_table_v18_wide.emplace_back( 7.90, 7.924923, 0.039625 ); + M_static_table_v18_wide.emplace_back( 8.00, 8.004570, 0.040022 ); + M_static_table_v18_wide.emplace_back( 8.10, 8.085017, 0.040424 ); + M_static_table_v18_wide.emplace_back( 8.20, 8.207514, 0.082072 ); + M_static_table_v18_wide.emplace_back( 8.30, 8.331242, 0.041656 ); + M_static_table_v18_wide.emplace_back( 8.40, 8.414973, 0.042074 ); + M_static_table_v18_wide.emplace_back( 8.50, 8.499545, 0.042497 ); + M_static_table_v18_wide.emplace_back( 8.60, 8.584967, 0.042924 ); + M_static_table_v18_wide.emplace_back( 8.70, 8.671247, 0.043355 ); + M_static_table_v18_wide.emplace_back( 8.80, 8.802626, 0.088023 ); + M_static_table_v18_wide.emplace_back( 8.90, 8.935326, 0.044676 ); + M_static_table_v18_wide.emplace_back( 9.00, 9.025127, 0.045125 ); + M_static_table_v18_wide.emplace_back( 9.10, 9.115831, 0.045579 ); + M_static_table_v18_wide.emplace_back( 9.20, 9.207446, 0.046036 ); + M_static_table_v18_wide.emplace_back( 9.30, 9.299982, 0.046499 ); + M_static_table_v18_wide.emplace_back( 9.40, 9.393449, 0.046967 ); + M_static_table_v18_wide.emplace_back( 9.50, 9.487855, 0.047439 ); + M_static_table_v18_wide.emplace_back( 9.60, 9.583209, 0.047915 ); + M_static_table_v18_wide.emplace_back( 9.70, 9.679522, 0.048397 ); + M_static_table_v18_wide.emplace_back( 9.80, 9.776803, 0.048883 ); + M_static_table_v18_wide.emplace_back( 9.90, 9.875062, 0.049375 ); + M_static_table_v18_wide.emplace_back( 10.00, 9.974308, 0.049871 ); + M_static_table_v18_wide.emplace_back( 10.10, 10.074551, 0.050372 ); + M_static_table_v18_wide.emplace_back( 10.20, 10.175802, 0.050879 ); + M_static_table_v18_wide.emplace_back( 10.30, 10.278070, 0.051389 ); + M_static_table_v18_wide.emplace_back( 10.40, 10.381366, 0.051906 ); + M_static_table_v18_wide.emplace_back( 10.50, 10.485701, 0.052428 ); + M_static_table_v18_wide.emplace_back( 10.60, 10.591084, 0.052955 ); + M_static_table_v18_wide.emplace_back( 10.70, 10.697526, 0.053487 ); + M_static_table_v18_wide.emplace_back( 10.80, 10.805038, 0.054024 ); + M_static_table_v18_wide.emplace_back( 10.90, 10.913631, 0.054568 ); + M_static_table_v18_wide.emplace_back( 11.00, 11.023315, 0.055116 ); + M_static_table_v18_wide.emplace_back( 11.10, 11.134101, 0.055670 ); + M_static_table_v18_wide.emplace_back( 11.20, 11.246000, 0.056229 ); + M_static_table_v18_wide.emplace_back( 11.40, 11.359024, 0.056794 ); + M_static_table_v18_wide.emplace_back( 11.50, 11.473184, 0.057365 ); + M_static_table_v18_wide.emplace_back( 11.60, 11.588492, 0.057942 ); + M_static_table_v18_wide.emplace_back( 11.70, 11.704958, 0.058524 ); + M_static_table_v18_wide.emplace_back( 11.80, 11.822595, 0.059112 ); + M_static_table_v18_wide.emplace_back( 11.90, 11.941414, 0.059706 ); + M_static_table_v18_wide.emplace_back( 12.10, 12.061427, 0.060306 ); + M_static_table_v18_wide.emplace_back( 12.20, 12.182646, 0.060912 ); + M_static_table_v18_wide.emplace_back( 12.30, 12.305084, 0.061525 ); + M_static_table_v18_wide.emplace_back( 12.40, 12.428752, 0.062143 ); + M_static_table_v18_wide.emplace_back( 12.60, 12.553663, 0.062767 ); + M_static_table_v18_wide.emplace_back( 12.70, 12.679830, 0.063399 ); + M_static_table_v18_wide.emplace_back( 12.80, 12.807264, 0.064035 ); + M_static_table_v18_wide.emplace_back( 12.90, 12.935979, 0.064679 ); + M_static_table_v18_wide.emplace_back( 13.10, 13.065988, 0.065329 ); + M_static_table_v18_wide.emplace_back( 13.20, 13.197304, 0.065986 ); + M_static_table_v18_wide.emplace_back( 13.30, 13.329939, 0.066649 ); + M_static_table_v18_wide.emplace_back( 13.50, 13.463907, 0.067319 ); + M_static_table_v18_wide.emplace_back( 13.60, 13.599221, 0.067995 ); + M_static_table_v18_wide.emplace_back( 13.70, 13.735896, 0.068679 ); + M_static_table_v18_wide.emplace_back( 13.90, 13.873944, 0.069369 ); + M_static_table_v18_wide.emplace_back( 14.00, 14.013379, 0.070066 ); + M_static_table_v18_wide.emplace_back( 14.20, 14.154216, 0.070770 ); + M_static_table_v18_wide.emplace_back( 14.30, 14.296468, 0.071481 ); + M_static_table_v18_wide.emplace_back( 14.40, 14.440150, 0.072200 ); + M_static_table_v18_wide.emplace_back( 14.60, 14.585276, 0.072926 ); + M_static_table_v18_wide.emplace_back( 14.70, 14.731860, 0.073658 ); + M_static_table_v18_wide.emplace_back( 14.90, 14.879918, 0.074399 ); + M_static_table_v18_wide.emplace_back( 15.00, 15.029464, 0.075147 ); + M_static_table_v18_wide.emplace_back( 15.20, 15.180512, 0.075901 ); + M_static_table_v18_wide.emplace_back( 15.30, 15.333079, 0.076665 ); + M_static_table_v18_wide.emplace_back( 15.50, 15.487179, 0.077435 ); + M_static_table_v18_wide.emplace_back( 15.60, 15.642827, 0.078213 ); + M_static_table_v18_wide.emplace_back( 15.80, 15.800040, 0.078999 ); + M_static_table_v18_wide.emplace_back( 16.00, 15.958834, 0.079794 ); + M_static_table_v18_wide.emplace_back( 16.10, 16.119223, 0.080595 ); + M_static_table_v18_wide.emplace_back( 16.30, 16.281223, 0.081406 ); + M_static_table_v18_wide.emplace_back( 16.40, 16.444852, 0.082224 ); + M_static_table_v18_wide.emplace_back( 16.60, 16.610126, 0.083050 ); + M_static_table_v18_wide.emplace_back( 16.80, 16.777060, 0.083885 ); + M_static_table_v18_wide.emplace_back( 16.90, 16.945673, 0.084728 ); + M_static_table_v18_wide.emplace_back( 17.10, 17.115980, 0.085579 ); + M_static_table_v18_wide.emplace_back( 17.30, 17.287998, 0.086440 ); + M_static_table_v18_wide.emplace_back( 17.50, 17.461746, 0.087308 ); + M_static_table_v18_wide.emplace_back( 17.60, 17.637239, 0.088186 ); + M_static_table_v18_wide.emplace_back( 17.80, 17.814496, 0.089072 ); + M_static_table_v18_wide.emplace_back( 18.00, 17.993535, 0.089967 ); + M_static_table_v18_wide.emplace_back( 18.20, 18.174373, 0.090871 ); + M_static_table_v18_wide.emplace_back( 18.40, 18.357028, 0.091785 ); + M_static_table_v18_wide.emplace_back( 18.50, 18.541520, 0.092707 ); + M_static_table_v18_wide.emplace_back( 18.70, 18.727865, 0.093639 ); + M_static_table_v18_wide.emplace_back( 18.90, 18.916083, 0.094580 ); + M_static_table_v18_wide.emplace_back( 19.10, 19.106193, 0.095530 ); + M_static_table_v18_wide.emplace_back( 19.30, 19.298213, 0.096491 ); + M_static_table_v18_wide.emplace_back( 19.50, 19.492164, 0.097460 ); + M_static_table_v18_wide.emplace_back( 19.70, 19.688063, 0.098440 ); + M_static_table_v18_wide.emplace_back( 19.90, 19.885931, 0.099429 ); + M_static_table_v18_wide.emplace_back( 20.10, 20.085788, 0.100429 ); + M_static_table_v18_wide.emplace_back( 20.30, 20.287654, 0.101437 ); + M_static_table_v18_wide.emplace_back( 20.50, 20.491548, 0.102457 ); + M_static_table_v18_wide.emplace_back( 20.70, 20.697491, 0.103487 ); + M_static_table_v18_wide.emplace_back( 20.90, 20.905505, 0.104527 ); + M_static_table_v18_wide.emplace_back( 21.10, 21.115609, 0.105577 ); + M_static_table_v18_wide.emplace_back( 21.30, 21.327824, 0.106638 ); + M_static_table_v18_wide.emplace_back( 21.50, 21.542172, 0.107710 ); + M_static_table_v18_wide.emplace_back( 21.80, 21.758675, 0.108793 ); + M_static_table_v18_wide.emplace_back( 22.00, 21.977353, 0.109886 ); + M_static_table_v18_wide.emplace_back( 22.20, 22.198229, 0.110990 ); + M_static_table_v18_wide.emplace_back( 22.40, 22.421325, 0.112106 ); + M_static_table_v18_wide.emplace_back( 22.60, 22.646664, 0.113233 ); + M_static_table_v18_wide.emplace_back( 22.90, 22.874266, 0.114370 ); + M_static_table_v18_wide.emplace_back( 23.10, 23.104156, 0.115520 ); + M_static_table_v18_wide.emplace_back( 23.30, 23.336357, 0.116681 ); + M_static_table_v18_wide.emplace_back( 23.60, 23.570892, 0.117854 ); + M_static_table_v18_wide.emplace_back( 23.80, 23.807783, 0.119038 ); + M_static_table_v18_wide.emplace_back( 24.00, 24.047055, 0.120235 ); + M_static_table_v18_wide.emplace_back( 24.30, 24.288732, 0.121443 ); + M_static_table_v18_wide.emplace_back( 24.50, 24.532838, 0.122664 ); + M_static_table_v18_wide.emplace_back( 24.80, 24.779397, 0.123896 ); + M_static_table_v18_wide.emplace_back( 25.00, 25.028434, 0.125142 ); + M_static_table_v18_wide.emplace_back( 25.30, 25.279974, 0.126399 ); + M_static_table_v18_wide.emplace_back( 25.50, 25.534042, 0.127670 ); + M_static_table_v18_wide.emplace_back( 25.80, 25.790663, 0.128952 ); + M_static_table_v18_wide.emplace_back( 26.00, 26.049863, 0.130248 ); + M_static_table_v18_wide.emplace_back( 26.30, 26.311669, 0.131558 ); + M_static_table_v18_wide.emplace_back( 26.60, 26.576106, 0.132880 ); + M_static_table_v18_wide.emplace_back( 26.80, 26.843200, 0.134215 ); + M_static_table_v18_wide.emplace_back( 27.10, 27.112979, 0.135564 ); + M_static_table_v18_wide.emplace_back( 27.40, 27.385468, 0.136926 ); + M_static_table_v18_wide.emplace_back( 27.70, 27.660697, 0.138303 ); + M_static_table_v18_wide.emplace_back( 27.90, 27.938692, 0.139693 ); + M_static_table_v18_wide.emplace_back( 28.20, 28.219480, 0.141096 ); + M_static_table_v18_wide.emplace_back( 28.50, 28.503091, 0.142515 ); + M_static_table_v18_wide.emplace_back( 28.80, 28.789552, 0.143947 ); + M_static_table_v18_wide.emplace_back( 29.10, 29.078891, 0.145393 ); + M_static_table_v18_wide.emplace_back( 29.40, 29.371139, 0.146855 ); + M_static_table_v18_wide.emplace_back( 29.70, 29.666324, 0.148331 ); + M_static_table_v18_wide.emplace_back( 30.00, 29.964475, 0.149821 ); + M_static_table_v18_wide.emplace_back( 30.30, 30.265623, 0.151327 ); + M_static_table_v18_wide.emplace_back( 30.60, 30.569798, 0.152848 ); + M_static_table_v18_wide.emplace_back( 30.90, 30.877029, 0.154384 ); + M_static_table_v18_wide.emplace_back( 31.20, 31.187349, 0.155936 ); + M_static_table_v18_wide.emplace_back( 31.50, 31.500787, 0.157503 ); + M_static_table_v18_wide.emplace_back( 31.80, 31.817375, 0.159086 ); + M_static_table_v18_wide.emplace_back( 32.10, 32.137145, 0.160684 ); + M_static_table_v18_wide.emplace_back( 32.50, 32.460129, 0.162299 ); + M_static_table_v18_wide.emplace_back( 32.80, 32.786358, 0.163930 ); + M_static_table_v18_wide.emplace_back( 33.10, 33.115866, 0.165578 ); + M_static_table_v18_wide.emplace_back( 33.40, 33.448686, 0.167242 ); + M_static_table_v18_wide.emplace_back( 33.80, 33.784851, 0.168923 ); + M_static_table_v18_wide.emplace_back( 34.10, 34.124395, 0.170620 ); + M_static_table_v18_wide.emplace_back( 34.50, 34.467351, 0.172335 ); + M_static_table_v18_wide.emplace_back( 34.80, 34.813753, 0.174067 ); + M_static_table_v18_wide.emplace_back( 35.20, 35.163637, 0.175817 ); + M_static_table_v18_wide.emplace_back( 35.50, 35.517038, 0.177583 ); + M_static_table_v18_wide.emplace_back( 35.90, 35.873990, 0.179368 ); + M_static_table_v18_wide.emplace_back( 36.20, 36.234529, 0.181171 ); + M_static_table_v18_wide.emplace_back( 36.60, 36.598692, 0.182992 ); + M_static_table_v18_wide.emplace_back( 37.00, 36.966515, 0.184831 ); + M_static_table_v18_wide.emplace_back( 37.30, 37.338035, 0.186689 ); + M_static_table_v18_wide.emplace_back( 37.70, 37.713288, 0.188564 ); + M_static_table_v18_wide.emplace_back( 38.10, 38.092313, 0.190460 ); + M_static_table_v18_wide.emplace_back( 38.50, 38.475147, 0.192374 ); + M_static_table_v18_wide.emplace_back( 38.90, 38.861829, 0.194307 ); + M_static_table_v18_wide.emplace_back( 39.30, 39.252397, 0.196260 ); + M_static_table_v18_wide.emplace_back( 39.60, 39.646890, 0.198233 ); + M_static_table_v18_wide.emplace_back( 40.00, 40.045348, 0.200225 ); + M_static_table_v18_wide.emplace_back( 40.40, 40.447810, 0.202237 ); + M_static_table_v18_wide.emplace_back( 40.90, 40.854318, 0.204270 ); + M_static_table_v18_wide.emplace_back( 41.30, 41.264910, 0.206322 ); + M_static_table_v18_wide.emplace_back( 41.70, 41.679629, 0.208396 ); + M_static_table_v18_wide.emplace_back( 42.10, 42.098517, 0.210491 ); + M_static_table_v18_wide.emplace_back( 42.50, 42.521614, 0.212606 ); + M_static_table_v18_wide.emplace_back( 42.90, 42.948963, 0.214743 ); + M_static_table_v18_wide.emplace_back( 43.40, 43.380607, 0.216901 ); + M_static_table_v18_wide.emplace_back( 43.80, 43.816590, 0.219081 ); + M_static_table_v18_wide.emplace_back( 44.30, 44.256954, 0.221283 ); + M_static_table_v18_wide.emplace_back( 44.70, 44.701744, 0.223507 ); + M_static_table_v18_wide.emplace_back( 45.20, 45.151004, 0.225753 ); + M_static_table_v18_wide.emplace_back( 45.60, 45.604779, 0.228022 ); + M_static_table_v18_wide.emplace_back( 46.10, 46.063114, 0.230313 ); + M_static_table_v18_wide.emplace_back( 46.50, 46.526056, 0.232628 ); + M_static_table_v18_wide.emplace_back( 47.00, 46.993651, 0.234966 ); + M_static_table_v18_wide.emplace_back( 47.50, 47.465945, 0.237328 ); + M_static_table_v18_wide.emplace_back( 47.90, 47.942986, 0.239713 ); + M_static_table_v18_wide.emplace_back( 48.40, 48.424821, 0.242122 ); + M_static_table_v18_wide.emplace_back( 48.90, 48.911498, 0.244555 ); + M_static_table_v18_wide.emplace_back( 49.40, 49.403067, 0.247013 ); + M_static_table_v18_wide.emplace_back( 49.90, 49.899576, 0.249496 ); + M_static_table_v18_wide.emplace_back( 50.40, 50.401075, 0.252003 ); + M_static_table_v18_wide.emplace_back( 50.90, 50.907614, 0.254535 ); + M_static_table_v18_wide.emplace_back( 51.40, 51.419244, 0.257094 ); + M_static_table_v18_wide.emplace_back( 51.90, 51.936016, 0.259677 ); + M_static_table_v18_wide.emplace_back( 52.50, 52.457982, 0.262288 ); + M_static_table_v18_wide.emplace_back( 53.00, 52.985193, 0.264923 ); + M_static_table_v18_wide.emplace_back( 53.50, 53.517703, 0.267586 ); + M_static_table_v18_wide.emplace_back( 54.10, 54.055565, 0.270275 ); + M_static_table_v18_wide.emplace_back( 54.60, 54.598833, 0.272992 ); + M_static_table_v18_wide.emplace_back( 55.10, 55.147560, 0.275735 ); + M_static_table_v18_wide.emplace_back( 55.70, 55.701802, 0.278506 ); + M_static_table_v18_wide.emplace_back( 56.30, 56.261615, 0.281306 ); + M_static_table_v18_wide.emplace_back( 56.80, 56.827054, 0.284133 ); + M_static_table_v18_wide.emplace_back( 57.40, 57.398175, 0.286988 ); + M_static_table_v18_wide.emplace_back( 58.00, 57.975036, 0.289872 ); + M_static_table_v18_wide.emplace_back( 58.60, 58.557695, 0.292786 ); + M_static_table_v18_wide.emplace_back( 59.10, 59.146209, 0.295728 ); + M_static_table_v18_wide.emplace_back( 59.70, 59.740639, 0.298701 ); + M_static_table_v18_wide.emplace_back( 60.30, 60.341042, 0.301702 ); + M_static_table_v18_wide.emplace_back( 60.90, 60.947480, 0.304735 ); + M_static_table_v18_wide.emplace_back( 61.60, 61.560012, 0.307797 ); + M_static_table_v18_wide.emplace_back( 62.20, 62.178701, 0.310891 ); + M_static_table_v18_wide.emplace_back( 62.80, 62.803607, 0.314015 ); + M_static_table_v18_wide.emplace_back( 63.40, 63.434793, 0.317171 ); + M_static_table_v18_wide.emplace_back( 64.10, 64.072324, 0.320359 ); + M_static_table_v18_wide.emplace_back( 64.70, 64.716261, 0.323578 ); + M_static_table_v18_wide.emplace_back( 65.40, 65.366670, 0.326830 ); + M_static_table_v18_wide.emplace_back( 66.00, 66.023616, 0.330115 ); + M_static_table_v18_wide.emplace_back( 66.70, 66.687165, 0.333433 ); + M_static_table_v18_wide.emplace_back( 67.40, 67.357382, 0.336784 ); + M_static_table_v18_wide.emplace_back( 68.00, 68.034335, 0.340169 ); + M_static_table_v18_wide.emplace_back( 68.70, 68.718091, 0.343587 ); + M_static_table_v18_wide.emplace_back( 69.40, 69.408720, 0.347041 ); + M_static_table_v18_wide.emplace_back( 70.10, 70.106289, 0.350528 ); + M_static_table_v18_wide.emplace_back( 70.80, 70.810869, 0.354051 ); + M_static_table_v18_wide.emplace_back( 71.50, 71.522530, 0.357609 ); + M_static_table_v18_wide.emplace_back( 72.20, 72.241343, 0.361203 ); + M_static_table_v18_wide.emplace_back( 73.00, 72.967381, 0.364834 ); + M_static_table_v18_wide.emplace_back( 73.70, 73.700715, 0.368500 ); + M_static_table_v18_wide.emplace_back( 74.40, 74.441420, 0.372204 ); + M_static_table_v18_wide.emplace_back( 75.20, 75.189568, 0.375944 ); + M_static_table_v18_wide.emplace_back( 75.90, 75.945236, 0.379723 ); + M_static_table_v18_wide.emplace_back( 76.70, 76.708498, 0.383539 ); + M_static_table_v18_wide.emplace_back( 77.50, 77.479432, 0.387394 ); + M_static_table_v18_wide.emplace_back( 78.30, 78.258113, 0.391287 ); + M_static_table_v18_wide.emplace_back( 79.00, 79.044620, 0.395219 ); + M_static_table_v18_wide.emplace_back( 79.80, 79.839032, 0.399192 ); + M_static_table_v18_wide.emplace_back( 80.60, 80.641427, 0.403203 ); + M_static_table_v18_wide.emplace_back( 81.50, 81.451887, 0.407256 ); + M_static_table_v18_wide.emplace_back( 82.30, 82.270492, 0.411349 ); + M_static_table_v18_wide.emplace_back( 83.10, 83.097325, 0.415483 ); + M_static_table_v18_wide.emplace_back( 83.90, 83.932467, 0.419659 ); + M_static_table_v18_wide.emplace_back( 84.80, 84.776002, 0.423876 ); + M_static_table_v18_wide.emplace_back( 85.60, 85.628014, 0.428136 ); + M_static_table_v18_wide.emplace_back( 86.50, 86.488590, 0.432439 ); + M_static_table_v18_wide.emplace_back( 87.40, 87.357815, 0.436785 ); + M_static_table_v18_wide.emplace_back( 88.20, 88.235776, 0.441175 ); + M_static_table_v18_wide.emplace_back( 89.10, 89.122560, 0.445609 ); + M_static_table_v18_wide.emplace_back( 90.00, 90.018257, 0.450087 ); + M_static_table_v18_wide.emplace_back( 90.90, 90.922956, 0.454611 ); + M_static_table_v18_wide.emplace_back( 91.80, 91.836746, 0.459179 ); + M_static_table_v18_wide.emplace_back( 92.80, 92.759721, 0.463795 ); + M_static_table_v18_wide.emplace_back( 93.70, 93.691972, 0.468456 ); + M_static_table_v18_wide.emplace_back( 94.60, 94.633592, 0.473164 ); + M_static_table_v18_wide.emplace_back( 95.60, 95.584675, 0.477919 ); + M_static_table_v18_wide.emplace_back( 96.50, 96.545317, 0.482722 ); + M_static_table_v18_wide.emplace_back( 97.50, 97.515614, 0.487574 ); + M_static_table_v18_wide.emplace_back( 98.50, 98.495662, 0.492474 ); + M_static_table_v18_wide.emplace_back( 99.50, 99.485560, 0.497424 ); + M_static_table_v18_wide.emplace_back( 100.50, 100.485406, 0.502422 ); + M_static_table_v18_wide.emplace_back( 101.50, 101.495301, 0.507472 ); + M_static_table_v18_wide.emplace_back( 102.50, 102.515346, 0.512572 ); + M_static_table_v18_wide.emplace_back( 103.50, 103.545642, 0.517723 ); + M_static_table_v18_wide.emplace_back( 104.60, 104.586293, 0.522927 ); + M_static_table_v18_wide.emplace_back( 105.60, 105.637403, 0.528182 ); + M_static_table_v18_wide.emplace_back( 106.70, 106.699077, 0.533491 ); + M_static_table_v18_wide.emplace_back( 107.80, 107.771420, 0.538852 ); + M_static_table_v18_wide.emplace_back( 108.90, 108.854541, 0.544268 ); + M_static_table_v18_wide.emplace_back( 109.90, 109.948547, 0.549738 ); + M_static_table_v18_wide.emplace_back( 111.10, 111.053549, 0.555263 ); + M_static_table_v18_wide.emplace_back( 112.20, 112.169655, 0.560843 ); + M_static_table_v18_wide.emplace_back( 113.30, 113.296979, 0.566480 ); + M_static_table_v18_wide.emplace_back( 114.40, 114.435632, 0.572173 ); + M_static_table_v18_wide.emplace_back( 115.60, 115.585730, 0.577924 ); + M_static_table_v18_wide.emplace_back( 116.70, 116.747386, 0.583732 ); + M_static_table_v18_wide.emplace_back( 117.90, 117.920716, 0.589598 ); + M_static_table_v18_wide.emplace_back( 119.10, 119.105839, 0.595524 ); + M_static_table_v18_wide.emplace_back( 120.30, 120.302873, 0.601509 ); + M_static_table_v18_wide.emplace_back( 121.50, 121.511937, 0.607555 ); + M_static_table_v18_wide.emplace_back( 122.70, 122.733152, 0.613660 ); + M_static_table_v18_wide.emplace_back( 124.00, 123.966641, 0.619828 ); + M_static_table_v18_wide.emplace_back( 125.20, 125.212526, 0.626057 ); + M_static_table_v18_wide.emplace_back( 126.50, 126.470933, 0.632349 ); + M_static_table_v18_wide.emplace_back( 127.70, 127.741987, 0.638704 ); + M_static_table_v18_wide.emplace_back( 129.00, 129.025815, 0.645123 ); + M_static_table_v18_wide.emplace_back( 130.30, 130.322546, 0.651607 ); + M_static_table_v18_wide.emplace_back( 131.60, 131.632310, 0.658156 ); + M_static_table_v18_wide.emplace_back( 133.00, 132.955236, 0.664770 ); + M_static_table_v18_wide.emplace_back( 134.30, 134.291459, 0.671452 ); + M_static_table_v18_wide.emplace_back( 135.60, 135.641111, 0.678200 ); + M_static_table_v18_wide.emplace_back( 137.00, 137.004326, 0.685015 ); + M_static_table_v18_wide.emplace_back( 138.40, 138.381242, 0.691900 ); + M_static_table_v18_wide.emplace_back( 139.80, 139.771997, 0.698854 ); + M_static_table_v18_wide.emplace_back( 141.20, 141.176729, 0.705877 ); + M_static_table_v18_wide.emplace_back( 142.60, 142.595579, 0.712972 ); + M_static_table_v18_wide.emplace_back( 144.00, 144.028688, 0.720137 ); + M_static_table_v18_wide.emplace_back( 145.50, 145.476201, 0.727375 ); + M_static_table_v18_wide.emplace_back( 146.90, 146.938261, 0.734685 ); + M_static_table_v18_wide.emplace_back( 148.40, 148.415015, 0.742069 ); + M_static_table_v18_wide.emplace_back( 149.90, 149.906611, 0.749527 ); + M_static_table_v18_wide.emplace_back( 151.40, 151.413197, 0.757059 ); + + // M_movable_table.emplace_back( 0.00, 0.026170, 0.026170 ); M_movable_table.emplace_back( 0.10, 0.104789, 0.052450 ); M_movable_table.emplace_back( 0.20, 0.208239, 0.051002 ); @@ -608,8 +2061,257 @@ ObjectTable::createTable() M_movable_table.emplace_back( 121.50, 121.662337, 6.078053 ); M_movable_table.emplace_back( 134.30, 134.457677, 6.717287 ); M_movable_table.emplace_back( 148.40, 148.598714, 7.423750 ); - M_movable_table.emplace_back( 164.00, 163.226977, 8.204513 ); - M_movable_table.emplace_back( 181.30, 181.498879, 9.067389 ); + + // + M_movable_table_v18_narrow.emplace_back( 0.00, 0.025524, 0.025524 ); + M_movable_table_v18_narrow.emplace_back( 0.10, 0.102202, 0.051154 ); + M_movable_table_v18_narrow.emplace_back( 0.20, 0.203098, 0.049743 ); + M_movable_table_v18_narrow.emplace_back( 0.30, 0.305818, 0.052978 ); + M_movable_table_v18_narrow.emplace_back( 0.40, 0.409750, 0.050953 ); + M_movable_table_v18_narrow.emplace_back( 0.50, 0.511704, 0.051001 ); + M_movable_table_v18_narrow.emplace_back( 0.60, 0.608237, 0.045533 ); + M_movable_table_v18_narrow.emplace_back( 0.70, 0.706671, 0.052902 ); + M_movable_table_v18_narrow.emplace_back( 0.80, 0.799516, 0.039943 ); + M_movable_table_v18_narrow.emplace_back( 0.90, 0.883601, 0.044143 ); + M_movable_table_v18_narrow.emplace_back( 1.00, 0.976530, 0.048786 ); + M_movable_table_v18_narrow.emplace_back( 1.10, 1.079233, 0.053916 ); + M_movable_table_v18_narrow.emplace_back( 1.20, 1.192736, 0.059587 ); + M_movable_table_v18_narrow.emplace_back( 1.30, 1.318177, 0.065854 ); + M_movable_table_v18_narrow.emplace_back( 1.40, 1.419511, 0.035480 ); + M_movable_table_v18_narrow.emplace_back( 1.50, 1.492291, 0.037299 ); + M_movable_table_v18_narrow.emplace_back( 1.60, 1.610025, 0.080434 ); + M_movable_table_v18_narrow.emplace_back( 1.70, 1.733795, 0.043336 ); + M_movable_table_v18_narrow.emplace_back( 1.80, 1.822688, 0.045557 ); + M_movable_table_v18_narrow.emplace_back( 1.90, 1.916139, 0.047893 ); + M_movable_table_v18_narrow.emplace_back( 2.00, 2.014382, 0.050350 ); + M_movable_table_v18_narrow.emplace_back( 2.10, 2.117662, 0.052931 ); + M_movable_table_v18_narrow.emplace_back( 2.20, 2.226237, 0.055644 ); + M_movable_table_v18_narrow.emplace_back( 2.30, 2.340378, 0.058498 ); + M_movable_table_v18_narrow.emplace_back( 2.50, 2.460372, 0.061497 ); + M_movable_table_v18_narrow.emplace_back( 2.60, 2.586519, 0.064650 ); + M_movable_table_v18_narrow.emplace_back( 2.70, 2.719132, 0.067964 ); + M_movable_table_v18_narrow.emplace_back( 2.90, 2.858545, 0.071449 ); + M_movable_table_v18_narrow.emplace_back( 3.00, 3.005105, 0.075112 ); + M_movable_table_v18_narrow.emplace_back( 3.20, 3.159180, 0.078963 ); + M_movable_table_v18_narrow.emplace_back( 3.30, 3.321155, 0.083012 ); + M_movable_table_v18_narrow.emplace_back( 3.50, 3.491435, 0.087268 ); + M_movable_table_v18_narrow.emplace_back( 3.70, 3.670444, 0.091742 ); + M_movable_table_v18_narrow.emplace_back( 3.90, 3.858632, 0.096446 ); + M_movable_table_v18_narrow.emplace_back( 4.10, 4.056468, 0.101391 ); + M_movable_table_v18_narrow.emplace_back( 4.30, 4.264447, 0.106589 ); + M_movable_table_v18_narrow.emplace_back( 4.50, 4.483090, 0.112054 ); + M_movable_table_v18_narrow.emplace_back( 4.70, 4.712943, 0.117799 ); + M_movable_table_v18_narrow.emplace_back( 5.00, 4.954581, 0.123839 ); + M_movable_table_v18_narrow.emplace_back( 5.20, 5.208608, 0.130188 ); + M_movable_table_v18_narrow.emplace_back( 5.50, 5.475659, 0.136863 ); + M_movable_table_v18_narrow.emplace_back( 5.80, 5.756402, 0.143880 ); + M_movable_table_v18_narrow.emplace_back( 6.00, 6.051539, 0.151257 ); + M_movable_table_v18_narrow.emplace_back( 6.40, 6.361808, 0.159012 ); + M_movable_table_v18_narrow.emplace_back( 6.70, 6.687985, 0.167165 ); + M_movable_table_v18_narrow.emplace_back( 7.00, 7.030885, 0.175736 ); + M_movable_table_v18_narrow.emplace_back( 7.40, 7.391366, 0.184746 ); + M_movable_table_v18_narrow.emplace_back( 7.80, 7.770329, 0.194218 ); + M_movable_table_v18_narrow.emplace_back( 8.20, 8.168723, 0.204175 ); + M_movable_table_v18_narrow.emplace_back( 8.60, 8.587542, 0.214644 ); + M_movable_table_v18_narrow.emplace_back( 9.00, 9.027834, 0.225648 ); + M_movable_table_v18_narrow.emplace_back( 9.50, 9.490701, 0.237218 ); + M_movable_table_v18_narrow.emplace_back( 10.00, 9.977300, 0.249380 ); + M_movable_table_v18_narrow.emplace_back( 10.50, 10.488847, 0.262166 ); + M_movable_table_v18_narrow.emplace_back( 11.00, 11.026622, 0.275608 ); + M_movable_table_v18_narrow.emplace_back( 11.60, 11.591969, 0.289739 ); + M_movable_table_v18_narrow.emplace_back( 12.20, 12.186302, 0.304594 ); + M_movable_table_v18_narrow.emplace_back( 12.80, 12.811107, 0.320211 ); + M_movable_table_v18_narrow.emplace_back( 13.50, 13.467946, 0.336628 ); + M_movable_table_v18_narrow.emplace_back( 14.20, 14.158462, 0.353887 ); + M_movable_table_v18_narrow.emplace_back( 14.90, 14.884382, 0.372032 ); + M_movable_table_v18_narrow.emplace_back( 15.60, 15.647521, 0.391107 ); + M_movable_table_v18_narrow.emplace_back( 16.40, 16.449786, 0.411159 ); + M_movable_table_v18_narrow.emplace_back( 17.30, 17.293185, 0.432240 ); + M_movable_table_v18_narrow.emplace_back( 18.20, 18.179826, 0.454401 ); + M_movable_table_v18_narrow.emplace_back( 19.10, 19.111925, 0.477699 ); + M_movable_table_v18_narrow.emplace_back( 20.10, 20.091814, 0.502191 ); + M_movable_table_v18_narrow.emplace_back( 21.10, 21.121944, 0.527939 ); + M_movable_table_v18_narrow.emplace_back( 22.20, 22.204889, 0.555007 ); + M_movable_table_v18_narrow.emplace_back( 23.30, 23.343358, 0.583462 ); + M_movable_table_v18_narrow.emplace_back( 24.50, 24.540198, 0.613378 ); + M_movable_table_v18_narrow.emplace_back( 25.80, 25.798401, 0.644826 ); + M_movable_table_v18_narrow.emplace_back( 27.10, 27.121113, 0.677887 ); + M_movable_table_v18_narrow.emplace_back( 28.50, 28.511642, 0.712643 ); + M_movable_table_v18_narrow.emplace_back( 30.00, 29.973465, 0.749181 ); + M_movable_table_v18_narrow.emplace_back( 31.50, 31.510237, 0.787592 ); + M_movable_table_v18_narrow.emplace_back( 33.10, 33.125802, 0.827972 ); + M_movable_table_v18_narrow.emplace_back( 34.80, 34.824198, 0.870423 ); + M_movable_table_v18_narrow.emplace_back( 36.60, 36.609672, 0.915051 ); + M_movable_table_v18_narrow.emplace_back( 38.50, 38.486690, 0.961966 ); + M_movable_table_v18_narrow.emplace_back( 40.40, 40.459945, 1.011288 ); + M_movable_table_v18_narrow.emplace_back( 42.50, 42.534371, 1.063138 ); + M_movable_table_v18_narrow.emplace_back( 44.70, 44.715155, 1.117646 ); + M_movable_table_v18_narrow.emplace_back( 47.00, 47.007750, 1.174949 ); + M_movable_table_v18_narrow.emplace_back( 49.40, 49.417889, 1.235190 ); + M_movable_table_v18_narrow.emplace_back( 51.90, 51.951598, 1.298519 ); + M_movable_table_v18_narrow.emplace_back( 54.60, 54.615213, 1.365096 ); + M_movable_table_v18_narrow.emplace_back( 57.40, 57.415395, 1.435086 ); + M_movable_table_v18_narrow.emplace_back( 60.30, 60.359145, 1.508664 ); + M_movable_table_v18_narrow.emplace_back( 63.40, 63.453825, 1.586015 ); + M_movable_table_v18_narrow.emplace_back( 66.70, 66.707172, 1.667332 ); + M_movable_table_v18_narrow.emplace_back( 70.10, 70.127322, 1.752818 ); + M_movable_table_v18_narrow.emplace_back( 73.70, 73.722826, 1.842686 ); + M_movable_table_v18_narrow.emplace_back( 77.50, 77.502676, 1.937163 ); + M_movable_table_v18_narrow.emplace_back( 81.50, 81.476324, 2.036484 ); + M_movable_table_v18_narrow.emplace_back( 85.60, 85.653704, 2.140896 ); + M_movable_table_v18_narrow.emplace_back( 90.00, 90.045263, 2.250662 ); + M_movable_table_v18_narrow.emplace_back( 94.60, 94.661983, 2.366057 ); + M_movable_table_v18_narrow.emplace_back( 99.50, 99.515407, 2.487367 ); + M_movable_table_v18_narrow.emplace_back( 104.60, 104.617671, 2.614897 ); + M_movable_table_v18_narrow.emplace_back( 109.90, 109.981533, 2.748965 ); + M_movable_table_v18_narrow.emplace_back( 115.60, 115.620407, 2.889908 ); + M_movable_table_v18_narrow.emplace_back( 121.50, 121.548392, 3.038077 ); + M_movable_table_v18_narrow.emplace_back( 127.70, 127.780311, 3.193842 ); + M_movable_table_v18_narrow.emplace_back( 134.30, 134.331748, 3.357594 ); + M_movable_table_v18_narrow.emplace_back( 141.20, 141.219084, 3.529742 ); + M_movable_table_v18_narrow.emplace_back( 148.40, 148.459541, 3.710715 ); + + // + M_movable_table_v18_normal.emplace_back( 0.00, 0.025845, 0.025845 ); + M_movable_table_v18_normal.emplace_back( 0.10, 0.099701, 0.048011 ); + M_movable_table_v18_normal.emplace_back( 0.20, 0.198705, 0.050994 ); + M_movable_table_v18_normal.emplace_back( 0.30, 0.306504, 0.056805 ); + M_movable_table_v18_normal.emplace_back( 0.40, 0.409145, 0.045835 ); + M_movable_table_v18_normal.emplace_back( 0.50, 0.512382, 0.057401 ); + M_movable_table_v18_normal.emplace_back( 0.60, 0.615888, 0.046106 ); + M_movable_table_v18_normal.emplace_back( 0.70, 0.715560, 0.053567 ); + M_movable_table_v18_normal.emplace_back( 0.80, 0.799079, 0.029952 ); + M_movable_table_v18_normal.emplace_back( 0.90, 0.896113, 0.067083 ); + M_movable_table_v18_normal.emplace_back( 1.00, 1.000704, 0.037508 ); + M_movable_table_v18_normal.emplace_back( 1.10, 1.078643, 0.040430 ); + M_movable_table_v18_normal.emplace_back( 1.20, 1.162652, 0.043579 ); + M_movable_table_v18_normal.emplace_back( 1.30, 1.303835, 0.097604 ); + M_movable_table_v18_normal.emplace_back( 1.50, 1.456015, 0.054575 ); + M_movable_table_v18_normal.emplace_back( 1.60, 1.569415, 0.058825 ); + M_movable_table_v18_normal.emplace_back( 1.70, 1.691648, 0.063407 ); + M_movable_table_v18_normal.emplace_back( 1.80, 1.823400, 0.068345 ); + M_movable_table_v18_normal.emplace_back( 2.00, 1.965414, 0.073668 ); + M_movable_table_v18_normal.emplace_back( 2.10, 2.118489, 0.079406 ); + M_movable_table_v18_normal.emplace_back( 2.30, 2.283485, 0.085591 ); + M_movable_table_v18_normal.emplace_back( 2.50, 2.461333, 0.092257 ); + M_movable_table_v18_normal.emplace_back( 2.70, 2.653032, 0.099442 ); + M_movable_table_v18_normal.emplace_back( 2.90, 2.859661, 0.107187 ); + M_movable_table_v18_normal.emplace_back( 3.10, 3.082384, 0.115536 ); + M_movable_table_v18_normal.emplace_back( 3.30, 3.322453, 0.124534 ); + M_movable_table_v18_normal.emplace_back( 3.60, 3.581219, 0.134233 ); + M_movable_table_v18_normal.emplace_back( 3.90, 3.860139, 0.144688 ); + M_movable_table_v18_normal.emplace_back( 4.20, 4.160782, 0.155956 ); + M_movable_table_v18_normal.emplace_back( 4.50, 4.484841, 0.168103 ); + M_movable_table_v18_normal.emplace_back( 4.80, 4.834139, 0.181195 ); + M_movable_table_v18_normal.emplace_back( 5.20, 5.210642, 0.195308 ); + M_movable_table_v18_normal.emplace_back( 5.60, 5.616468, 0.210519 ); + M_movable_table_v18_normal.emplace_back( 6.00, 6.053902, 0.226915 ); + M_movable_table_v18_normal.emplace_back( 6.50, 6.525405, 0.244588 ); + M_movable_table_v18_normal.emplace_back( 7.00, 7.033631, 0.263638 ); + M_movable_table_v18_normal.emplace_back( 7.60, 7.581439, 0.284171 ); + M_movable_table_v18_normal.emplace_back( 8.20, 8.171913, 0.306303 ); + M_movable_table_v18_normal.emplace_back( 8.80, 8.808376, 0.330159 ); + M_movable_table_v18_normal.emplace_back( 9.50, 9.494408, 0.355873 ); + M_movable_table_v18_normal.emplace_back( 10.20, 10.233872, 0.383590 ); + M_movable_table_v18_normal.emplace_back( 11.00, 11.030928, 0.413466 ); + M_movable_table_v18_normal.emplace_back( 11.90, 11.890062, 0.445668 ); + M_movable_table_v18_normal.emplace_back( 12.80, 12.816110, 0.480379 ); + M_movable_table_v18_normal.emplace_back( 13.80, 13.814282, 0.517793 ); + M_movable_table_v18_normal.emplace_back( 14.90, 14.890195, 0.558120 ); + M_movable_table_v18_normal.emplace_back( 16.00, 16.049905, 0.601590 ); + M_movable_table_v18_normal.emplace_back( 17.30, 17.299939, 0.648444 ); + M_movable_table_v18_normal.emplace_back( 18.60, 18.647330, 0.698948 ); + M_movable_table_v18_normal.emplace_back( 20.10, 20.099662, 0.753384 ); + M_movable_table_v18_normal.emplace_back( 21.60, 21.665107, 0.812061 ); + M_movable_table_v18_normal.emplace_back( 23.30, 23.352476, 0.875308 ); + M_movable_table_v18_normal.emplace_back( 25.20, 25.171263, 0.943480 ); + M_movable_table_v18_normal.emplace_back( 27.10, 27.131705, 1.016962 ); + M_movable_table_v18_normal.emplace_back( 29.20, 29.244835, 1.096168 ); + M_movable_table_v18_normal.emplace_back( 31.50, 31.522545, 1.181541 ); + M_movable_table_v18_normal.emplace_back( 34.00, 33.977651, 1.273565 ); + M_movable_table_v18_normal.emplace_back( 36.60, 36.623971, 1.372755 ); + M_movable_table_v18_normal.emplace_back( 39.40, 39.476398, 1.479671 ); + M_movable_table_v18_normal.emplace_back( 42.50, 42.550983, 1.594914 ); + M_movable_table_v18_normal.emplace_back( 45.80, 45.865031, 1.719133 ); + M_movable_table_v18_normal.emplace_back( 49.40, 49.437190, 1.853026 ); + M_movable_table_v18_normal.emplace_back( 53.30, 53.287563, 1.997347 ); + M_movable_table_v18_normal.emplace_back( 57.40, 57.437820, 2.152909 ); + M_movable_table_v18_normal.emplace_back( 61.90, 61.911315, 2.320586 ); + M_movable_table_v18_normal.emplace_back( 66.70, 66.733226, 2.501324 ); + M_movable_table_v18_normal.emplace_back( 71.90, 71.930687, 2.696137 ); + M_movable_table_v18_normal.emplace_back( 77.50, 77.532947, 2.906123 ); + M_movable_table_v18_normal.emplace_back( 83.50, 83.571534, 3.132464 ); + M_movable_table_v18_normal.emplace_back( 90.00, 90.080432, 3.376433 ); + M_movable_table_v18_normal.emplace_back( 97.00, 97.096270, 3.639404 ); + M_movable_table_v18_normal.emplace_back( 104.60, 104.658531, 3.922856 ); + M_movable_table_v18_normal.emplace_back( 112.70, 112.809772, 4.228385 ); + M_movable_table_v18_normal.emplace_back( 121.50, 121.595865, 4.557708 ); + M_movable_table_v18_normal.emplace_back( 131.00, 131.066256, 4.912682 ); + M_movable_table_v18_normal.emplace_back( 141.20, 141.274240, 5.295302 ); + + // + M_movable_table_v18_wide.emplace_back( 0.00, 0.026170, 0.026170 ); + M_movable_table_v18_wide.emplace_back( 0.10, 0.104789, 0.052449 ); + M_movable_table_v18_wide.emplace_back( 0.20, 0.208240, 0.051001 ); + M_movable_table_v18_wide.emplace_back( 0.30, 0.304589, 0.045348 ); + M_movable_table_v18_wide.emplace_back( 0.40, 0.411152, 0.061214 ); + M_movable_table_v18_wide.emplace_back( 0.50, 0.524658, 0.052292 ); + M_movable_table_v18_wide.emplace_back( 0.60, 0.607289, 0.030340 ); + M_movable_table_v18_wide.emplace_back( 0.70, 0.708215, 0.070586 ); + M_movable_table_v18_wide.emplace_back( 0.80, 0.819755, 0.040954 ); + M_movable_table_v18_wide.emplace_back( 0.90, 0.905969, 0.045261 ); + M_movable_table_v18_wide.emplace_back( 1.00, 1.001251, 0.050021 ); + M_movable_table_v18_wide.emplace_back( 1.10, 1.106553, 0.055281 ); + M_movable_table_v18_wide.emplace_back( 1.20, 1.222930, 0.061095 ); + M_movable_table_v18_wide.emplace_back( 1.30, 1.351547, 0.067521 ); + M_movable_table_v18_wide.emplace_back( 1.50, 1.493690, 0.074622 ); + M_movable_table_v18_wide.emplace_back( 1.60, 1.650783, 0.082470 ); + M_movable_table_v18_wide.emplace_back( 1.80, 1.824397, 0.091143 ); + M_movable_table_v18_wide.emplace_back( 2.00, 2.016271, 0.100730 ); + M_movable_table_v18_wide.emplace_back( 2.20, 2.228324, 0.111323 ); + M_movable_table_v18_wide.emplace_back( 2.50, 2.462678, 0.123032 ); + M_movable_table_v18_wide.emplace_back( 2.70, 2.721681, 0.135971 ); + M_movable_table_v18_wide.emplace_back( 3.00, 3.007923, 0.150271 ); + M_movable_table_v18_wide.emplace_back( 3.30, 3.324268, 0.166075 ); + M_movable_table_v18_wide.emplace_back( 3.70, 3.673885, 0.183542 ); + M_movable_table_v18_wide.emplace_back( 4.10, 4.060271, 0.202845 ); + M_movable_table_v18_wide.emplace_back( 4.50, 4.487293, 0.224178 ); + M_movable_table_v18_wide.emplace_back( 5.00, 4.959226, 0.247755 ); + M_movable_table_v18_wide.emplace_back( 5.50, 5.480792, 0.273812 ); + M_movable_table_v18_wide.emplace_back( 6.00, 6.057212, 0.302609 ); + M_movable_table_v18_wide.emplace_back( 6.70, 6.694254, 0.334434 ); + M_movable_table_v18_wide.emplace_back( 7.40, 7.398295, 0.369607 ); + M_movable_table_v18_wide.emplace_back( 8.20, 8.176381, 0.408478 ); + M_movable_table_v18_wide.emplace_back( 9.00, 9.036297, 0.451438 ); + M_movable_table_v18_wide.emplace_back( 10.00, 9.986653, 0.498917 ); + M_movable_table_v18_wide.emplace_back( 11.00, 11.036958, 0.551388 ); + M_movable_table_v18_wide.emplace_back( 12.20, 12.197725, 0.609378 ); + M_movable_table_v18_wide.emplace_back( 13.50, 13.480571, 0.673467 ); + M_movable_table_v18_wide.emplace_back( 14.90, 14.898335, 0.744296 ); + M_movable_table_v18_wide.emplace_back( 16.40, 16.465207, 0.822575 ); + M_movable_table_v18_wide.emplace_back( 18.20, 18.196868, 0.909086 ); + M_movable_table_v18_wide.emplace_back( 20.10, 20.110649, 1.004696 ); + M_movable_table_v18_wide.emplace_back( 22.20, 22.225705, 1.110360 ); + M_movable_table_v18_wide.emplace_back( 24.50, 24.563203, 1.227138 ); + M_movable_table_v18_wide.emplace_back( 27.10, 27.146537, 1.356197 ); + M_movable_table_v18_wide.emplace_back( 30.00, 30.001564, 1.498830 ); + M_movable_table_v18_wide.emplace_back( 33.10, 33.156856, 1.656462 ); + M_movable_table_v18_wide.emplace_back( 36.60, 36.643992, 1.830674 ); + M_movable_table_v18_wide.emplace_back( 40.40, 40.497875, 2.023208 ); + M_movable_table_v18_wide.emplace_back( 44.70, 44.757073, 2.235990 ); + M_movable_table_v18_wide.emplace_back( 49.40, 49.464215, 2.471151 ); + M_movable_table_v18_wide.emplace_back( 54.60, 54.666412, 2.731045 ); + M_movable_table_v18_wide.emplace_back( 60.30, 60.415729, 3.018271 ); + M_movable_table_v18_wide.emplace_back( 66.70, 66.769707, 3.335706 ); + M_movable_table_v18_wide.emplace_back( 73.70, 73.791938, 3.686525 ); + M_movable_table_v18_wide.emplace_back( 81.50, 81.552704, 4.074240 ); + M_movable_table_v18_wide.emplace_back( 90.00, 90.129677, 4.502732 ); + M_movable_table_v18_wide.emplace_back( 99.50, 99.608697, 4.976288 ); + M_movable_table_v18_wide.emplace_back( 109.90, 110.084635, 5.499649 ); + M_movable_table_v18_wide.emplace_back( 121.50, 121.662338, 6.078053 ); + M_movable_table_v18_wide.emplace_back( 134.30, 134.457678, 6.717287 ); + M_movable_table_v18_wide.emplace_back( 148.40, 148.598714, 7.423750 ); + } /*-------------------------------------------------------------------*/ @@ -675,6 +2377,74 @@ ObjectTable::getMovableObjInfo( const double & see_dist, return true; } +/*-------------------------------------------------------------------*/ +bool +ObjectTable::getLandmarkDistanceRangeV18( const ViewWidth::Type view_width, + const double quant_dist, + double * mean_dist, + double * dist_error ) const +{ + const std::vector< DataEntry > * table = ( view_width == ViewWidth::NARROW + ? &M_static_table_v18_narrow + : view_width == ViewWidth::NORMAL + ? &M_static_table_v18_normal + : &M_static_table_v18_wide ); + + std::vector< DataEntry >::const_iterator + it = std::lower_bound( table->begin(), + table->end(), + DataEntry( quant_dist - 0.001 ), + []( const DataEntry & lhs, + const DataEntry & rhs ) + { + return lhs.M_seen_dist < rhs.M_seen_dist; + } ); + if ( it == table->end() ) + { + std::cerr << "(ObjectTable::getLandmarkDistanceRangeV18) illegal distance = " << quant_dist << std::endl; + return false; + } + + *mean_dist = it->M_average; + *dist_error = it->M_error; + + return true; +} + +/*-------------------------------------------------------------------*/ +bool +ObjectTable::getDistanceRangeV18( const ViewWidth::Type view_width, + const double quant_dist, + double * mean_dist, + double * dist_error ) const +{ + const std::vector< DataEntry > * table = ( view_width == ViewWidth::NARROW + ? &M_movable_table_v18_narrow + : view_width == ViewWidth::NORMAL + ? &M_movable_table_v18_normal + : &M_movable_table_v18_wide ); + + std::vector< DataEntry >::const_iterator + it = std::lower_bound( table->begin(), + table->end(), + DataEntry( quant_dist - 0.001 ), + []( const DataEntry & lhs, + const DataEntry & rhs ) + { + return lhs.M_seen_dist < rhs.M_seen_dist; + } ); + if ( it == table->end() ) + { + std::cerr << "(ObjectTable::getDistanceRangeV18) illegal distance = " << quant_dist << std::endl; + return false; + } + + *mean_dist = it->M_average; + *dist_error = it->M_error; + + return true; +} + /*-------------------------------------------------------------------*/ /*! diff --git a/rcsc/player/object_table.h b/rcsc/player/object_table.h index 843b419..060ff2b 100644 --- a/rcsc/player/object_table.h +++ b/rcsc/player/object_table.h @@ -32,6 +32,7 @@ #ifndef RCSC_PLAYER_OBJECT_TABLE_H #define RCSC_PLAYER_OBJECT_TABLE_H +#include #include #include @@ -104,9 +105,17 @@ class ObjectTable { //! distance table for stationary objects (line, marker) std::vector< DataEntry > M_static_table; + std::vector< DataEntry > M_static_table_v18_narrow; //!< landmark distance table for v18+ narrow + std::vector< DataEntry > M_static_table_v18_normal; //!< landmark distance table for v18+ normal + std::vector< DataEntry > M_static_table_v18_wide; //!< landmark distance table for v18+ wide + //! distance table for movable objects (ball, player) std::vector< DataEntry > M_movable_table; + std::vector< DataEntry > M_movable_table_v18_narrow; //!< distance table for v18+ narrow + std::vector< DataEntry > M_movable_table_v18_normal; //!< distance table for v18+ normal + std::vector< DataEntry > M_movable_table_v18_wide; //!< distance table for v18+ wide + public: /*! \brief create distance table @@ -146,6 +155,54 @@ class ObjectTable { double * ave, double * err ) const; + /*! + \brief get the predefinede distance range for the landmark objects (v18+) + \param quant_dist seen distance value + \param mean_dist variable pointer to store the result mean distance + \param dist_error variable pointer to store the result error range + \return true if found the matched data + */ + bool getLandmarkDistanceRangeV18( const ViewWidth::Type view_width, + const double quant_dist, + double * mean_dist, + double * dist_error ) const; + + bool getLandmarkDistanceRange( const double /*client_version*/, + const ViewWidth::Type /*view_width*/, + const double quant_dist, + double * mean_dist, + double * dist_error ) const + { + // return ( client_version >= 18.0 + // ? getLandmarkDistanceRangeV18( view_width, quant_dist, mean_dist, dist_error ) + // : getStaticObjInfo( quant_dist, mean_dist, dist_error ) ); + return getStaticObjInfo( quant_dist, mean_dist, dist_error ); + } + + /*! + \brief get the predefinede distance range for the movable objects (v18+) + \param quant_dist seen distance value + \param mean_dist variable pointer to store the result mean distance + \param dist_error variable pointer to store the result error range + \return true if found the matched data + */ + bool getDistanceRangeV18( const ViewWidth::Type view_width, + const double quant_dist, + double * mean_dist, + double * dist_error ) const; + + bool getDistanceRange( const double /*client_version*/, + const ViewWidth::Type /*view_width*/, + const double quant_dist, + double * mean_dist, + double * dist_error ) const + { + // return ( client_version >= 18.0 + // ? getDistanceRangeV18( view_width, quant_dist, mean_dist, dist_error ) + // : getMovableObjInfo( quant_dist, mean_dist, dist_error ) ); + return getMovableObjInfo( quant_dist, mean_dist, dist_error ); + } + /*! \brief static utility. round real value \param value value to be rounded diff --git a/rcsc/player/player_agent.cpp b/rcsc/player/player_agent.cpp index d4ad206..4510f42 100644 --- a/rcsc/player/player_agent.cpp +++ b/rcsc/player/player_agent.cpp @@ -40,6 +40,8 @@ #include "audio_sensor.h" #include "fullstate_sensor.h" +#include "localization_default.h" + #include "player_command.h" #include "say_message_builder.h" #include "soccer_action.h" @@ -62,7 +64,6 @@ #include #include #include -#include #include #include @@ -136,6 +137,9 @@ struct PlayerAgent::Impl { //! pointer to reserved action std::shared_ptr< ViewAction > view_action_; + //! pointer to reserved action + std::shared_ptr< FocusAction > focus_action_; + //! intention queue SoccerIntention::Ptr intention_; @@ -392,6 +396,14 @@ struct PlayerAgent::Impl { */ void doNeckAction(); + /*! + \brief perform reserved change_focus action + + This method is called after doBodyAction() + This method is called after doViewAction() + This method is called after doNeckAction() + */ + void doFocusAction(); /*! \brief output debug messages to disk/server. @@ -804,9 +816,9 @@ PlayerAgent::initImpl( CmdLineParser & cmd_parser ) M_config.parse( cmd_parser ); if ( config().version() < 8.0 - || 18.0 <= config().version() ) + || MAX_PROTOCOL_VERSION < config().version() ) { - std::cerr << "Unsupported client version: " << config().version() + std::cerr << "(PlayerAgent::initImpl) Unsupported client version: " << config().version() << std::endl; return false; } @@ -827,6 +839,10 @@ PlayerAgent::initImpl( CmdLineParser & cmd_parser ) AudioCodec::instance().createMap( config().audioShift() ); + + M_worldmodel.setLocalization( std::shared_ptr< Localization >( new LocalizationDefault() ) ); + M_fullstate_worldmodel.setLocalization( std::shared_ptr< Localization >( new LocalizationDefault() ) ); + return true; } @@ -1007,6 +1023,8 @@ PlayerAgent::handleTimeout( const int timeout_count, } TimeStamp cur_time; + cur_time.setNow(); + std::int64_t msec_from_sense = -1; /* std::cerr << "cur_sec = " << cur_time.sec() @@ -1309,7 +1327,8 @@ PlayerAgent::Impl::sendSettingCommands() std::ostringstream ostr; // set synch see mode - if ( agent_.config().synchSee() ) + if ( agent_.config().version() < 18.0 + && agent_.config().synchSee() ) { ostr << "(synch_see)"; } @@ -1389,6 +1408,8 @@ PlayerAgent::Impl::setDebugFlags() return; } + dlog.setTimeRange( c.debugStartTime(), c.debugEndTime() ); + dlog.setLogFlag( ¤t_time_, Logger::SYSTEM, c.debugSystem() ); dlog.setLogFlag( ¤t_time_, Logger::SENSOR, c.debugSensor() ); dlog.setLogFlag( ¤t_time_, Logger::WORLD, c.debugWorld() ); @@ -2105,7 +2126,8 @@ PlayerAgent::Impl::analyzeInit( const char * msg ) if ( ! agent_.M_worldmodel.init( agent_.config().teamName(), side, unum, - agent_.config().goalie() ) ) + agent_.config().goalie(), + agent_.config().version() ) ) { agent_.M_client->setServerAlive( false ); return; @@ -2114,7 +2136,8 @@ PlayerAgent::Impl::analyzeInit( const char * msg ) if ( agent_.config().debugFullstate() && ! agent_.M_fullstate_worldmodel.init( agent_.config().teamName(), side, unum, - agent_.config().goalie() ) ) + agent_.config().goalie(), + agent_.config().version() ) ) { agent_.M_client->setServerAlive( false ); return; @@ -2132,6 +2155,19 @@ PlayerAgent::Impl::analyzeInit( const char * msg ) sendSettingCommands(); + // + // + // + see_state_.setProtocolVersion( agent_.config().version() ); + if ( agent_.config().version() >= 18.0 ) + { + std::cerr << agent_.world().teamName() << ' ' + << agent_.world().self().unum() << ": " + << agent_.world().time() + << " (v18+) force synch see mode." + << std::endl; + } + // // call init message event handler // @@ -2373,15 +2409,19 @@ PlayerAgent::action() M_impl->doArmAction(); M_impl->doViewAction(); M_impl->doNeckAction(); + M_impl->doFocusAction(); communicationImpl(); // ------------------------------------------------------------------------ // set command effect. these must be called before command composing. // set self view mode, pointto and attentionto info. M_worldmodel.updateJustAfterDecision( effector() ); - // set cycles till next see, update estimated next see arrival timing - M_impl->see_state_.setViewMode( world().self().viewWidth(), - world().self().viewQuality() ); + if ( effector().changeViewCommand() ) + { + // set cycles till next see, update estimated next see arrival timing + M_impl->see_state_.setViewMode( effector().changeViewCommand()->width(), + effector().changeViewCommand()->quality() ); + } // ------------------------------------------------------------------------ // compose command string, and send it to the rcssserver @@ -2458,6 +2498,20 @@ PlayerAgent::Impl::doViewAction() } } +/*-------------------------------------------------------------------*/ +/*! + + */ +void +PlayerAgent::Impl::doFocusAction() +{ + if ( focus_action_ ) + { + focus_action_->execute( &agent_ ); + focus_action_.reset(); + } +} + /*-------------------------------------------------------------------*/ /*! @@ -2472,8 +2526,10 @@ PlayerAgent::Impl::doNeckAction() } else { - dlog.addText( Logger::SYSTEM, - __FILE__": WARNING. no turn_neck." ); + std::cerr << agent_.world().teamName() << ' ' + << agent_.world().self().unum() << ": " + << agent_.world().time() + << " WARNING. no turn_neck." << std::endl; } } @@ -2764,11 +2820,6 @@ PlayerAgent::doDash( const double & power, return true; } -bool -PlayerAgent::doOmniDash( PlayerAgent * agent, Vector2D point ) { - return Body_GoToPoint(point, 1.0, ServerParam::i().maxDashPower()).execute( agent ); -} - /*-------------------------------------------------------------------*/ /*! @@ -2948,6 +2999,78 @@ PlayerAgent::doChangeView( const ViewWidth & width ) return true; } +/*-------------------------------------------------------------------*/ +bool +PlayerAgent::doChangeFocus( const double moment_dist, + const AngleDeg & moment_dir ) +{ + + // check the range of distance + double aligned_moment_dist = moment_dist; + if ( world().self().focusDist() + aligned_moment_dist < 0.0 ) + { + if ( world().self().focusDist() + aligned_moment_dist < -1.0e-5 ) + { + std::cerr << world().teamName() << ' ' << world().self().unum() << ": " << world().time() + << " (doChangeFocus) under min dist. " << world().self().focusDist() + moment_dist << std::endl; + dlog.addText( Logger::ACTION, + __FILE__" (doChangeFocus) under min dist %f command=%f", + world().self().focusDist() + moment_dist, moment_dist ); + } + aligned_moment_dist = -world().self().focusDist(); + } + else if ( world().self().focusDist() + aligned_moment_dist > 40.0 ) + { + if ( world().self().focusDist() + aligned_moment_dist > 40.0 + 1.0e-5 ) + { + std::cerr << world().teamName() << ' ' << world().self().unum() << ": " << world().time() + << " (doChangeFocus) over dist. " << world().self().focusDist() + moment_dist << std::endl; + dlog.addText( Logger::ACTION, + __FILE__" (doChangeFocus) over max dist %f command=%f", + world().self().focusDist() + moment_dist, moment_dist ); + } + aligned_moment_dist = 40.0 - world().self().focusDist(); + } + + // check the range of visible angle + const ViewWidth next_width = M_effector.queuedNextViewWidth(); + const double next_half_angle = next_width.width() * 0.5; + + AngleDeg aligned_moment_dir = moment_dir; + if ( world().self().focusDir().degree() + aligned_moment_dir.degree() < -next_half_angle ) + { + if ( world().self().focusDir().degree() + aligned_moment_dir.degree() < -next_half_angle - 1.0e-5 ) + { + std::cerr << world().teamName() << ' ' << world().self().unum() << ": " << world().time() + << " (doChangeFocus) under min angle. " << world().self().focusDir().degree() + moment_dir.degree() + << " < " << -next_half_angle + << std::endl; + dlog.addText( Logger::ACTION, + __FILE__" (doChangeFocus) under min angle %f < %f. command=%f", + world().self().focusDir().degree() + moment_dir.degree(), -next_half_angle, moment_dir.degree() ); + } + aligned_moment_dir = -next_half_angle - world().self().focusDir().degree(); + } + else if ( world().self().focusDir().degree() + aligned_moment_dir.degree() > next_half_angle ) + { + if ( world().self().focusDir().degree() + aligned_moment_dir.degree() > next_half_angle + 1.0e-5 ) + { + std::cerr << world().teamName() << ' ' << world().self().unum() << ": " << world().time() + << " (doChangeFocus) over max angle " << world().self().focusDir().degree() + moment_dir.degree() + << " > next_half=" << next_half_angle + << std::endl; + dlog.addText( Logger::ACTION, + __FILE__" (doChangeFocus) over max angle %f > %f. command=%f", + world().self().focusDir().degree() + moment_dir.degree(), next_half_angle, moment_dir.degree() ); + } + aligned_moment_dir = next_half_angle - world().self().focusDir().degree(); + } + + M_effector.setChangeFocus( aligned_moment_dist, aligned_moment_dir ); + return true; +} + + /*-------------------------------------------------------------------*/ /*! @@ -3078,13 +3201,13 @@ PlayerAgent::doAttentionto( SideID side, return false; } - if ( world().self().attentiontoUnum() == unum - && world().self().attentiontoSide() == side ) - { - dlog.addText( Logger::ACTION, - __FILE__": agent->doAttentionto. already attended." ); - return false; - } + // if ( world().self().attentiontoUnum() == unum + // && world().self().attentiontoSide() == side ) + // { + // dlog.addText( Logger::ACTION, + // __FILE__": agent->doAttentionto. already attended." ); + // return false; + // } M_effector.setAttentionto( side, unum ); return true; @@ -3157,6 +3280,23 @@ PlayerAgent::setViewAction( ViewAction * act ) } } +/*-------------------------------------------------------------------*/ +/*! + + */ +void +PlayerAgent::setFocusAction( FocusAction * act ) +{ + if ( act ) + { + M_impl->focus_action_ = std::shared_ptr< FocusAction >( act ); + } + else + { + M_impl->focus_action_.reset(); + } +} + /*-------------------------------------------------------------------*/ /*! diff --git a/rcsc/player/player_agent.h b/rcsc/player/player_agent.h index 06269ba..38080df 100644 --- a/rcsc/player/player_agent.h +++ b/rcsc/player/player_agent.h @@ -57,6 +57,7 @@ class SeeState; class SoccerIntention; class NeckAction; class ViewAction; +class FocusAction; class VisualSensor; /*! @@ -241,8 +242,6 @@ class PlayerAgent */ bool doMove( const double & x, const double & y ); - - bool doOmniDash( PlayerAgent * agent, Vector2D point ); /*! \brief register tackle command @@ -269,6 +268,14 @@ class PlayerAgent */ bool doChangeView( const ViewWidth & width ); + /*! + \brief register change_focus command + \param moment_dist distance added to the current focus point + \param moment_dir direction added to the current focus point + */ + bool doChangeFocus( const double moment_dist, + const AngleDeg & moment_dir ); + /* brief register say command. param msg message string @@ -325,6 +332,13 @@ class PlayerAgent */ void setViewAction( ViewAction * act ); + /*! + \brief reserve change_focus action + \param act pointer to the action. must be a dynamically allocated object. + */ + void setFocusAction( FocusAction * act ); + + /*! \brief add say message to the action effector \param message pointer to the dynamically allocated object. diff --git a/rcsc/player/player_command.cpp b/rcsc/player/player_command.cpp index 66a658a..21d96ce 100644 --- a/rcsc/player/player_command.cpp +++ b/rcsc/player/player_command.cpp @@ -220,6 +220,17 @@ PlayerChangeViewCommand::toCommandString( std::ostream & to ) const return to; } + +/*-------------------------------------------------------------------*/ +/*! + +*/ +std::ostream & +PlayerChangeFocusCommand::toCommandString( std::ostream & to ) const +{ + return to << "(change_focus " << M_moment_dist << ' ' << M_moment_dir << ')'; +} + /*-------------------------------------------------------------------*/ /*! diff --git a/rcsc/player/player_command.h b/rcsc/player/player_command.h index de01258..de320f4 100644 --- a/rcsc/player/player_command.h +++ b/rcsc/player/player_command.h @@ -66,6 +66,7 @@ class PlayerCommand { // support commands TURN_NECK, CHANGE_VIEW, + CHANGE_FOCUS, SAY, POINTTO, ATTENTIONTO, @@ -912,6 +913,81 @@ class PlayerChangeViewCommand } }; +////////////////////////////////////////////////////////////////////// +/*! + \class PlayerChangeFocusCommand + \brief player's change focus command + +
+  Format:
+  <- (change_focus  )
+  
+*/ +class PlayerChangeFocusCommand + : public PlayerSupportCommand { +private: + double M_moment_dist; //!< this value is added to the current focus distance, and the result is limited to [0.0, 40.0]. + double M_moment_dir; //!< this value is added to the current focus direction, and the result is limited to visible angle. + + PlayerChangeFocusCommand() = delete; // not used +public: + + /*! + \brief construct with command parameters + \param moment_dist moment for the distance + \param moment_dir moment for the direction + */ + PlayerChangeFocusCommand( const double moment_dist, + const double moment_dir ) + : M_moment_dist( moment_dist ), + M_moment_dir( moment_dir ) + { } + + /*! + \brief get command type + \return command type Id + */ + Type type() const + { + return CHANGE_FOCUS; + } + + /*! + \brief put command string to ostream + \param to reference to the output stream + \return reference to the output stream + */ + std::ostream & toCommandString( std::ostream & to ) const; + + /*! + \brief get thencommand name + \return command name string + */ + std::string name() const + { + return std::string( "change_focus" ); + } + + /*! + \brief get the command parameter + \return the value of moment distance + */ + double momentDist() const + { + return M_moment_dist; + } + + /*! + \brief get the command parameter + \return the value of moment direction + */ + double momentDir() const + { + return M_moment_dir; + } + +}; + ////////////////////////////////////////////////////////////////////// /*! \class PlayerSayCommand diff --git a/rcsc/player/player_config.cpp b/rcsc/player/player_config.cpp index b8b2113..d0c8f2b 100644 --- a/rcsc/player/player_config.cpp +++ b/rcsc/player/player_config.cpp @@ -148,6 +148,9 @@ PlayerConfig::setDefaultParam() // // debug logging // + M_debug_start_time = -1; + M_debug_end_time = 99999999; + M_debug_log_ext = ".log"; M_debug_system = false; @@ -239,6 +242,9 @@ PlayerConfig::createParamMap() ( "offline_log_ext", "", &M_offline_log_ext ) ( "offline_client_number", "", &M_offline_client_number ) + ( "debug_start_time", "", &M_debug_start_time ) + ( "debug_end_time", "", &M_debug_end_time ) + ( "debug_log_ext", "", &M_debug_log_ext ) ( "debug_system", "", BoolSwitch( &M_debug_system ) ) diff --git a/rcsc/player/player_config.h b/rcsc/player/player_config.h index dcf7dc8..d571da3 100644 --- a/rcsc/player/player_config.h +++ b/rcsc/player/player_config.h @@ -138,6 +138,9 @@ class PlayerConfig { // debug logging // + int M_debug_start_time; //!< the start time for recording the debug log + int M_debug_end_time; //!< the end time for recording the debug log + std::string M_debug_log_ext; //!< the extension string of debug log file bool M_debug_system; //!< debug level flag @@ -469,6 +472,18 @@ class PlayerConfig { // debug logging // + /*! + \brief get the start time for receoding the debug log + \return the start time for receoding the debug log + */ + int debugStartTime() const { return M_debug_start_time; } + + /*! + \brief get the end time for receoding the debug log + \return the end time for receoding the debug log + */ + int debugEndTime() const { return M_debug_end_time; } + /*! \brief get the debug log file extention string. \return the debug log file extention string. diff --git a/rcsc/player/see_state.cpp b/rcsc/player/see_state.cpp index f3016aa..97d452c 100644 --- a/rcsc/player/see_state.cpp +++ b/rcsc/player/see_state.cpp @@ -49,14 +49,15 @@ bool SeeState::S_synch_see_mode = false; */ SeeState::SeeState() - : M_current_time( -1, 0 ) - , M_last_see_time( -1, 0 ) - , M_synch_type( SYNCH_NO ) - , M_last_timing( TIME_NOSYNCH ) - , M_current_see_count( 0 ) - , M_cycles_till_next_see( 100 ) - , M_view_width( ViewWidth::NORMAL ) - , M_view_quality( ViewQuality::HIGH ) + : M_protocol_version( 1.0 ), + M_current_time( -1, 0 ), + M_last_see_time( -1, 0 ), + M_synch_type( SYNCH_NO ), + M_last_timing( TIME_NOSYNCH ), + M_current_see_count( 0 ), + M_cycles_till_next_see( 100 ), + M_view_width( ViewWidth::NORMAL ), + M_view_quality( ViewQuality::HIGH ) { for ( int i = 0; i < HISTORY_SIZE; i++ ) { @@ -222,11 +223,8 @@ SeeState::updateBySee( const GameTime & see_time, // see timing is synchronized. // - if ( M_cycles_till_next_see > 0 ) - { - M_cycles_till_next_see = 0; - setViewMode( vw, vq ); - } + // update M_cycles_till_next_see and M_synch_type according to the current view mode + setViewMode( vw, vq ); // update current see arrival timing. Timing new_timing = getNextTiming( vw, vq ); @@ -271,7 +269,7 @@ SeeState::setNewCycle( const GameTime & new_time ) #ifdef DEBUG_PRINT dlog.addText( Logger::SYSTEM, - __FILE__" (updateBySee) set new cycle. cycle till next see = %d", + __FILE__" (setNewCycle) set new cycle. cycle till next see = %d", M_cycles_till_next_see ); #endif } @@ -435,15 +433,6 @@ void SeeState::setViewMode( const ViewWidth & new_width, const ViewQuality & new_quality ) { -// if ( M_last_see_time != M_current_time ) -// { -// #ifdef DEBUG_PRINT -// dlog.addText( Logger::SYSTEM, -// __FILE__" (setViewMode) no current cycle see arrival" ); -// #endif -// return; -// } - M_view_width = new_width; M_view_quality = new_quality; @@ -478,6 +467,15 @@ SeeState::setViewMode( const ViewWidth & new_width, break; } +// if ( M_protocol_version >= 18.0 ) +// { +// M_cycles_till_next_see = 1; +// #ifdef DEBUG_PRINT +// dlog.addText( Logger::SYSTEM, +// __FILE__" (setViewMode) v18+: cycle = 1" ); +// #endif +// } + return; } diff --git a/rcsc/player/see_state.h b/rcsc/player/see_state.h index 9d0de4a..639b7aa 100644 --- a/rcsc/player/see_state.h +++ b/rcsc/player/see_state.h @@ -76,9 +76,10 @@ class SeeState { HISTORY_SIZE = 3 }; - //double M_protocol_version; static bool S_synch_see_mode; + double M_protocol_version; + GameTime M_current_time; //!< update when new cycle detected GameTime M_last_see_time; //!< last see arrival game time @@ -111,6 +112,19 @@ class SeeState { S_synch_see_mode = true; } + /*! + \brief set the protocl version number + \param ver the version number + */ + void setProtocolVersion( const double ver ) + { + M_protocol_version = ver; + if ( ver >= 18.0 ) + { + S_synch_see_mode = true; + } + } + /*! \brief static method. get the status of synch_see \return the status of synch_see @@ -245,7 +259,7 @@ class SeeState { \param new_width new view width \param new_quality new view quality - This method MUST be called just after change_view command sent and + This method MUST be called just after sending change_view command and only when current cycle see message is received */ void setViewMode( const ViewWidth & new_width, diff --git a/rcsc/player/self_object.cpp b/rcsc/player/self_object.cpp index 6793095..a9eff43 100644 --- a/rcsc/player/self_object.cpp +++ b/rcsc/player/self_object.cpp @@ -174,6 +174,24 @@ SelfObject::faceValid() const return M_face_count < S_face_count_thr; } +/*-------------------------------------------------------------------*/ +Vector2D +SelfObject::focusPoint() const +{ + if ( ! posValid() + || ! faceValid() ) + { + return Vector2D::INVALIDATED; + } + + Vector2D result = pos(); + if ( focusDist() > 1.0e-10 ) + { + result += Vector2D::from_polar( focusDist(), face() + focusDir() ); + } + return result; +} + /*-------------------------------------------------------------------*/ /*! @@ -483,6 +501,9 @@ SelfObject::updateAfterSenseBody( const BodySensor & sense, M_view_width = sense.viewWidth(); M_view_quality = sense.viewQuality(); + M_focus_dist = sense.focusDist(); + M_focus_dir = sense.focusDir(); + //////////////////////////////////////////////////// // stamina M_stamina.updateBySenseBody( sense.stamina(), diff --git a/rcsc/player/self_object.h b/rcsc/player/self_object.h index 5c25d74..befd111 100644 --- a/rcsc/player/self_object.h +++ b/rcsc/player/self_object.h @@ -76,6 +76,9 @@ class SelfObject ViewWidth M_view_width; //!< current view width type ViewQuality M_view_quality; //!< current view quality type + double M_focus_dist; //!< the distance to the current focus point + AngleDeg M_focus_dir; //!< the direction to the current focus point + StaminaModel M_stamina; //!< current stamina info // some action effect @@ -267,6 +270,32 @@ class SelfObject return M_view_quality; } + /*! + \brief get the focus distance updated by the sense_body message + \return the distance to the focus point + */ + double focusDist() const + { + return M_focus_dist; + } + + /*! + \brief get the focus direction updated by the sense_body message + \return the value of focus direction + \return the direction to the focus point, relative to the body angle + */ + + const AngleDeg & focusDir() const + { + return M_focus_dir; + } + + /*! + \brief get the estimated focus point according to the self localization result + \return the global coordinates of the estimated focus point + */ + Vector2D focusPoint() const; + /*! \brief get time when the last catch command is performed \return const reference to the time object diff --git a/rcsc/player/soccer_action.h b/rcsc/player/soccer_action.h index 798ca2d..dc60996 100644 --- a/rcsc/player/soccer_action.h +++ b/rcsc/player/soccer_action.h @@ -227,6 +227,55 @@ class ViewAction ///////////////////////////////////////////////////////////////////// +/*! + \class FocusAction + \brief abstract change_focus action + */ +class FocusAction + : public AbstractAction { +public: + + typedef std::shared_ptr< FocusAction > Ptr; +private: + + //! not used + FocusAction( const FocusAction & ) = delete; + //! not used + FocusAction & operator=( const FocusAction & ) = delete; + +protected: + + /*! + \brief nothing to do. but accessible only from derived classes. + */ + FocusAction() = default; + +public: + /*! + \brief nothing to do, but should be a virtual method. + */ + virtual + ~FocusAction() = default; + + /*! + \brief pure virtual. set command to the action effector + \retval true if action is performed + \retval false if action is failed or not needed. + */ + virtual + bool execute( PlayerAgent * agent ) = 0; + + /*! + \brief create cloned action object + \return pointer to the cloned object instance. + */ + virtual + FocusAction * clone() const = 0; + +}; + +///////////////////////////////////////////////////////////////////// + /*! \class ArmAction \brief abstract pointto action diff --git a/rcsc/player/view_grid_map.cpp b/rcsc/player/view_grid_map.cpp index 6e5e4e1..969a3f9 100644 --- a/rcsc/player/view_grid_map.cpp +++ b/rcsc/player/view_grid_map.cpp @@ -42,49 +42,29 @@ #include #include -// #define USE_VECTOR -// #define USE_MULTI_ARRAY - -#ifdef USE_VECTOR -# include -#elif USE_MULTY_ARRAY -# include -#endif +#include #include #include #include #define DEBUG_PROFILE -// #define DEBUG_PRINT -// #define DEBUG_PRINT_TEXT -// #define DEBUG_PAINT_GRID_MAP +#define DEBUG_PRINT namespace rcsc { -const double ViewGridMap::GRID_LENGTH = 2.0; - -const double ViewGridMap::PITCH_MIN_X = ( std::ceil( ( -ServerParam::DEFAULT_PITCH_LENGTH*0.5 + 1.5 ) - / ViewGridMap::GRID_LENGTH ) - * ViewGridMap::GRID_LENGTH ); -const double ViewGridMap::PITCH_MAX_X = ( std::floor( ( +ServerParam::DEFAULT_PITCH_LENGTH*0.5 - 0.5 ) - / ViewGridMap::GRID_LENGTH ) - * ViewGridMap::GRID_LENGTH ); -const double ViewGridMap::PITCH_LENGTH = ViewGridMap::PITCH_MAX_X - ViewGridMap::PITCH_MIN_X; +const double ViewGridMap::GRID_LENGTH = 1.0; -const double ViewGridMap::PITCH_MIN_Y = ( std::ceil( ( -ServerParam::DEFAULT_PITCH_WIDTH*0.5 + 1.5 ) - / ViewGridMap::GRID_LENGTH ) +const double ViewGridMap::PITCH_MAX_X = ( std::ceil( ( +ServerParam::DEFAULT_PITCH_LENGTH*0.5 - 3.0 ) / ViewGridMap::GRID_LENGTH ) * ViewGridMap::GRID_LENGTH ); -const double ViewGridMap::PITCH_MAX_Y = ( std::floor( ( +ServerParam::DEFAULT_PITCH_WIDTH*0.5 - 1.5 ) - / ViewGridMap::GRID_LENGTH ) +const double ViewGridMap::PITCH_MAX_Y = ( std::ceil( ( +ServerParam::DEFAULT_PITCH_WIDTH*0.5 - 3.0 ) / ViewGridMap::GRID_LENGTH ) * ViewGridMap::GRID_LENGTH ); -const double ViewGridMap::PITCH_WIDTH = ViewGridMap::PITCH_MAX_Y - ViewGridMap::PITCH_MIN_Y; +const double ViewGridMap::PITCH_LENGTH = ViewGridMap::PITCH_MAX_X * 2.0; +const double ViewGridMap::PITCH_WIDTH = ViewGridMap::PITCH_MAX_Y * 2.0; -const int ViewGridMap::GRID_X_SIZE -= static_cast< int >( std::ceil( ViewGridMap::PITCH_LENGTH / ViewGridMap::GRID_LENGTH ) ) + 1; -const int ViewGridMap::GRID_Y_SIZE -= static_cast< int >( std::ceil( ViewGridMap::PITCH_WIDTH / ViewGridMap::GRID_LENGTH ) ) + 1; +const int ViewGridMap::GRID_X_SIZE = static_cast< int >( std::ceil( ViewGridMap::PITCH_LENGTH / ViewGridMap::GRID_LENGTH ) ) + 1; +const int ViewGridMap::GRID_Y_SIZE = static_cast< int >( std::ceil( ViewGridMap::PITCH_WIDTH / ViewGridMap::GRID_LENGTH ) ) + 1; const double ViewGridMap::GRID_RADIUS = ViewGridMap::GRID_LENGTH*0.5 * std::sqrt( 2.0 ); @@ -93,134 +73,74 @@ namespace { inline int -grid_x_index( const double & x ) +grid_x_index( const double x ) { - int ix = static_cast< int >( std::ceil( ( x - ViewGridMap::PITCH_MIN_X ) + int ix = static_cast< int >( std::ceil( ( x + ViewGridMap::PITCH_MAX_X ) / ViewGridMap::GRID_LENGTH ) ); return bound( 0, ix, ViewGridMap::GRID_X_SIZE ); } inline int -grid_y_index( const double & y ) +grid_y_index( const double y ) { - int iy = static_cast< int >( std::ceil( ( y - ViewGridMap::PITCH_MIN_Y ) + int iy = static_cast< int >( std::ceil( ( y + ViewGridMap::PITCH_MAX_Y ) / ViewGridMap::GRID_LENGTH ) ); return bound( 0, iy, ViewGridMap::GRID_Y_SIZE ); } -#if 0 inline int grid_index( const Vector2D & pos ) { - int ix = static_cast< int >( std::ceil( ( pos.x - ViewGridMap::PITCH_MIN_X ) + int ix = static_cast< int >( std::ceil( ( pos.x + ViewGridMap::PITCH_MAX_X ) / ViewGridMap::GRID_LENGTH ) ); - int iy = static_cast< int >( std::ceil( ( pos.y - ViewGridMap::PITCH_MIN_Y ) + int iy = static_cast< int >( std::ceil( ( pos.y + ViewGridMap::PITCH_MAX_Y ) / ViewGridMap::GRID_LENGTH ) ); - ix = bound( 0, ix, ViewGridMap::GRID_X_SIZE ); - iy = bound( 0, iy, ViewGridMap::GRID_Y_SIZE ); + ix = bound( 0, ix, ViewGridMap::GRID_X_SIZE - 1 ); + iy = bound( 0, iy, ViewGridMap::GRID_Y_SIZE - 1 ); return ix * ViewGridMap::GRID_Y_SIZE + iy; } inline Vector2D -grid_center( const int idx ) +grid_center( const int ix, + const int iy ) { - int ix = idx / ViewGridMap::GRID_Y_SIZE; - int iy = idx % ViewGridMap::GRID_Y_SIZE; - - return Vector2D( ix * ViewGridMap::GRID_LENGTH + ViewGridMap::PITCH_MIN_X, - iy * ViewGridMap::GRID_LENGTH + ViewGridMap::PITCH_MIN_Y ); + return Vector2D( ix * ViewGridMap::GRID_LENGTH - ViewGridMap::PITCH_MAX_X, + iy * ViewGridMap::GRID_LENGTH - ViewGridMap::PITCH_MAX_Y ); } -#endif inline Vector2D -grid_center( const int ix, - const int iy ) +grid_center( const int idx ) { - return Vector2D( ix * ViewGridMap::GRID_LENGTH + ViewGridMap::PITCH_MIN_X, - iy * ViewGridMap::GRID_LENGTH + ViewGridMap::PITCH_MIN_Y ); + return grid_center( idx / ViewGridMap::GRID_Y_SIZE, + idx % ViewGridMap::GRID_Y_SIZE ); } } /////////////////////////////////////////////////////////////////////// -/*! - -*/ -struct ViewGridMap::Impl { - -#ifdef USE_VECTOR - std::vector< int > grid_map_; -#elif defined (USE_MULTI_ARRAY) - boost::multi_array< int, 2 > grid_map_; -#else - int ** grid_map_; -#endif - - Impl() - : -#ifdef USE_VECTOR - grid_map_( ViewGridMap::GRID_X_SIZE * ViewGridMap::GRID_Y_SIZE, 0 ) -#elif defined (USE_MULTI_ARRAY) - grid_map_( boost::extents[ViewGridMap::GRID_X_SIZE][ViewGridMap::GRID_Y_SIZE] ) -#else - grid_map_( 0 ) -#endif - { -#ifdef USE_VECTOR - // do nothing -#elif defined (USE_MULTI_ARRAY) - for ( int x = 0; x < ViewGridMap::GRID_X_SIZE; ++x ) - { - for ( int y = 0; y < ViewGridMap::GRID_Y_SIZE; ++y ) - { - grid_map_[x][y] = 0; - } - } -#else - grid_map_ = new int*[ViewGridMap::GRID_X_SIZE]; - for ( int x = 0; x < ViewGridMap::GRID_X_SIZE; ++x ) - { - grid_map_[x] = new int[ViewGridMap::GRID_Y_SIZE]; - for ( int y = 0; y < ViewGridMap::GRID_Y_SIZE; ++y ) - { - grid_map_[x][y] = 0; - } - } -#endif - } - - ~Impl() - { -#ifdef USE_VECTOR - -#elif defined( USE_MULTI_ARRAY) - -#else - for ( int y = 0; y < ViewGridMap::GRID_Y_SIZE; ++y ) - { - delete [] grid_map_[y]; - } - - delete [] grid_map_; -#endif - } -}; /*-------------------------------------------------------------------*/ /*! */ ViewGridMap::ViewGridMap() - : M_impl( new ViewGridMap::Impl() ) { - // std::cerr << __FILE__"create ViewGridMap size=" << M_impl->grid_map_.size() - // << std::endl; + M_grid_map.reserve( GRID_X_SIZE * GRID_Y_SIZE ); + + for ( int x = 0; x < GRID_X_SIZE; ++x ) + { + for ( int y = 0; y < GRID_Y_SIZE; ++y ) + { + M_grid_map.emplace_back( grid_center( x, y ) ); + } + } + } /*-------------------------------------------------------------------*/ @@ -239,20 +159,10 @@ ViewGridMap::~ViewGridMap() void ViewGridMap::incrementAll() { -#ifdef USE_VECTOR - for ( int & v : M_impl->grid_map_ ) + for ( Grid & p : M_grid_map ) { - v += 1; + p.seen_count_ += 1; } -#else - for ( int x = 0; x < ViewGridMap::GRID_X_SIZE; ++x ) - { - for ( int y = 0; y < ViewGridMap::GRID_Y_SIZE; ++y ) - { - M_impl->grid_map_[x][y] += 1; - } - } -#endif } /*-------------------------------------------------------------------*/ @@ -271,20 +181,6 @@ ViewGridMap::update( const GameTime & time, } s_update_time = time; -#ifdef DEBUG_PRINT - dlog.addText( Logger::WORLD, - __FILE__" PITCH_MIN_X=%.1f PITCH_MAX_X=%.1f GRID_X_SIZE=%d", - PITCH_MIN_X, PITCH_MAX_X, - GRID_X_SIZE ); - dlog.addText( Logger::WORLD, - __FILE__" PITCH_MIN_Y=%.1f PITCH_MAX_Y=%.1f GRID_Y_SIZE=%d", - PITCH_MIN_Y, PITCH_MAX_Y, - GRID_Y_SIZE ); - dlog.addText( Logger::WORLD, - __FILE__" grid map size=%d", - M_impl->grid_map_.size() ); -#endif - #ifdef DEBUG_PROFILE Timer timer; @@ -295,101 +191,35 @@ ViewGridMap::update( const GameTime & time, return; } - const AngleDeg left_angle = view_area.angle() - view_area.viewWidth() * 0.5; - const AngleDeg right_angle = view_area.angle() + view_area.viewWidth() * 0.5; + const AngleDeg left_angle = view_area.angle() - view_area.viewWidth() * 0.5 + 2.0; + const AngleDeg right_angle = view_area.angle() + view_area.viewWidth() * 0.5 - 2.0; - static const double VISIBLE_DIST = ServerParam::i().visibleDistance() - GRID_RADIUS; + static const double VISIBLE_DIST = ServerParam::i().visibleDistance() - 0.5; -#ifdef USE_VECTOR - int i = 0; - const std::vector< int >::iterator end = M_impl->grid_map_.end(); - for ( std::vector< int >::iterator v = M_impl->grid_map_.begin(); - v != end; - ++v, ++i ) + for ( Grid & p : M_grid_map ) { - int & value = *v;; - Vector2D pos = grid_center( i ); -#else - for ( int ix = 0; ix < ViewGridMap::GRID_X_SIZE; ++ix ) + const double dist = view_area.origin().dist( p.center_ ); + if ( dist < VISIBLE_DIST ) + { + p.seen_count_ = 0; + } + else { - for ( int iy = 0; iy < ViewGridMap::GRID_Y_SIZE; ++iy ) + const AngleDeg angle = ( p.center_ - view_area.origin() ).th(); + if ( angle.isRightOf( left_angle ) + && angle.isLeftOf( right_angle ) ) { - int & value = M_impl->grid_map_[ix][iy]; - Vector2D pos = grid_center( ix, iy ); -#endif - - double dist = view_area.origin().dist( pos ); - if ( dist > VISIBLE_DIST ) - { - AngleDeg angle = ( pos - view_area.origin() ).th(); - if ( angle.isRightOf( left_angle ) - && angle.isLeftOf( right_angle ) ) - { - double angle_thr = AngleDeg::asin_deg( GRID_RADIUS / dist ); - if ( ( angle - left_angle ).abs() > angle_thr - && ( angle - right_angle ).abs() > angle_thr ) - { - value = 0; - } - - } - } -#ifdef DEBUG_PRINT_TEXT -# ifdef USE_VECTOR - dlog.addText( Logger::WORLD, - __FILE__" %05d (%04d %04d) pos=(%.2f %.2f) -> %d | count=%d", - i, - i / ViewGridMap::GRID_Y_SIZE, - i % ViewGridMap::GRID_Y_SIZE, - pos.x, pos.y, - grid_index( pos ), - *v ); - if ( grid_index( pos ) != i ) - { - dlog.addText( Logger::WORLD, - __FILE__"---> index mismatch" ); - } -# else - dlog.addText( Logger::WORLD, - __FILE__" (%03d %03d) pos=(%.2f %.2f) -> (%d %d) | count=%d", - ix, iy, - pos.x, pos.y, - grid_x_index( pos.x ), grid_y_index( pos.y ), - value ); - if ( ix != grid_x_index( pos.x ) - || iy != grid_y_index( pos.y ) ) - { - dlog.addText( Logger::WORLD, - __FILE__"---> index mismatch" ); - } -# endif -#endif -#ifdef DEBUG_PAINT_GRID_MAP - // int vv = std::max( 0, 255 - *v * 20 ); - int vv = std::max( 0, 255 - value * 20 ); - dlog.addRect( Logger::WORLD, - pos.x - GRID_LENGTH*0.125, pos.y - GRID_LENGTH*0.125, - GRID_LENGTH*0.25, GRID_LENGTH*0.25, - vv, vv, vv, - true ); -#endif -#ifndef USE_VECTOR + p.seen_count_ = 0; } } -#else + } -#endif #ifdef DEBUG_PROFILE dlog.addText( Logger::WORLD, __FILE__" (update) PROFILE elapsed %f [ms] grid_size=%d", timer.elapsedReal(), -#ifdef USE_VECTOR - M_impl->grid_map_.size() -#else - GRID_X_SIZE * GRID_Y_SIZE -#endif - ); + M_grid_map.size() ); #endif } @@ -398,23 +228,34 @@ ViewGridMap::update( const GameTime & time, */ int -ViewGridMap::seenCount( const Vector2D & pos ) +ViewGridMap::seenCount( const Vector2D & pos ) const { -#ifdef USE_VECTOR - return M_impl->grid_map_.at( grid_index( pos ) ); - // try - // { - // return M_impl->grid_map_.at( grid_index( pos ) ); - // } - // catch ( std::exception & e ) - // { - // std::cerr << __FILE__ ": exception caught! " << e.what() - // << std::endl; - // return 1000; - // } -#else - return M_impl->grid_map_[grid_x_index( pos.x )][grid_y_index( pos.y )]; -#endif + try + { + return M_grid_map.at( grid_index( pos ) ).seen_count_; + } + catch ( std::exception & e ) + { + std::cerr << __FILE__ ": out of the grid range " << pos + << " " << e.what() + << std::endl; + return 1000; + } +} + +/*-------------------------------------------------------------------*/ +void +ViewGridMap::debugOutput() const +{ + for ( const Grid & p : M_grid_map ) + { + const int col = std::max( 0, 255 - p.seen_count_ * 20 ); + dlog.addRect( Logger::WORLD, + p.center_.x - GRID_LENGTH*0.05, p.center_.y - GRID_LENGTH*0.05, + GRID_LENGTH*0.1, GRID_LENGTH*0.1, + col, col, col, + true ); + } } } diff --git a/rcsc/player/view_grid_map.h b/rcsc/player/view_grid_map.h index 8a6e944..7c3519f 100644 --- a/rcsc/player/view_grid_map.h +++ b/rcsc/player/view_grid_map.h @@ -32,12 +32,14 @@ #ifndef RCSC_PLAYER_VIEW_GRID_MAP_H #define RCSC_PLAYER_VIEW_GRID_MAP_H -#include +#include + +#include +#include namespace rcsc { class GameTime; -class Vector2D; class ViewArea; /*! @@ -45,22 +47,32 @@ class ViewArea; \brief grid map that stores field accuracy information */ class ViewGridMap { -private: +public: + + struct Grid { + const rcsc::Vector2D center_; + int seen_count_; - struct Impl; + Grid() = delete; + + explicit + Grid( const rcsc::Vector2D & center ) + : center_( center ), + seen_count_( 0 ) + { } + }; + +private: - std::unique_ptr< Impl > M_impl; + std::vector< Grid > M_grid_map; public: static const double GRID_LENGTH; - static const double PITCH_MIN_X; static const double PITCH_MAX_X; - static const double PITCH_LENGTH; - - static const double PITCH_MIN_Y; static const double PITCH_MAX_Y; + static const double PITCH_LENGTH; static const double PITCH_WIDTH; static const int GRID_X_SIZE; @@ -91,12 +103,22 @@ class ViewGridMap { void update( const GameTime & time, const ViewArea & view_area ); + const std::vector< Grid > & gridMap() const + { + return M_grid_map; + } + /*! \brief get the count since last observation \param pos target point \return count value */ - int seenCount( const Vector2D & pos ); + int seenCount( const Vector2D & pos ) const; + + /*! + \brief output the debug data + */ + void debugOutput() const; }; diff --git a/rcsc/player/world_model.cpp b/rcsc/player/world_model.cpp index 4c96939..369998d 100644 --- a/rcsc/player/world_model.cpp +++ b/rcsc/player/world_model.cpp @@ -41,7 +41,6 @@ #include "visual_sensor.h" #include "fullstate_sensor.h" #include "debug_client.h" -#include "intercept_table.h" #include "penalty_kick_state.h" #include "player_command.h" #include "player_predicate.h" @@ -60,8 +59,8 @@ #include #include -#define DEBUG_PROFILE -#define DEBUG_PRINT +// #define DEBUG_PROFILE +// #define DEBUG_PRINT // #define DEBUG_PRINT_SELF_UPDATE // #define DEBUG_PRINT_BALL_UPDATE @@ -72,8 +71,7 @@ // #define DEBUG_PRINT_LINES // #define DEBUG_PRINT_LAST_KICKER - -// #defin USE_VIEW_GRID_MAP +#define USE_VIEW_GRID_MAP namespace rcsc { @@ -356,8 +354,9 @@ const double WorldModel::DIR_STEP = 360.0 / static_cast< double >( DIR_CONF_DIVS */ WorldModel::WorldModel() - : M_localize( new LocalizationDefault() ), - M_intercept_table( new InterceptTable( *this ) ), + : M_client_version( 8 ), + M_localize(), + M_intercept_table(), M_audio_memory( new AudioMemory() ), M_penalty_kick_state( new PenaltyKickState() ), M_our_side( NEUTRAL ), @@ -398,7 +397,6 @@ WorldModel::WorldModel() M_last_kicker_unum( Unum_Unknown ), M_view_area_cont( MAX_RECORD, ViewArea() ) { - assert( M_intercept_table ); assert( M_penalty_kick_state ); for ( int i = 0; i < 11; ++i ) @@ -427,12 +425,6 @@ WorldModel::WorldModel() */ WorldModel::~WorldModel() { - if ( M_intercept_table ) - { - delete M_intercept_table; - M_intercept_table = nullptr; - } - if ( M_penalty_kick_state ) { delete M_penalty_kick_state; @@ -448,7 +440,8 @@ bool WorldModel::init( const std::string & teamname, const SideID ourside, const int my_unum, - const bool my_goalie ) + const bool my_goalie, + const double client_version ) { if ( ! M_localize ) { @@ -468,6 +461,8 @@ WorldModel::init( const std::string & teamname, return false; } + M_client_version = client_version; + M_our_team_name = teamname; M_our_side = ourside; M_self.init( ourside, my_unum, my_goalie ); @@ -509,17 +504,6 @@ WorldModel::setValid( bool is_valid ) M_valid = is_valid; } -/*-------------------------------------------------------------------*/ -/*! - - */ -const -InterceptTable * -WorldModel::interceptTable() const -{ - return M_intercept_table; -} - /*-------------------------------------------------------------------*/ /*! @@ -2100,9 +2084,9 @@ WorldModel::updateJustBeforeDecision( const ActionEffector & act, estimateMaybeKickableTeammate(); M_self.updateKickableState( M_ball, - M_intercept_table->selfReachCycle(), - M_intercept_table->teammateReachCycle(), - M_intercept_table->opponentReachCycle() ); + interceptTable().selfStep(), + interceptTable().teammateStep(), + interceptTable().opponentStep() ); } /*-------------------------------------------------------------------*/ @@ -2222,7 +2206,7 @@ WorldModel::localizeSelf( const VisualSensor & see, Vector2D my_pos_error( 0.0, 0.0 ); // estimate self face angle - if ( ! M_localize->estimateSelfFace( see, &angle_face, &angle_face_error ) ) + if ( ! M_localize->estimateSelfFace( *this, see, &angle_face, &angle_face_error ) ) { return false; } @@ -2245,7 +2229,7 @@ WorldModel::localizeSelf( const VisualSensor & see, // estimate self position - if ( ! M_localize->localizeSelf( see, act, this->self().playerTypePtr(), + if ( ! M_localize->localizeSelf( *this, see, act, angle_face, angle_face_error, &my_pos, &my_pos_error ) ) { @@ -2316,7 +2300,7 @@ WorldModel::localizeBall( const VisualSensor & see, Vector2D rvel( Vector2D::INVALIDATED ); Vector2D vel_error( 0.0, 0.0 ); - if ( ! M_localize->localizeBallRelative( see, act, + if ( ! M_localize->localizeBallRelative( *this, see, self().face().degree(), self().faceError(), &rpos, &rpos_error, &rvel, &vel_error ) ) @@ -2394,12 +2378,17 @@ WorldModel::localizeBall( const VisualSensor & see, gvel = self().vel() + rvel; vel_error += self().velError(); vel_count = 0; +#ifdef DEBUG_PRINT_BALL_UPDATE + dlog.addText( Logger::WORLD, + __FILE__" (localizeBall) self_vel=(%.3f %.3f) ball_rvel=(%.3f %.3f) r=%.3f th=%.1f gvel=(%.3f %.3f)", + self().vel().x, self().vel().y, rvel.x, rvel.y, rvel.r(), rvel.th().degree(), gvel.x, gvel.y ); +#endif } ////////////////////////////////////////////////////////////////// // calc global velocity using rpos diff (if ball is out of view cone and within vis_dist) - if ( ! gvel.isValid() ) + //if ( ! gvel.isValid() ) { estimateBallVelByPosDiff( see, act, rpos, rpos_error, gvel, vel_error, vel_count ); @@ -2540,6 +2529,12 @@ WorldModel::estimateBallVelByPosDiff( const VisualSensor & see, tmp_vel *= ServerParam::i().ballDecay(); tmp_vel_error *= ServerParam::i().ballDecay(); + // collision + // if ( self().collidesWithBall() ) + // { + // tmp_vel *= -0.1; + // tmp_vel_error *= 0.1; + // } #ifdef DEBUG_PRINT_BALL_UPDATE dlog.addText( Logger::WORLD, "________ rpos(%.3f %.3f) prev_rpos(%.3f %.3f)", @@ -2582,12 +2577,28 @@ WorldModel::estimateBallVelByPosDiff( const VisualSensor & see, dlog.addText( Logger::WORLD, __FILE__" (estimateBallVelByPosDiff) update" ); #endif - vel = tmp_vel; - vel_error = tmp_vel_error; - vel_count = 1; + if ( ! vel.isValid() ) + { + vel = tmp_vel; + vel_error = tmp_vel_error; + vel_count = 1; + } + else + { + // the player has observed the ball velocity by see message + if ( ! self().collidesWithBall() + && prevBall().rpos().r2() < std::pow( ServerParam::i().visibleDistance() - 0.2, 2 ) + && tmp_vel.r() * 0.5 < vel.r() ) // if the ball collides with other players, the seen vel would be much smaller. + { + vel = tmp_vel; + vel_error = tmp_vel_error; + vel_count = 1; + } + } } } - else if ( ball().rposCount() == 2 ) + else if ( ! vel.isValid() + && ball().rposCount() == 2 ) { #ifdef DEBUG_PRINT_BALL_UPDATE dlog.addText( Logger::WORLD, @@ -2655,7 +2666,8 @@ WorldModel::estimateBallVelByPosDiff( const VisualSensor & see, } } - else if ( ball().rposCount() == 3 ) + else if ( ! vel.isValid() + && ball().rposCount() == 3 ) { #ifdef DEBUG_PRINT_BALL_UPDATE dlog.addText( Logger::WORLD, @@ -2810,7 +2822,8 @@ WorldModel::localizePlayers( const VisualSensor & see ) for ( const VisualSensor::PlayerT & p : see.opponents() ) { Localization::PlayerT player; - if ( ! M_localize->localizePlayer( p, + if ( ! M_localize->localizePlayer( *this, + p, MY_FACE, MY_FACE_ERR, MYPOS, MYVEL, &player ) ) { @@ -2844,7 +2857,8 @@ WorldModel::localizePlayers( const VisualSensor & see ) for ( const VisualSensor::PlayerT & p : see.unknownOpponents() ) { Localization::PlayerT player; - if ( ! M_localize->localizePlayer( p, + if ( ! M_localize->localizePlayer( *this, + p, MY_FACE, MY_FACE_ERR, MYPOS, MYVEL, &player ) ) { @@ -2875,7 +2889,8 @@ WorldModel::localizePlayers( const VisualSensor & see ) for ( const VisualSensor::PlayerT & p : see.teammates() ) { Localization::PlayerT player; - if ( ! M_localize->localizePlayer( p, + if ( ! M_localize->localizePlayer( *this, + p, MY_FACE, MY_FACE_ERR, MYPOS, MYVEL, &player ) ) { @@ -2909,7 +2924,8 @@ WorldModel::localizePlayers( const VisualSensor & see ) for ( const VisualSensor::PlayerT & p : see.unknownTeammates() ) { Localization::PlayerT player; - if ( ! M_localize->localizePlayer( p, + if ( ! M_localize->localizePlayer( *this, + p, MY_FACE, MY_FACE_ERR, MYPOS, MYVEL, &player ) ) { @@ -2941,7 +2957,8 @@ WorldModel::localizePlayers( const VisualSensor & see ) { Localization::PlayerT player; // localize - if ( ! M_localize->localizePlayer( p, + if ( ! M_localize->localizePlayer( *this, + p, MY_FACE, MY_FACE_ERR, MYPOS, MYVEL, &player ) ) { @@ -4187,7 +4204,7 @@ WorldModel::estimateMaybeKickableTeammate() { dlog.addText( Logger::WORLD, __FILE__":(estimateMaybeKickableTeammate) heard pass kick" ); - s_previous_teammate_step = this->interceptTable()->teammateReachCycle(); + s_previous_teammate_step = this->interceptTable().teammateStep(); s_previous_time = this->time(); M_maybe_kickable_teammate = nullptr; return; @@ -4199,14 +4216,14 @@ WorldModel::estimateMaybeKickableTeammate() { dlog.addText( Logger::WORLD, __FILE__":(estimateMaybeKickableTeammate) found" ); - s_previous_teammate_step = 1; //this->interceptTable()->teammateReachCycle(); + s_previous_teammate_step = 1; //this->interceptTable().teammateStep(); s_previous_time = this->time(); M_maybe_kickable_teammate = t; return; } } - s_previous_teammate_step = this->interceptTable()->teammateReachCycle(); + s_previous_teammate_step = this->interceptTable().teammateStep(); s_previous_time = this->time(); dlog.addText( Logger::WORLD, @@ -4329,9 +4346,10 @@ WorldModel::updateOffsideLine() #if 1 // add 2013-06-18 - Vector2D ball_pos = ball().inertiaPoint( std::min( interceptTable()->selfReachStep(), - std::min( interceptTable()->teammateReachStep(), - interceptTable()->opponentReachStep() ) ) ); + Vector2D ball_pos = ball().inertiaPoint( std::min( { + interceptTable().selfStep(), + interceptTable().teammateStep(), + interceptTable().opponentStep() } ) ); if ( ball_pos.x > new_line ) { new_line = ball_pos.x; @@ -4567,7 +4585,7 @@ WorldModel::updateTheirOffenseLine() void WorldModel::updateTheirDefenseLine() { - double first = 0.0, second = 0.0; + double first_x = 0.0, second_x = 0.0; int first_count = 1000, second_count = 1000; const PlayerObject * first_player = nullptr; @@ -4576,11 +4594,47 @@ WorldModel::updateTheirDefenseLine() for ( const PlayerObject * p : M_opponents_from_self ) { // 2015-07-14 - const PlayerType * ptype = p->playerTypePtr(); - double x = p->pos().x; - double adjust = 0.0; - if ( x > ball().pos().x + 3.0 ) + // 2023-06-24 + double player_x = p->pos().x; + if ( p->posCount() > 0 + && player_x > ball().pos().x + 3.0 ) { + const PlayerType * ptype = p->playerTypePtr(); +#if 1 + Vector2D opponent_pos = p->pos(); + Vector2D opponent_vel = p->vel(); + Vector2D accel_unit = ( p->bodyCount() <= 3 + ? Vector2D::from_polar( 1.0, p->body() ) + : Vector2D( -1.0, 0.0 ) ); + const int max_count = std::min( 3, p->posCount() ); + // dlog.addText( Logger::WORLD, + // "(updateTheirDefenseLine) opponent=%d accel_unit=(%.3f %.3f) max_count=%d pos=(%.1f %.1f)", + // p->unum(), accel_unit.x, accel_unit.y, max_count, opponent_pos.x, opponent_pos.y ); + for ( int i = 0; i < max_count; ++i ) + { + if ( i == 0 + && p->bodyCount() <= 3 + && accel_unit.th().abs() < 160.0 ) + { + // turn + opponent_pos += opponent_vel; + opponent_vel *= ptype->playerDecay(); + accel_unit.assign( -1.0, 0.0 ); + continue; + } + opponent_vel += accel_unit * ( 0.7 * ( ServerParam::i().maxDashPower() * ptype->dashRate( ptype->effortMax() ) ) ); + opponent_pos += opponent_vel; + // dlog.addText( Logger::WORLD, + // "(updateTheirDefenseLine) opponent=%d accel_unit=(%.3f %.3f) loop=%d pos=(%.1f %.1f) vel=(%.2f %.2f)", + // p->unum(), accel_unit.x, accel_unit.y, i, opponent_pos.x, opponent_pos.y, + // opponent_vel.x, opponent_vel.y ); + opponent_vel *= ptype->playerDecay(); + } + player_x = opponent_pos.x; + dlog.addText( Logger::WORLD, + "(updateTheirDefenseLine) opponent=%d world_x=%.1f predict_x=%.1f", + p->unum(), p->pos().x, player_x ); +#else double rate = 0.1; if ( p->vel().x < -ptype->realSpeedMax()*ptype->playerDecay() * 0.8 || ball().pos().x > 25.0 ) @@ -4590,28 +4644,29 @@ WorldModel::updateTheirDefenseLine() // dlog.addText( Logger::WORLD, // "(updateTheirDefenseLine) %d rate=%.1f", // p->unum(), rate ); - adjust = rate * ptype->realSpeedMax() * std::min( 3, p->posCount() ); + double adjust = rate * ptype->realSpeedMax() * std::min( 3, p->posCount() ); + // dlog.addText( Logger::WORLD, + // "(updateTheirDefenseLine) %d x=%.1f adjust=%.1f", + // (*it)->unum(), x, adjust ); + player_x -= adjust; +#endif } - // dlog.addText( Logger::WORLD, - // "(updateTheirDefenseLine) %d x=%.1f adjust=%.1f", - // (*it)->unum(), x, adjust ); - x -= adjust; - if ( x > second ) + if ( player_x > second_x ) { - second = x; + second_x = player_x; second_count = p->posCount(); second_player = p; - if ( second > first ) + if ( second_x > first_x ) { - std::swap( first, second ); + std::swap( first_x, second_x ); std::swap( first_count, second_count ); std::swap( first_player, second_player ); } } } - double new_line = second; + double new_line = second_x; int count = second_count; // dlog.addText( Logger::WORLD, @@ -4623,12 +4678,12 @@ WorldModel::updateTheirDefenseLine() if ( 20.0 < ball().pos().x && ball().pos().x < ServerParam::i().theirPenaltyAreaLineX() ) { - if ( first < ServerParam::i().theirPenaltyAreaLineX() ) + if ( first_x < ServerParam::i().theirPenaltyAreaLineX() ) { // dlog.addText( Logger::WORLD, // "(updateTheirDefenseLine) no goalie. %.1f -> %.1f", // second, first ); - new_line = first; + new_line = first_x; count = 30; } } @@ -5223,13 +5278,13 @@ void WorldModel::updateInterceptTable() { // update interception table - M_intercept_table->update(); + M_intercept_table.update( *this ); if ( M_audio_memory->ourInterceptTime() == time() ) { for ( const AudioMemory::OurIntercept & v : M_audio_memory->ourIntercept() ) { - M_intercept_table->hearTeammate( v.interceptor_, v.cycle_ ); + M_intercept_table.hearTeammate( *this, v.interceptor_, v.cycle_ ); } } @@ -5238,14 +5293,14 @@ WorldModel::updateInterceptTable() { for ( const AudioMemory::OppIntercept & v : M_audio_memory->oppIntercept() ) { - M_intercept_table->hearOpponent( v.interceptor_, v.cycle_ ); + M_intercept_table.hearOpponent( *this, v.interceptor_, v.cycle_ ); } } - M_self.setBallReachStep( std::min( M_intercept_table->selfReachCycle(), - M_intercept_table->selfReachCycle() ) ); + M_self.setBallReachStep( std::min( interceptTable().selfStep(), + interceptTable().selfExhaustStep() ) ); - const std::map< const AbstractPlayerObject *, int > & m = M_intercept_table->playerMap(); + const std::map< const AbstractPlayerObject *, int > & m = interceptTable().playerMap(); for ( PlayerObject & p : M_teammates ) { diff --git a/rcsc/player/world_model.h b/rcsc/player/world_model.h index 54a7a67..59fe6a3 100644 --- a/rcsc/player/world_model.h +++ b/rcsc/player/world_model.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -53,7 +54,6 @@ class AudioMemory; class ActionEffector; class BodySensor; class FullstateSensor; -class InterceptTable; class Localization; class PenaltyKickState; class PlayerPredicate; @@ -78,8 +78,10 @@ class WorldModel { private: + double M_client_version; + std::shared_ptr< Localization > M_localize; //!< localization module - InterceptTable * M_intercept_table; //!< interception info table + InterceptTable M_intercept_table; //!< interception info table std::shared_ptr< AudioMemory > M_audio_memory; //!< heard deqinfo memory PenaltyKickState * M_penalty_kick_state; //!< penalty kick mode status @@ -219,6 +221,7 @@ class WorldModel { \param our_side our side ID \param unum my uniform number \param goalie true if I am goalie + \param client_version the client protocol version \return true if successfully initialized, false otherwise This method is called just after receive init reply @@ -226,7 +229,8 @@ class WorldModel { bool init( const std::string & team_name, const SideID our_side, const int unum, - const bool goalie ); + const bool goalie, + const double client_version ); /*! \brief get this world mode is valid or not @@ -240,11 +244,23 @@ class WorldModel { */ void setValid( bool is_valid ); + /*! + \brief get the client version. + \return the version numver + */ + double clientVersion() const + { + return M_client_version; + } + /*! \brief get intercept table \return const pointer to the intercept table instance */ - const InterceptTable * interceptTable() const; + const InterceptTable & interceptTable() const + { + return M_intercept_table; + } /*! \brief get penalty kick state diff --git a/rcsc/rcg/CMakeLists.txt b/rcsc/rcg/CMakeLists.txt index 1a4dff8..8c30f0f 100644 --- a/rcsc/rcg/CMakeLists.txt +++ b/rcsc/rcg/CMakeLists.txt @@ -6,13 +6,13 @@ add_library(rcsc_rcg OBJECT parser_v2.cpp parser_v3.cpp parser_v4.cpp - parser_v5.cpp serializer.cpp serializer_v1.cpp serializer_v2.cpp serializer_v3.cpp serializer_v4.cpp serializer_v5.cpp + serializer_v6.cpp util.cpp ) @@ -31,13 +31,13 @@ install(FILES parser_v2.h parser_v3.h parser_v4.h - parser_v5.h serializer.h serializer_v1.h serializer_v2.h serializer_v3.h serializer_v4.h serializer_v5.h + serializer_v6.h types.h util.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/rcsc/rcg diff --git a/rcsc/rcg/Makefile.am b/rcsc/rcg/Makefile.am index 0eb469e..8a45d8f 100644 --- a/rcsc/rcg/Makefile.am +++ b/rcsc/rcg/Makefile.am @@ -10,13 +10,13 @@ librcsc_rcg_la_SOURCES = \ parser_v2.cpp \ parser_v3.cpp \ parser_v4.cpp \ - parser_v5.cpp \ serializer.cpp \ serializer_v1.cpp \ serializer_v2.cpp \ serializer_v3.cpp \ serializer_v4.cpp \ serializer_v5.cpp \ + serializer_v6.cpp \ util.cpp librcsc_rcgincludedir = $(includedir)/rcsc/rcg @@ -29,17 +29,17 @@ librcsc_rcginclude_HEADERS = \ parser_v2.h \ parser_v3.h \ parser_v4.h \ - parser_v5.h \ serializer.h \ serializer_v1.h \ serializer_v2.h \ serializer_v3.h \ serializer_v4.h \ serializer_v5.h \ + serializer_v6.h \ types.h \ util.h -librcsc_rcg_la_LDFLAGS = -version-info 5:0:0 +librcsc_rcg_la_LDFLAGS = -version-info 6:0:0 #libXXXX_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) # 1. Start with version information of `0:0:0' for each libtool library. # diff --git a/rcsc/rcg/parser.cpp b/rcsc/rcg/parser.cpp index c4bbdcb..82f4434 100644 --- a/rcsc/rcg/parser.cpp +++ b/rcsc/rcg/parser.cpp @@ -41,7 +41,7 @@ #include "parser_v2.h" #include "parser_v3.h" #include "parser_v4.h" -#include "parser_v5.h" +//#include "parser_v5.h" namespace rcsc { namespace rcg { @@ -65,8 +65,6 @@ Parser::creators() Parser::Ptr Parser::create( std::istream & is ) { - Parser::Ptr ptr; - char header[5]; int version = REC_OLD_VERSION; @@ -74,7 +72,17 @@ Parser::create( std::istream & is ) if ( is.gcount() != 4 ) { - return ptr; + std::cerr << "(rcsc::rcg::Parser::create) no header." << std::endl; + return Parser::Ptr(); + } + + if ( header[0] == 'J' + && header[1] == 'S' + && header[2] == 'O' + && header[3] == 'N' ) + { + std::cerr << "(rcsc::rcg::Parser::create) JSON not supported." << std::endl; + return Parser::Ptr(); } if ( header[0] == 'U' @@ -84,12 +92,21 @@ Parser::create( std::istream & is ) version = static_cast< int >( header[3] ); } + std::cerr << "(rcsc::rcg::Parser::create) rcg version = " + << ( version == static_cast< int >( '0' ) + REC_VERSION_6 ? REC_VERSION_6 + : version == static_cast< int >( '0' ) + REC_VERSION_5 ? REC_VERSION_5 + : version == static_cast< int >( '0' ) + REC_VERSION_4 ? REC_VERSION_4 + : version ) + << std::endl; + + Parser::Ptr ptr; Parser::Creator creator; if ( Parser::creators().getCreator( creator, version ) ) { ptr = creator(); } - else if ( version == static_cast< int >( '0' ) + REC_VERSION_5 ) ptr = Parser::Ptr( new ParserV5() ); + else if ( version == static_cast< int >( '0' ) + REC_VERSION_6 ) ptr = Parser::Ptr( new ParserV4() ); + else if ( version == static_cast< int >( '0' ) + REC_VERSION_5 ) ptr = Parser::Ptr( new ParserV4() ); else if ( version == static_cast< int >( '0' ) + REC_VERSION_4 ) ptr = Parser::Ptr( new ParserV4() ); else if ( version == REC_VERSION_3 ) ptr = Parser::Ptr( new ParserV3() ); else if ( version == REC_VERSION_2 ) ptr = Parser::Ptr( new ParserV2() ); diff --git a/rcsc/rcg/parser_v4.cpp b/rcsc/rcg/parser_v4.cpp index 556d938..fd59628 100644 --- a/rcsc/rcg/parser_v4.cpp +++ b/rcsc/rcg/parser_v4.cpp @@ -69,13 +69,25 @@ ParserV4::parse( std::istream & is, // skip header line if ( ! std::getline( is, line ) - || line != "ULG4" ) + || line.length() < 4 + || line.compare( 0, 3, "ULG" ) != 0 ) { + std::cerr << "Unknown header line: [" << line << "]" << std::endl; return false; } - if ( ! handler.handleLogVersion( REC_VERSION_4 ) ) + const int version = std::stoi( line.substr( 3 ) ); + if ( version != REC_VERSION_4 + && version != REC_VERSION_5 + && version != REC_VERSION_6 ) { + std::cerr << "Unsupported rcg version: [" << line << "]" << std::endl; + return false; + } + + if ( ! handler.handleLogVersion( version ) ) + { + std::cerr << "Unsupported game log version: [" << line << "]" << std::endl; return false; } @@ -512,7 +524,7 @@ ParserV4::parseShow( const int n_line, p.neck_ = strtof( buf, &next ); buf = next; while ( *buf == ' ' ) ++buf; - // x y vx vy body neck + // arm if ( *buf != '\0' && *buf != '(' ) { p.point_x_ = strtof( buf, &next ); buf = next; @@ -525,13 +537,30 @@ ParserV4::parseShow( const int n_line, while ( *buf == ' ' ) ++buf; p.view_quality_ = *buf; ++buf; p.view_width_ = strtof( buf, &next ); buf = next; + while ( *buf == ' ' || *buf == ')' ) ++buf; + + // (fp dist dir) + // focus point is introduced in the monitor protocol v6 + if ( ! std::strncmp( buf, "(fp ", 4 ) ) + { + buf += 4; + p.focus_dist_ = strtof( buf, &next ); buf = next; + p.focus_dir_ = strtof( buf, &next ); buf = next; + while ( *buf == ' ' || *buf == ')' ) ++buf; + } - // (s stamina effort recovery) + // (s stamina effort recovery[ capacity]) + // capacity is introduced in the monitor protocol v5 while ( *buf != '\0' && *buf != 's' ) ++buf; ++buf; // skip 's' //while ( *buf != '\0' && *buf != ' ' ) ++buf; p.stamina_ = strtof( buf, &next ); buf = next; p.effort_ = strtof( buf, &next ); buf = next; p.recovery_ = strtof( buf, &next ); buf = next; + while ( *buf == ' ' ) ++buf; + if ( *buf != ')' ) + { + p.stamina_capacity_ = strtof( buf, &next ); buf = next; + } while ( *buf != '\0' && *buf != ')' ) ++buf; while ( *buf == ')' ) ++buf; @@ -563,6 +592,12 @@ ParserV4::parseShow( const int n_line, p.tackle_count_ = static_cast< UInt16 >( std::strtol( buf, &next, 10 ) ); buf = next; p.pointto_count_ = static_cast< UInt16 >( std::strtol( buf, &next, 10 ) ); buf = next; p.attentionto_count_ = static_cast< UInt16 >( std::strtol( buf, &next, 10 ) ); buf = next; + while ( *buf == ' ' ) ++buf; + if ( *buf != ')' ) + { + p.change_focus_count_ = static_cast< UInt16 >( std::strtol( buf, &next, 10 ) ); buf = next; + } + while ( *buf == ')' ) ++buf; while ( *buf == ' ' ) ++buf; @@ -776,9 +811,12 @@ create_v4() return ptr; } -const int version = static_cast< int >( '0' ) + REC_VERSION_4; -rcss::RegHolder v4 = Parser::creators().autoReg( &create_v4, version ); - +const int version4 = static_cast< int >( '0' ) + REC_VERSION_4; +const int version5 = static_cast< int >( '0' ) + REC_VERSION_5; +const int version6 = static_cast< int >( '0' ) + REC_VERSION_6; +rcss::RegHolder v4 = Parser::creators().autoReg( &create_v4, version4 ); +rcss::RegHolder v5 = Parser::creators().autoReg( &create_v4, version5 ); +rcss::RegHolder v6 = Parser::creators().autoReg( &create_v4, version6 ); } } // end of namespace diff --git a/rcsc/rcg/parser_v5.cpp b/rcsc/rcg/parser_v5.cpp deleted file mode 100644 index a3d73a4..0000000 --- a/rcsc/rcg/parser_v5.cpp +++ /dev/null @@ -1,352 +0,0 @@ -// -*-c++-*- - -/*! - \file parser_v5.cpp - \brief rcg v5 parser Source File. -*/ - -/* - *Copyright: - - Copyright (C) Hidehisa AKIYAMA - - This code is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - *EndCopyright: - */ - -///////////////////////////////////////////////////////////////////// - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "parser_v5.h" - -#include "handler.h" -#include "types.h" - -#include -#include -#include -#include -#include -#include - -namespace rcsc { -namespace rcg { - -/*-------------------------------------------------------------------*/ -/*! - - */ -bool -ParserV5::parse( std::istream & is, - Handler & handler ) const -{ - // streampos must be the first point!!! - is.seekg( 0 ); - - if ( ! is.good() ) - { - return false; - } - - std::string line; - line.reserve( 8192 ); - - // skip header line - if ( ! std::getline( is, line ) - || line != "ULG5" ) - { - return false; - } - - if ( ! handler.handleLogVersion( REC_VERSION_5 ) ) - { - return false; - } - - int n_line = 1; - while ( std::getline( is, line ) ) - { - ++n_line; - if ( ! parseLine( n_line, line, handler ) ) - { - return false; - } - } - - if ( is.eof() ) - { - return handler.handleEOF(); - } - - return false; -} - -/*-------------------------------------------------------------------*/ -/*! - - */ -bool -ParserV5::parseShow( const int n_line, - const std::string & line, - Handler & handler ) const -{ - /* - (show