diff --git a/CMakeLists.txt b/CMakeLists.txt index 098f5030..b8c361d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.5.1) -project(RCSSServer VERSION 18.1.3) +project(RCSSServer VERSION 19.0.0) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -19,7 +19,7 @@ endif() find_package(BISON REQUIRED) find_package(FLEX REQUIRED) #find_package(Boost COMPONENTS system filesystem REQUIRED) -find_package(Boost COMPONENTS system REQUIRED) +find_package(Boost 1.44.0 COMPONENTS system REQUIRED) include(GNUInstallDirs) include(CheckIncludeFileCXX) diff --git a/ChangeLog b/ChangeLog index 1f1f573d..ba4746a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2024-03-25 Hidehisa Akiyama + + * CMakeLists.txt: + * NEWS: + * configure.ac: + - update a major version number. Official release 19.0.0 + - introduce a bipedal dash model. + - introduce a new gaussian observation noise model. + - reformat JSON monitor protocol and game log. + 2023-04-29 Hidehisa Akiyama * CMakeLists.txt: diff --git a/NEWS b/NEWS index 89a04859..09b2f6b5 100644 --- a/NEWS +++ b/NEWS @@ -1,13 +1,93 @@ +[19.0.0] + * New prameters: + - server::dist_noise_rate (default value: 0.0125) + - server::focus_dist_noise_rate (default value: 0.0125) + - server::land_dist_noise_rate (default value: 0.00125) + - server::land_focus_dist_noise_rate (default value: 0.00125) + + * New command: + - "(dash (l POWER DIR) (r POWER DIR))" + This is an extension of the dash command. All version players + can use this format. If the command is accepted, players can + perform acceleration and direction change simultaneously based + on the bipedal dash model. + + - "(gaussian_see)" + All version players can use this command. If the command is + accepted, rcssserver sent a reply message, "(ok gaussian_see)". + This command is used for a gaussian noise mode describing below. + + * Introduce a bipedal dash model. Players can now independently + issue dash commands to the left and right legs. This means that + players can now apply different accelerations to each leg. With + the bipedal dash model, players can perform acceleration and + direction changes simultaneously, governed by differential drive + kinematics. + + The rotation is calculated as: + + rotation = (left_leg_vel.bx - right_leg_vel.bx)/(player_size*2) + + where bx is the x-component of the vector with the player's + body direction as the x-axis. + + The player's result velocity is calculated as: + + vel = (left_leg_vel + right_leg_vel)/2 + + Stamina is consumed independently on the left and right legs, + and the total consumption is the sum of half of each leg: + + stamina = stamina - (left_consumed/2 + right_consumed/2) + + * Introduce a new gaussian observation noise model. This model is + activated by "(gaussian_see)" command and replaces the previous + quantization model. In this model, In this model, the noised + distance in the player's observation is determined by a + Gaussian distribution: + + stddev = actual_dist * noise_rate + focus_dist * focus_noise_rate + noised_dist = max(0.0, normal_distribution(actual_dist, stddev)) + + where normal_distribution(mean, stddev) is a random number + generator based on a Gaussian distribution with given mean and + standard deviation. actual_dist represents the actual distance + between the observed object and the player, while focus_dist is + the distance between the observed object and the player's focus + point. noise_rate and focus_noise_rate are determined by + heterogeneous parameters, with default values defined as new + server parameters, uniformly set for all player types in the + current version. For ball and player observation, + server::dist_noise_rate and server::focus_dist_noise_rate are + applied, while for flags (landmark objects), server::land_dist_noise_rate + and server::focus_dist_noise_rate are applied. + + The velocity noise formula is similar to the previous one. + The formula of dir_chg remains unchanged, while dist_chg is + calculated as: + + dist_chg = actual_dist_chg * noised_dist / actual_dist + + where actual_dist_chg represents the x-component of the velocity + vector with the direction from the player to the observed object + as the x-axis. The resulting dist_chg value is rounded to two + decimal places before being sent. + + * Improve the JSON game log format. The format of each data has + been reviewed to make it easier to parse and the JSON rcg is + now recorded as a pure JSON file. The parser library is bundled + in rcssmonitor. + [18.1.3] * Fix an issue in the penalty shootouts referee. If both teams - score the same when finishing all extended trials, the penalty - shootouts referee will not end the game and the simulator will - get stuck. Thanks go to Omid Amini for providing the patch. + score the same when finishing all extended trials, the penalty + shootouts referee will not end the game and the simulator will + get stuck. Thanks go to Omid Amini for providing the patch. [18.1.2] * Fix a problem of v18 observation noise model. Quantized distance values affected by the focus point are now rounded to one decimal - place. + place. [18.1.1] * Fix a problem in which the focus point is sometimes not updated. diff --git a/README.md b/README.md index 60edf435..0c7db2c5 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ For further reading, please check [the user's manual](https://rcsoccersim.readth rcssserver is implemented by C++14 and depends some libraries. Make sure you have the required dependencies installed on your system: -- g++ (which supports C++14) +- g++ (which supports C++17) - autoconf - automake - libtool @@ -22,7 +22,7 @@ Make sure you have the required dependencies installed on your system: - bison - boost >= 1.44 -In the case of Ubuntu 18.04 or 20.04, the following commands will resolve all dependencies: +In the case of Ubuntu 20.04 or 22.04, the following commands will resolve all dependencies: ``` sudo apt update diff --git a/configure.ac b/configure.ac index 56c817e4..c59ef54c 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.69]) LT_PREREQ([2.2]) -AC_INIT([RCSSServer],[18.1.3],[https://github.com/rcsoccersim/],[rcssserver]) +AC_INIT([RCSSServer],[19.0.0],[https://github.com/rcsoccersim/],[rcssserver]) #AM_INIT_AUTOMAKE([gnu 1.7.2 check-news dist-bzip2 dist-zip]) AM_INIT_AUTOMAKE([gnu 1.7.2 check-news foreign]) @@ -47,7 +47,7 @@ AX_CHECK_ZLIB([], ################################################## AC_FUNC_ALLOCA -AC_HEADER_STDC +#AC_HEADER_STDC AC_CHECK_HEADERS([arpa/inet.h fcntl.h]) AC_CHECK_HEADERS([inttypes.h libintl.h libintl.h malloc.h netdb.h]) AC_CHECK_HEADERS([netinet/in.h poll.h pwd.h stddef.h stdlib.h sys/param.h]) @@ -65,7 +65,7 @@ AC_TYPE_INT16_T AC_TYPE_INT32_T AC_TYPE_INT8_T AC_TYPE_SIZE_T -AC_HEADER_TIME +#AC_HEADER_TIME AC_STRUCT_TM AC_TYPE_UINT16_T AC_TYPE_UINT32_T @@ -98,12 +98,6 @@ AC_DEFINE_UNQUOTED([RETSIGTYPE],[$ac_cv_type_signal],[Define as the return type (`int' or `void').]) AC_FUNC_STRFTIME -AC_CHECK_FUNCS([memset], [], [ - echo "************** ERROR ****************" - echo "Could not find memset function." - echo "Please upgrade you system" - exit 1 -]) AC_CHECK_FUNCS([floor gethostbyname gettimeofday inet_ntoa memset mkdir pow rint]) AC_CHECK_FUNCS([select socket sqrt strdup strerror]) @@ -194,7 +188,7 @@ AX_CXX_COMPILE_STDCXX_17(noext) # check boost ################################################## -AX_BOOST_BASE([1.32.0]) +AX_BOOST_BASE([1.44.0]) AX_BOOST_SYSTEM CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" diff --git a/m4/ax_boost_base.m4 b/m4/ax_boost_base.m4 index b1fed7a5..8485cc92 100644 --- a/m4/ax_boost_base.m4 +++ b/m4/ax_boost_base.m4 @@ -10,7 +10,7 @@ # # 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 +# If no path to the installed boost library is given the macro searches # under /usr, /usr/local, /opt, /opt/local and /opt/homebrew and evaluates # the $BOOST_ROOT environment variable. Further documentation is available # at . @@ -33,7 +33,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 52 +#serial 54 # example boost program (need to pass version) m4_define([_AX_BOOST_BASE_PROGRAM], diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1bac9502..91ed5582 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,6 +37,7 @@ add_executable(RCSSServer initsenderonlinecoach.cpp initsenderplayer.cpp landmarkreader.cpp + leg.cpp logger.cpp main.cpp monitor.cpp @@ -94,7 +95,6 @@ target_link_libraries(RCSSServer RCSS::ConfParser RCSS::Net RCSS::GZ -# Boost::filesystem ZLIB::ZLIB ) diff --git a/src/Makefile.am b/src/Makefile.am index 277e2dbd..bc03609e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,6 +20,7 @@ rcssserver_SOURCES = \ initsenderonlinecoach.cpp \ initsenderplayer.cpp \ landmarkreader.cpp \ + leg.cpp \ logger.cpp \ main.cpp \ monitor.cpp \ @@ -90,6 +91,7 @@ noinst_HEADERS = \ initsenderonlinecoach.h \ initsenderplayer.h \ landmarkreader.h \ + leg.h \ logger.h \ monitor.h \ observer.h \ diff --git a/src/audio.cpp b/src/audio.cpp index b22a21fa..08435f67 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -985,6 +985,7 @@ RegHolder vp15 = AudioSenderPlayer::factory().autoReg( &create< AudioSenderPlaye RegHolder vp16 = AudioSenderPlayer::factory().autoReg( &create< AudioSenderPlayerv8 >, 16 ); RegHolder vp17 = AudioSenderPlayer::factory().autoReg( &create< AudioSenderPlayerv8 >, 17 ); RegHolder vp18 = AudioSenderPlayer::factory().autoReg( &create< AudioSenderPlayerv8 >, 18 ); +RegHolder vp19 = AudioSenderPlayer::factory().autoReg( &create< AudioSenderPlayerv8 >, 19 ); template< typename Sender > AudioSender::Ptr @@ -1011,6 +1012,7 @@ RegHolder vc15 = AudioSenderCoach::factory().autoReg( &create< AudioSenderCoachv RegHolder vc16 = AudioSenderCoach::factory().autoReg( &create< AudioSenderCoachv7 >, 16 ); RegHolder vc17 = AudioSenderCoach::factory().autoReg( &create< AudioSenderCoachv7 >, 17 ); RegHolder vc18 = AudioSenderCoach::factory().autoReg( &create< AudioSenderCoachv7 >, 18 ); +RegHolder vc19 = AudioSenderCoach::factory().autoReg( &create< AudioSenderCoachv7 >, 19 ); template< typename Sender > AudioSender::Ptr @@ -1037,5 +1039,6 @@ RegHolder voc15 = AudioSenderOnlineCoach::factory().autoReg( &create< AudioSende RegHolder voc16 = AudioSenderOnlineCoach::factory().autoReg( &create< AudioSenderOnlineCoachv7 >, 16 ); RegHolder voc17 = AudioSenderOnlineCoach::factory().autoReg( &create< AudioSenderOnlineCoachv7 >, 17 ); RegHolder voc18 = AudioSenderOnlineCoach::factory().autoReg( &create< AudioSenderOnlineCoachv7 >, 18 ); +RegHolder voc19 = AudioSenderOnlineCoach::factory().autoReg( &create< AudioSenderOnlineCoachv7 >, 19 ); } } diff --git a/src/bodysender.cpp b/src/bodysender.cpp index 97ef226b..78545dd5 100644 --- a/src/bodysender.cpp +++ b/src/bodysender.cpp @@ -438,6 +438,7 @@ RegHolder vp15 = BodySenderPlayer::factory().autoReg( &create< BodySenderPlayerV RegHolder vp16 = BodySenderPlayer::factory().autoReg( &create< BodySenderPlayerV14 >, 16 ); RegHolder vp17 = BodySenderPlayer::factory().autoReg( &create< BodySenderPlayerV14 >, 17 ); RegHolder vp18 = BodySenderPlayer::factory().autoReg( &create< BodySenderPlayerV18 >, 18 ); +RegHolder vp19 = BodySenderPlayer::factory().autoReg( &create< BodySenderPlayerV18 >, 19 ); } } diff --git a/src/fullstatesender.cpp b/src/fullstatesender.cpp index 0c391937..024187e8 100644 --- a/src/fullstatesender.cpp +++ b/src/fullstatesender.cpp @@ -541,6 +541,7 @@ RegHolder vp15 = FullStateSenderPlayer::factory().autoReg( &create< FullStateSen RegHolder vp16 = FullStateSenderPlayer::factory().autoReg( &create< FullStateSenderPlayerV13 >, 16 ); RegHolder vp17 = FullStateSenderPlayer::factory().autoReg( &create< FullStateSenderPlayerV13 >, 17 ); RegHolder vp18 = FullStateSenderPlayer::factory().autoReg( &create< FullStateSenderPlayerV18 >, 18 ); +RegHolder vp19 = FullStateSenderPlayer::factory().autoReg( &create< FullStateSenderPlayerV18 >, 19 ); } } diff --git a/src/heteroplayer.cpp b/src/heteroplayer.cpp index b6d0a55d..3aa06a44 100644 --- a/src/heteroplayer.cpp +++ b/src/heteroplayer.cpp @@ -124,6 +124,8 @@ HeteroPlayer::HeteroPlayer() setDefaultObservationParams(); + setDefaultGaussianObservationParams(); + // double real_speed_max = ( SP.maxPower() * M_dash_power_rate * M_effort_max ) @@ -237,6 +239,9 @@ HeteroPlayer::setDefault() // v18 setDefaultObservationParams(); + + // v19 + setDefaultGaussianObservationParams(); } void @@ -252,10 +257,22 @@ HeteroPlayer::setDefaultObservationParams() 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_land_vel_far_length = 20.0; + M_land_vel_too_far_length = 40.0; M_flag_max_observation_length = maximum_dist_in_pitch; } + +void +HeteroPlayer::setDefaultGaussianObservationParams() +{ + const ServerParam & SP = ServerParam::instance(); + + M_dist_noise_rate = SP.distNoiseRate(); + M_focus_dist_noise_rate = SP.focusDistNoiseRate(); + M_land_dist_noise_rate = SP.landDistNoiseRate(); + M_land_focus_dist_noise_rate = SP.landFocusDistNoiseRate(); +} + std::ostream & HeteroPlayer::print( std::ostream & o ) const { @@ -286,10 +303,14 @@ HeteroPlayer::print( std::ostream & o ) const o << "\tBall Vel Far Length = " << ballVelFarLength() << '\n'; o << "\tBall Vel Too Far Length = " << ballVelTooFarLength() << '\n'; o << "\tBall Max Observation Length = " << ballMaxObservationLength() << '\n'; - o << "\tFlag Chg Far Length = " << flagChgFarLength() << '\n'; - o << "\tFlag Chg Too Far Length = " << flagChgTooFarLength() << '\n'; - o << "\tFlag Max Observation Length = " << flagMaxObservationLength() << std::endl; - + o << "\tFlag Chg Far Length = " << landVelFarLength() << '\n'; + o << "\tFlag Chg Too Far Length = " << landVelTooFarLength() << '\n'; + o << "\tFlag Max Observation Length = " << landMaxObservationLength() << '\n'; + o << "\tDist Noise Rate = " << distNoiseRate() << '\n'; + o << "\tFocus Dist Noise Rate = " << focusDistNoiseRate() << '\n'; + o << "\tLand Dist Noise Rate = " << landDistNoiseRate() << '\n'; + o << "\tLand Focus Dist Noise Rate = " << landFocusDistNoiseRate() << std::endl; + return o; } @@ -379,9 +400,19 @@ HeteroPlayer::printParamsSExp( std::ostream & o, to_sexp( o, "ball_vel_far_length", ballVelFarLength() ); to_sexp( o, "ball_vel_too_far_length", ballVelTooFarLength() ); to_sexp( o, "ball_max_observation_length", ballMaxObservationLength() ); - to_sexp( o, "flag_chg_far_length", flagChgFarLength() ); - to_sexp( o, "flag_chg_too_far_length", flagChgTooFarLength() ); - to_sexp( o, "flag_max_observation_length", flagMaxObservationLength() ); + to_sexp( o, "flag_chg_far_length", landVelFarLength() ); + to_sexp( o, "flag_chg_too_far_length", landVelTooFarLength() ); + to_sexp( o, "flag_max_observation_length", landMaxObservationLength() ); + + if ( version < 19 ) + { + return; + } + + to_sexp( o, "dist_noise_rate", distNoiseRate() ); + to_sexp( o, "focus_dist_noise_rate", focusDistNoiseRate() ); + to_sexp( o, "land_dist_noise_rate", landDistNoiseRate() ); + to_sexp( o, "land_focus_dist_noise_rate", landFocusDistNoiseRate() ); } @@ -389,6 +420,7 @@ void HeteroPlayer::printParamsJSON( std::ostream & o, const unsigned int version ) const { + o << ','; to_json_member( o, "player_speed_max", playerSpeedMax() ); o << ','; to_json_member( o, "stamina_inc_max", staminaIncMax() ); @@ -438,10 +470,21 @@ HeteroPlayer::printParamsJSON( std::ostream & o, o << ","; to_json_member( o, "ball_max_observation_length", ballMaxObservationLength() ); o << ","; - to_json_member( o, "flag_chg_far_length", flagChgFarLength() ); + to_json_member( o, "flag_chg_far_length", landVelFarLength() ); + o << ","; + to_json_member( o, "flag_chg_too_far_length", landVelTooFarLength() ); + o << ","; + to_json_member( o, "flag_max_observation_length", landMaxObservationLength() ); + } + if ( version >= 19 ) + { + o << ","; + to_json_member( o, "dist_noise_rate", distNoiseRate() ); + o << ","; + to_json_member( o, "focus_dist_noise_rate", focusDistNoiseRate() ); o << ","; - to_json_member( o, "flag_chg_too_far_length", flagChgTooFarLength() ); + to_json_member( o, "land_dist_noise_rate", landDistNoiseRate() ); o << ","; - to_json_member( o, "flag_max_observation_length", flagMaxObservationLength() ); + to_json_member( o, "land_focus_dist_noise_rate", landFocusDistNoiseRate() ); } } diff --git a/src/heteroplayer.h b/src/heteroplayer.h index 2795ae93..590ad6cc 100644 --- a/src/heteroplayer.h +++ b/src/heteroplayer.h @@ -66,9 +66,14 @@ class HeteroPlayer { double ballVelFarLength() const { return M_ball_vel_far_length; } double ballVelTooFarLength() const { return M_ball_vel_too_far_length; } double ballMaxObservationLength() const { return M_ball_max_observation_length; } - double flagChgFarLength() const { return M_flag_chg_far_length; } - double flagChgTooFarLength() const { return M_flag_chg_too_far_length; } - double flagMaxObservationLength() const { return M_flag_max_observation_length; } + double landVelFarLength() const { return M_land_vel_far_length; } + double landVelTooFarLength() const { return M_land_vel_too_far_length; } + double landMaxObservationLength() const { return M_flag_max_observation_length; } + + double distNoiseRate() const { return M_dist_noise_rate; } + double focusDistNoiseRate() const { return M_focus_dist_noise_rate; } + double landDistNoiseRate() const { return M_land_dist_noise_rate; } + double landFocusDistNoiseRate() const { return M_land_focus_dist_noise_rate; } std::ostream & print( std::ostream & o ) const; @@ -86,6 +91,8 @@ class HeteroPlayer { void setDefaultObservationParams(); + void setDefaultGaussianObservationParams(); + double M_player_speed_max; double M_stamina_inc_max; double M_player_decay; @@ -112,9 +119,15 @@ class HeteroPlayer { double M_ball_vel_far_length; double M_ball_vel_too_far_length; double M_ball_max_observation_length; - double M_flag_chg_far_length; - double M_flag_chg_too_far_length; + double M_land_vel_far_length; + double M_land_vel_too_far_length; double M_flag_max_observation_length; + + // v19 + double M_dist_noise_rate; + double M_focus_dist_noise_rate; + double M_land_dist_noise_rate; + double M_land_focus_dist_noise_rate; }; inline diff --git a/src/initsendercoach.cpp b/src/initsendercoach.cpp index 595e9628..7e7069dd 100644 --- a/src/initsendercoach.cpp +++ b/src/initsendercoach.cpp @@ -223,6 +223,7 @@ RegHolder vc15 = InitSenderOfflineCoach::factory().autoReg( &create< InitSenderO RegHolder vc16 = InitSenderOfflineCoach::factory().autoReg( &create< InitSenderOfflineCoachV8 >, 16 ); RegHolder vc17 = InitSenderOfflineCoach::factory().autoReg( &create< InitSenderOfflineCoachV8 >, 17 ); RegHolder vc18 = InitSenderOfflineCoach::factory().autoReg( &create< InitSenderOfflineCoachV8 >, 18 ); +RegHolder vc19 = InitSenderOfflineCoach::factory().autoReg( &create< InitSenderOfflineCoachV8 >, 19 ); } } diff --git a/src/initsenderlogger.cpp b/src/initsenderlogger.cpp index 4b1212d3..8d6c6725 100644 --- a/src/initsenderlogger.cpp +++ b/src/initsenderlogger.cpp @@ -545,21 +545,22 @@ InitSenderLoggerJSON::~InitSenderLoggerJSON() void InitSenderLoggerJSON::sendHeader() { - transport() << "JSON\n"; + //transport() << "JSON\n"; transport() << "[\n"; - transport() << '{' - << std::quoted( "type" ) << ':' << std::quoted( "header" ); + // transport() << '{' + // << std::quoted( "type" ) << ':' << std::quoted( "header" ); - transport() << ',' - << std::quoted( "version" ) << ':' << std::quoted( VERSION ); + transport() << '{' + << std::quoted( "version" ) << ':' << std::quoted( VERSION ) + << "}"; + transport() << ",\n"; const std::time_t t = stadium().getStartTime(); - transport() << ',' + transport() << '{' << std::quoted( "timestamp" ) << ':' - << '"' << std::put_time( std::localtime( &t ), "%FT%T%z" ) << '"'; - - transport() << '}'; + << '"' << std::put_time( std::localtime( &t ), "%FT%T%z" ) << '"' + << '}'; } @@ -610,7 +611,7 @@ RegHolder vl2 = InitSenderLogger::factory().autoReg( &create< InitSenderLoggerV2 RegHolder vl3 = InitSenderLogger::factory().autoReg( &create< InitSenderLoggerV3 >, 3 ); RegHolder vl4 = InitSenderLogger::factory().autoReg( &create< InitSenderLoggerV4 >, 4 ); RegHolder vl5 = InitSenderLogger::factory().autoReg( &create< InitSenderLoggerV5 >, 5 ); -RegHolder vl7 = InitSenderLogger::factory().autoReg( &create< InitSenderLoggerV6 >, 6 ); +RegHolder vl6 = InitSenderLogger::factory().autoReg( &create< InitSenderLoggerV6 >, 6 ); RegHolder vljson = InitSenderLogger::factory().autoReg( &create< InitSenderLoggerJSON >, -1 ); diff --git a/src/initsenderonlinecoach.cpp b/src/initsenderonlinecoach.cpp index e3b8f5aa..65505214 100644 --- a/src/initsenderonlinecoach.cpp +++ b/src/initsenderonlinecoach.cpp @@ -302,6 +302,7 @@ RegHolder voc15 = InitSenderOnlineCoach::factory().autoReg( &create< InitSenderO RegHolder voc16 = InitSenderOnlineCoach::factory().autoReg( &create< InitSenderOnlineCoachV8 >, 16 ); RegHolder voc17 = InitSenderOnlineCoach::factory().autoReg( &create< InitSenderOnlineCoachV8 >, 17 ); RegHolder voc18 = InitSenderOnlineCoach::factory().autoReg( &create< InitSenderOnlineCoachV8 >, 18 ); +RegHolder voc19 = InitSenderOnlineCoach::factory().autoReg( &create< InitSenderOnlineCoachV8 >, 19 ); } } diff --git a/src/initsenderplayer.cpp b/src/initsenderplayer.cpp index 875da199..6d1b992e 100644 --- a/src/initsenderplayer.cpp +++ b/src/initsenderplayer.cpp @@ -283,6 +283,7 @@ RegHolder vp15 = InitSenderPlayer::factory().autoReg( &create< InitSenderPlayerV RegHolder vp16 = InitSenderPlayer::factory().autoReg( &create< InitSenderPlayerV8 >, 16 ); RegHolder vp17 = InitSenderPlayer::factory().autoReg( &create< InitSenderPlayerV8 >, 17 ); RegHolder vp18 = InitSenderPlayer::factory().autoReg( &create< InitSenderPlayerV8 >, 18 ); +RegHolder vp19 = InitSenderPlayer::factory().autoReg( &create< InitSenderPlayerV8 >, 19 ); } } diff --git a/src/leg.cpp b/src/leg.cpp new file mode 100644 index 00000000..095ef237 --- /dev/null +++ b/src/leg.cpp @@ -0,0 +1,181 @@ +// -*-c++-*- + +/*************************************************************************** + leg.cpp + ------------------- + begin : 23-OCT-2023 + copyright : (C) 2023 by The RoboCup Soccer Simulator + Maintenance Group. +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU LGPL as published by the Free Software * + * Foundation; either version 3 of the License, or (at your option) any * + * later version. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "leg.h" + +#include "player.h" +#include "heteroplayer.h" +#include "serverparam.h" +#include "playerparam.h" + +#include +#include + +namespace { + +double +normalize_dash_power( const double p ) +{ + return std::clamp( p, + ServerParam::instance().minDashPower(), + ServerParam::instance().maxDashPower() ); +} + +double +normalize_dash_angle( const double d ) +{ + double dir = std::clamp( d, + ServerParam::instance().minDashAngle(), + ServerParam::instance().maxDashAngle() ); + if ( ServerParam::instance().dashAngleStep() < EPS ) + { + // players can dash any direction. + } + else + { + // The dash direction is discretized by server::dash_angle_step + dir = ServerParam::instance().dashAngleStep() * rint( dir / ServerParam::instance().dashAngleStep() ); + } + return dir; +} + +} + + +Leg::Leg( const Player & player ) + : M_player( player ), + M_command_type( NONE ), + M_kick_power( 0.0 ), + M_kick_dir( 0.0 ), + M_dash_power( 0.0 ), + M_dash_dir( 0.0 ) +{ + +} + +void +Leg::resetCommand() +{ + M_command_type = NONE; + M_kick_power = 0.0; + M_kick_dir = 0.0; + M_dash_power = 0.0; + M_dash_dir = 0.0; +} + +void +Leg::move() +{ + if ( commandDone() ) + { + return; + } + + M_command_type = MOVE; +} + +void +Leg::kick( const double power, + const double dir ) +{ + if ( commandDone() ) + { + return; + } + + M_kick_power = power; + M_kick_dir = dir; + + M_command_type = KICK; +} + +void +Leg::turn() +{ + if ( commandDone() ) + { + return; + } + + M_command_type = TURN; +} + + +void +Leg::dash( const double power, + const double dir ) +{ + if ( commandDone() ) + { + return; + } + + M_dash_power = normalize_dash_power( power ); + M_dash_dir = normalize_dash_angle( dir ); + + M_command_type = DASH; +} + +void +Leg::tackle() +{ + if ( commandDone() ) + { + return; + } + + M_command_type = TACKLE; +} + +PVector +Leg::calcDashAccel( const double consumed_stamina ) const +{ + const ServerParam & param = ServerParam::instance(); + + const double power = normalize_dash_power( dashPower() < 0.0 ? -consumed_stamina : consumed_stamina * 2.0 ); + + const double dir_rate = std::clamp( std::fabs( dashDir() ) > 90.0 + ? param.backDashRate() - ( ( param.backDashRate() - param.sideDashRate() ) + * ( 1.0 - ( std::fabs( dashDir() ) - 90.0 ) / 90.0 ) ) + : param.sideDashRate() + ( ( 1.0 - param.sideDashRate() ) + * ( 1.0 - std::fabs( dashDir() ) / 90.0 ) ), + 0.0, + 1.0 ); + double accel_magnitude = std::fabs( M_player.effort() * power * dir_rate * M_player.playerType()->dashPowerRate() ); + + if ( M_player.pos().y < 0.0 ) + { + accel_magnitude /= ( M_player.side() == LEFT + ? param.slownessOnTopForLeft() + : param.slownessOnTopForRight() ); + } + + PVector accel = PVector::fromPolar( accel_magnitude, + normalize_angle( M_player.angleBodyCommitted() + Deg2Rad( dashDir() ) ) ); + if ( power < 0.0 ) + { + accel = -accel; + } + + return accel; +} diff --git a/src/leg.h b/src/leg.h new file mode 100644 index 00000000..81cf60a4 --- /dev/null +++ b/src/leg.h @@ -0,0 +1,109 @@ +// -*-c++-*- + + +/*************************************************************************** + leg.h + ------------------- + begin : 23-OCT-2023 + copyright : (C) 2023 by The RoboCup Soccer Simulator + Maintenance Group. +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU LGPL as published by the Free Software * + * Foundation; either version 3 of the License, or (at your option) any * + * later version. * + * * + ***************************************************************************/ + +#ifndef RCSSSERVER_LEG_H +#define RCSSSERVER_LEG_H + +#include "object.h" + +class Player; + +/*! + \todo inherits an abstract actuator class +*/ +class Leg { +public: + enum CommandType { + MOVE, + DASH, + TURN, + KICK, + TACKLE, + NONE + }; + +private: + const Player & M_player; + + CommandType M_command_type; + + double M_kick_power; + double M_kick_dir; + + double M_dash_power; + double M_dash_dir; + + Leg() = delete; + Leg( const Leg & ) = delete; + const Leg & operator=( const Leg & ) = delete; + +public: + explicit + Leg( const Player & player ); + + void resetCommand(); + + void move(); + + void kick( const double power, + const double dir ); + + void turn(); + + void dash( const double power, + const double dir ); + + void tackle(); + + + bool commandDone() const + { + return M_command_type != NONE; + } + + CommandType commandType() const + { + return M_command_type; + } + + double kickPower() const + { + return M_kick_power; + } + + double kickDir() const + { + return M_kick_dir; + } + + double dashPower() const + { + return M_dash_power; + } + + double dashDir() const + { + return M_dash_dir; + } + + PVector calcDashAccel( const double consumed_stamina ) const; +}; + +#endif diff --git a/src/pcombuilder.h b/src/pcombuilder.h index 30a086e6..048fd359 100644 --- a/src/pcombuilder.h +++ b/src/pcombuilder.h @@ -78,6 +78,8 @@ class Builder { virtual void dash( double power ) = 0; virtual void dash( double power, double dir ) = 0; + virtual void dashLeftLeg( double power, double dir ) = 0; + virtual void dashRightLeg( double power, double dir ) = 0; virtual void turn( double moment ) = 0; virtual void turn_neck( double moment ) = 0; virtual void change_focus( double moment_dist, double moment_dir ) = 0; @@ -100,6 +102,7 @@ class Builder { virtual void clang( int min, int max) = 0; virtual void ear( bool on, TEAM team_side, std::string team_name, EAR_MODE mode ) = 0; virtual void synch_see() = 0; + virtual void gaussian_see() = 0; }; diff --git a/src/player.cpp b/src/player.cpp index b0147302..aaf65028 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -184,6 +184,7 @@ Player::Player( Stadium & stadium, M_synch_see( false ), M_visual_send_interval( 4 ), M_high_quality( true ), + M_gaussian_see( false ), M_visible_angle( Deg2Rad( ServerParam::instance().visibleAngleDegree() ) ), M_view_width( rcss::pcom::NORMAL ), // @@ -226,6 +227,8 @@ Player::Player( Stadium & stadium, M_change_focus_count(0 ), M_change_view_count( 0 ), M_say_count( 0 ), + M_left_leg( *this ), + M_right_leg( *this ), M_arm( ServerParam::instance().pointToBan(), ServerParam::instance().pointToDuration() ), M_attentionto_count( 0 ), @@ -1093,6 +1096,10 @@ Player::dash( double power, { if ( ! M_command_done ) { +#if 1 + dashLeftLeg( power, dir ); + dashRightLeg( power, dir ); +#else const ServerParam & param = ServerParam::instance(); power = NormalizeDashPower( power ); @@ -1150,15 +1157,116 @@ Player::dash( double power, M_dash_cycles = 1; ++M_dash_count; M_command_done = true; +#endif + } +} + + +void +Player::dashLeftLeg( double power, + double dir ) +{ + if ( M_left_leg.commandDone() ) + { + return; + } + + M_left_leg.dash( power, dir ); + + M_dash_cycles = 1; + //++M_dash_count; + M_command_done = true; +} + +void +Player::dashRightLeg( double power, + double dir ) +{ + if ( M_right_leg.commandDone() ) + { + return; + } + + M_right_leg.dash( power, dir ); + + M_dash_cycles = 1; + //++M_dash_count; + M_command_done = true; +} + +void +Player::applyLegsEffect() +{ + applyDashEffect(); + // applyKickEffect(); +} + + +void +Player::applyDashEffect() +{ + if ( M_left_leg.commandType() != Leg::DASH + && M_right_leg.commandType() != Leg::DASH ) + { + return; } + + ++M_dash_count; + + double left_power = M_left_leg.dashPower(); + double right_power = M_right_leg.dashPower(); + + double left_consumed_stamina = ( left_power < 0.0 ? -left_power : left_power * 0.5 ); + double right_consumed_stamina = ( right_power < 0.0 ? -right_power : right_power * 0.5 ); + double consumed_stamina = left_consumed_stamina + right_consumed_stamina; + if ( consumed_stamina < 1.0e-5 ) + { + // no dash effect + return; + } + + consumed_stamina = std::min( consumed_stamina, stamina() + M_player_type->extraStamina() ); + + left_consumed_stamina = consumed_stamina * left_consumed_stamina / ( left_consumed_stamina + right_consumed_stamina ); + right_consumed_stamina = consumed_stamina * right_consumed_stamina / ( left_consumed_stamina + right_consumed_stamina ); + + const PVector left_accel = M_left_leg.calcDashAccel( left_consumed_stamina ); + const PVector right_accel = M_right_leg.calcDashAccel( right_consumed_stamina ); + + const PVector body_unit = PVector::fromPolar( 1.0, angleBodyCommitted() ); + const PVector vel_l = vel() + left_accel; + const PVector vel_r = vel() + right_accel; + const double vel_l_body = body_unit.x * vel_l.x + body_unit.y * vel_l.y; + const double vel_r_body = body_unit.x * vel_r.x + body_unit.y * vel_r.y; + + const PVector new_vel = ( vel_r + vel_l ) /= 2.0; + push( new_vel - vel() ); + + if ( M_left_leg.commandType() == Leg::DASH + && M_left_leg.commandType() == Leg::DASH ) + { + const double omega = ( vel_l_body - vel_r_body ) / ( M_player_type->playerSize() * 2.0 ); + M_angle_body = normalize_angle( angleBodyCommitted() + + ( 1.0 + drand( -M_randp, M_randp ) ) * omega ); + } + + M_stamina = std::max( 0.0, stamina() - consumed_stamina ); } +// void +// Player::applyKickEffect() +// { +// // TBD +// } void Player::turn( double moment ) { if ( ! M_command_done ) { + M_left_leg.turn(); + M_right_leg.turn(); + M_angle_body = normalize_angle( angleBodyCommitted() + ( 1.0 + drand( -M_randp, M_randp ) ) * NormalizeMoment( moment ) @@ -1664,6 +1772,8 @@ Player::move( double x, return; } + M_left_leg.move(); + M_right_leg.move(); M_command_done = true; ++M_move_count; } @@ -1961,6 +2071,9 @@ Player::tackle( double power_or_angle, return; } + M_left_leg.tackle(); + M_right_leg.tackle(); + M_command_done = true; M_tackle_cycles = ServerParam::instance().tackleCycles(); ++M_tackle_count; @@ -2270,6 +2383,13 @@ Player::synch_see() send( "(ok synch_see)" ); } +void +Player::gaussian_see() +{ + M_gaussian_see = true; + send( "(ok gaussian_see)" ); +} + void Player::sendInit() { @@ -2663,6 +2783,9 @@ Player::resetCommandFlags() M_turn_neck_done = false; M_done_received = false; + + M_left_leg.resetCommand(); + M_right_leg.resetCommand(); } void diff --git a/src/player.h b/src/player.h index b48e9883..0e3d017b 100644 --- a/src/player.h +++ b/src/player.h @@ -23,6 +23,7 @@ #define RCSSSERVER_PLAYER_H #include "arm.h" +#include "leg.h" #include "audio.h" #include "object.h" #include "pcombuilder.h" @@ -118,6 +119,7 @@ class Player bool M_synch_see; int M_visual_send_interval; bool M_high_quality; + bool M_gaussian_see; double M_visible_angle; rcss::pcom::VIEW_WIDTH M_view_width; @@ -178,6 +180,8 @@ class Player int M_change_view_count; int M_say_count; + Leg M_left_leg; + Leg M_right_leg; Arm M_arm; int M_attentionto_count; @@ -338,6 +342,7 @@ class Player double wideViewAngleNoiseTerm() const { return M_wide_view_angle_noise_term; } double normalViewAngleNoiseTerm() const { return M_normal_view_angle_noise_term; } double narrowViewAngleNoiseTerm() const { return M_narrow_view_angle_noise_term; } + bool isGaussianSee() const { return M_gaussian_see; } // // audio sensor @@ -371,6 +376,15 @@ class Player const double & effort() const { return M_effort; } const double & staminaCapacity() const { return M_stamina_capacity; } + // + // leg + // + void applyLegsEffect(); +private: + void applyDashEffect(); + //void applyKickEffect(); + +public: // // arm // @@ -467,12 +481,15 @@ class Player private: + bool parseCommand( const char * command ); int parseEar( const char * command ); /** PlayerCommands */ void dash( double power ) override; void dash( double power, double dir ) override; + void dashLeftLeg( double power, double dir ) override; + void dashRightLeg( double power, double dir ) override; void turn( double moment ) override; void turn_neck( double moment ) override; void change_focus( double moment_dist, double moment_dir) override; @@ -497,6 +514,7 @@ class Player void clang( int min, int max) override; void ear( bool on, rcss::pcom::TEAM team_side, std::string team_name, rcss::pcom::EAR_MODE mode ) override; void synch_see() override; + void gaussian_see() override; }; #endif diff --git a/src/player_command_parser.ypp b/src/player_command_parser.ypp index 77119319..a3bc9804 100644 --- a/src/player_command_parser.ypp +++ b/src/player_command_parser.ypp @@ -91,6 +91,7 @@ namespace %token RCSS_PCOM_CLANG "clang" %token RCSS_PCOM_EAR "ear" %token RCSS_PCOM_SYNCH_SEE "synch_see" +%token RCSS_PCOM_GAUSSIAN_SEE "gaussian_see" %token < m_view_w > RCSS_PCOM_VIEW_WIDTH_NARROW "narrow" %token < m_view_w > RCSS_PCOM_VIEW_WIDTH_NORMAL "normal" @@ -151,6 +152,7 @@ command : dash_com | clang_com | ear_com | synch_see_com + | gaussian_see_com ; dash_com : RCSS_PCOM_LP RCSS_PCOM_DASH floating_point_number RCSS_PCOM_RP @@ -161,6 +163,25 @@ dash_com : RCSS_PCOM_LP RCSS_PCOM_DASH floating_point_number RCSS_PCOM_RP { BUILDER.dash( $< m_double >3, $< m_double >4 ); } + | RCSS_PCOM_LP RCSS_PCOM_DASH dash_params RCSS_PCOM_RP +; + +dash_params : dash_left + | dash_right + | dash_left dash_right + | dash_right dash_left +; + +dash_left : RCSS_PCOM_LP RCSS_PCOM_LEFT floating_point_number floating_point_number RCSS_PCOM_RP + { + BUILDER.dashLeftLeg( $< m_double >3, $< m_double >4 ); + } +; + +dash_right : RCSS_PCOM_LP RCSS_PCOM_RIGHT floating_point_number floating_point_number RCSS_PCOM_RP + { + BUILDER.dashRightLeg( $< m_double >3, $< m_double >4 ); + } ; turn_com : RCSS_PCOM_LP RCSS_PCOM_TURN floating_point_number RCSS_PCOM_RP @@ -352,6 +373,12 @@ synch_see_com : RCSS_PCOM_LP RCSS_PCOM_SYNCH_SEE RCSS_PCOM_RP } ; +gaussian_see_com : RCSS_PCOM_LP RCSS_PCOM_GAUSSIAN_SEE RCSS_PCOM_RP + { + BUILDER.gaussian_see(); + } +; + on_off : RCSS_PCOM_ON { $< m_bool >$ = true; diff --git a/src/player_command_tok.lpp b/src/player_command_tok.lpp index e03e4218..15d16e5d 100644 --- a/src/player_command_tok.lpp +++ b/src/player_command_tok.lpp @@ -72,6 +72,7 @@ tackle { return RCSS_PCOM_TACKLE; } clang { return RCSS_PCOM_CLANG; } ear { return RCSS_PCOM_EAR; } synch_see { return RCSS_PCOM_SYNCH_SEE; } +gaussian_see { return RCSS_PCOM_GAUSSIAN_SEE; } narrow { return RCSS_PCOM_VIEW_WIDTH_NARROW; } normal { return RCSS_PCOM_VIEW_WIDTH_NORMAL; } diff --git a/src/playerparam.cpp b/src/playerparam.cpp index 9dfe3ced..eb554c10 100644 --- a/src/playerparam.cpp +++ b/src/playerparam.cpp @@ -139,7 +139,6 @@ const double PlayerParam::DEFAULT_FOUL_DETECT_PROBABILITY_DELTA_FACTOR = 0.0; const double PlayerParam::DEFAULT_CATCHABLE_AREA_L_STRETCH_MIN = 1.0; const double PlayerParam::DEFAULT_CATCHABLE_AREA_L_STRETCH_MAX = 1.3; - PlayerParam & PlayerParam::instance( rcss::conf::Builder * parent ) { diff --git a/src/random.h b/src/random.h index e89773fd..733fdce4 100644 --- a/src/random.h +++ b/src/random.h @@ -95,4 +95,11 @@ drand( double low, double high ) return rng( DefaultRNG::instance() ); } +inline +double +ndrand( double mean, double stddev ) +{ + std::normal_distribution<> rng( mean, stddev ); + return rng( DefaultRNG::instance() ); +} #endif diff --git a/src/serializercoachstdv14.cpp b/src/serializercoachstdv14.cpp index eaec2b7c..b05501ed 100644 --- a/src/serializercoachstdv14.cpp +++ b/src/serializercoachstdv14.cpp @@ -139,6 +139,7 @@ RegHolder v15 = SerializerCoach::factory().autoReg( &SerializerCoachStdv14::crea RegHolder v16 = SerializerCoach::factory().autoReg( &SerializerCoachStdv14::create, 16 ); RegHolder v17 = SerializerCoach::factory().autoReg( &SerializerCoachStdv14::create, 17 ); RegHolder v18 = SerializerCoach::factory().autoReg( &SerializerCoachStdv14::create, 18 ); +RegHolder v19 = SerializerCoach::factory().autoReg( &SerializerCoachStdv14::create, 19 ); } } diff --git a/src/serializercommonjson.cpp b/src/serializercommonjson.cpp index 0260bca0..9b123983 100644 --- a/src/serializercommonjson.cpp +++ b/src/serializercommonjson.cpp @@ -55,8 +55,7 @@ void SerializerCommonJSON::serializeServerParamBegin( std::ostream & strm ) const { strm << "{" - << std::quoted( "type" ) << ':' << std::quoted( "server_param" ) << ',' - << std::quoted( "params" ) << ":{"; + << std::quoted( "server_param" ) << ":{"; } @@ -71,8 +70,7 @@ void SerializerCommonJSON::serializePlayerParamBegin( std::ostream & strm ) const { strm << "{" - << std::quoted( "type" ) << ':' << std::quoted( "player_param" ) << ',' - << std::quoted( "params" ) << ":{"; + << std::quoted( "player_param" ) << ":{"; } @@ -88,11 +86,8 @@ SerializerCommonJSON::serializePlayerTypeBegin( std::ostream & strm, const int id ) const { strm << '{' - << std::quoted( "type" ) << ':' << std::quoted( "player_type" ) - << ',' - << std::quoted( "id" ) << ':' << id - << ',' - << std::quoted( "params" ) << ":{"; + << std::quoted( "player_type" ) << ":{" + << std::quoted( "id" ) << ':' << id; } void diff --git a/src/serializercommonstdv8.cpp b/src/serializercommonstdv8.cpp index 52d74454..0ef25644 100644 --- a/src/serializercommonstdv8.cpp +++ b/src/serializercommonstdv8.cpp @@ -111,6 +111,7 @@ RegHolder v15 = SerializerCommon::factory().autoReg( &SerializerCommonStdv8::cre RegHolder v16 = SerializerCommon::factory().autoReg( &SerializerCommonStdv8::create, 16 ); RegHolder v17 = SerializerCommon::factory().autoReg( &SerializerCommonStdv8::create, 17 ); RegHolder v18 = SerializerCommon::factory().autoReg( &SerializerCommonStdv8::create, 18 ); +RegHolder v19 = SerializerCommon::factory().autoReg( &SerializerCommonStdv8::create, 19 ); } } diff --git a/src/serializermonitor.cpp b/src/serializermonitor.cpp index 736eab62..efffd8de 100644 --- a/src/serializermonitor.cpp +++ b/src/serializermonitor.cpp @@ -421,8 +421,6 @@ SerializerMonitorStdv5::serializePlayerFocusPoint( std::ostream & os, //=================================================================== */ -#define USE_FLAT_STYLE - SerializerMonitorJSON::SerializerMonitorJSON( const SerializerCommon::Ptr common ) : SerializerMonitor( common ) { @@ -474,8 +472,6 @@ time_to_json( std::ostream & os, } } -#ifdef USE_FLAT_STYLE - void team_to_json( std::ostream & os, const Team & team ) @@ -486,11 +482,10 @@ team_to_json( std::ostream & os, return; } - os << '{' - << std::quoted( "side" ) << ':' << std::quoted( side ); + os << std::quoted( side ) << ':'; // key - os << ',' - << std::quoted( "name" ) << ':'; + os << '{'; // begin value object + os << std::quoted( "name" ) << ':'; if ( team.name().empty() ) os << "null"; else os << std::quoted( team.name() ); os << ',' @@ -502,24 +497,20 @@ team_to_json( std::ostream & os, << std::quoted( "pen_miss" ) << ':' << team.penaltyTaken() - team.penaltyPoint(); } - os << '}'; + os << '}'; // end value object } -void -teams_to_json( std::ostream & os, - const Team & team_l, - const Team & team_r ) -{ - os << std::quoted( "teams" ) << ':'; - - os << '['; - team_to_json( os, team_l ); - - os << ','; - team_to_json( os, team_r ); - - os << ']'; -} +// void +// teams_to_json( std::ostream & os, +// const Team & team_l, +// const Team & team_r ) +// { +// os << std::quoted( "teams" ) << ':'; +// os << '{'; +// team_to_json( os, team_l ); os << ','; +// team_to_json( os, team_r ); +// os << '}'; +// } } @@ -529,16 +520,16 @@ SerializerMonitorJSON::serializeTeam( std::ostream & os, const Team & team_l, const Team & team_r ) const { - os << '{'; - os << std::quoted( "type" ) << ':' << std::quoted( "team" ); - - os << ','; - time_to_json( os, time, stime ); + os << '{'; // begin team + os << std::quoted( "team" ) << ':'; // key - os << ','; - teams_to_json( os, team_l, team_r ); + os << '{'; // start object + time_to_json( os, time, stime ); os << ','; + team_to_json( os, team_l ); os << ','; + team_to_json( os, team_r ); + os << '}'; // end object - os << '}'; + os << '}'; // end team } @@ -548,13 +539,13 @@ SerializerMonitorJSON::serializePlayMode( std::ostream & os, const PlayMode pmode ) const { os << '{'; - os << std::quoted( "type" ) << ':' << std::quoted( "playmode" ); + os << std::quoted( "playmode" ) << ':'; - os << ','; + os << '{'; time_to_json( os, time, stime ); - os << ','; serializePlayModeId( os, pmode ); + os << '}'; os << '}'; } @@ -565,9 +556,9 @@ SerializerMonitorJSON::serializeShowBegin( std::ostream & os, const int time, const int stime ) const { os << '{'; - os << std::quoted( "type" ) << ':' << std::quoted( "show" ); + os << std::quoted( "show" ) << ':'; - os << ','; + os << '{'; time_to_json( os, time, stime ); } @@ -576,6 +567,7 @@ void SerializerMonitorJSON::serializeShowEnd( std::ostream & os ) const { os << '}'; + os << '}'; } @@ -593,29 +585,18 @@ SerializerMonitorJSON::serializeScore( std::ostream & os, const Team & team_l, const Team & team_r ) const { - teams_to_json( os, team_l, team_r ); + os << std::quoted( "team" ) << ':'; + + os << '{'; // start object + team_to_json( os, team_l ); os << ','; + team_to_json( os, team_r ); + os << '}'; // end object } namespace { constexpr double POS_PREC = 0.0001; constexpr double DIR_PREC = 0.001; - -#else -void -vec_to_json( std::ostream & os, - const std::string & name, - const double x, - const double y ) -{ - os << std::quoted( name ) << ':' - << '{' - << std::quoted( "x" ) << ':' << Quantize( x, POS_PREC ) - << ',' - << std::quoted( "y" ) << ':' << Quantize( y, POS_PREC ) - << '}'; -} -#endif } void @@ -624,7 +605,6 @@ SerializerMonitorJSON::serializeBall( std::ostream & os, { os << std::quoted( "ball" ) << ':' << '{'; -#ifdef USE_FLAT_STYLE os << std::quoted( "x" ) << ':' << Quantize( ball.pos().x, POS_PREC ) << ',' << std::quoted( "y" ) << ':' << Quantize( ball.pos().y, POS_PREC ) @@ -632,11 +612,6 @@ SerializerMonitorJSON::serializeBall( std::ostream & os, << std::quoted( "vx" ) << ':' << Quantize( ball.vel().x, POS_PREC ) << ',' << std::quoted( "vy" ) << ':' << Quantize( ball.vel().y, POS_PREC ); -#else - vec_to_json( os, "pos", ball.pos().x, ball.pos().x ); - os << ','; - vec_to_json( os, "vel", ball.vel().x, ball.vel().x ); -#endif os << '}'; } @@ -680,7 +655,6 @@ void SerializerMonitorJSON::serializePlayerPos( std::ostream & os, const Player & player ) const { -#ifdef USE_FLAT_STYLE os << ',' << std::quoted( "x" ) << ':' << Quantize( player.pos().x, POS_PREC ) << ',' @@ -689,12 +663,6 @@ SerializerMonitorJSON::serializePlayerPos( std::ostream & os, << std::quoted( "vx" ) << ':' << Quantize( player.vel().x, POS_PREC ) << ',' << std::quoted( "vy" ) << ':' << Quantize( player.vel().y, POS_PREC ); -#else - os << ','; - vec_to_json( os, "pos", player.pos().x, player.pos().y ); - os << ','; - vec_to_json( os, "vel", player.vel().x, player.vel().y ); -#endif os << ',' << std::quoted( "body" ) << ':' << Quantize( Rad2Deg( player.angleBodyCommitted() ), DIR_PREC ); @@ -709,15 +677,10 @@ SerializerMonitorJSON::serializePlayerArm( std::ostream & os, { if ( player.arm().isPointing() ) { -#ifdef USE_FLAT_STYLE os << ',' << std::quoted( "px" ) << ':' << Quantize( player.arm().dest().getX(), POS_PREC ) << ',' << std::quoted( "py" ) << ':' << Quantize( player.arm().dest().getY(), POS_PREC ); -#else - os << ','; - vec_to_json( os, "arm", player.arm().dest().getX(), player.arm().dest().getY() ); -#endif } } @@ -725,19 +688,10 @@ SerializerMonitorJSON::serializePlayerArm( std::ostream & os, void SerializerMonitorJSON::serializePlayerViewMode( std::ostream & os, const Player & player ) const { - os << ','; -#ifdef USE_FLAT_STYLE - os << std::quoted( "vq" ) << ':' << std::quoted( player.highQuality() ? "h" : "l" ) + os << ',' + << std::quoted( "vq" ) << ':' << std::quoted( player.highQuality() ? "h" : "l" ) << ',' << std::quoted( "vw" ) << ':' << Quantize( Rad2Deg( player.visibleAngle() ), DIR_PREC ); -#else - os << std::quoted( "view" ) << ':' - << '{' - << std::quoted( "q" ) << ':' << std::quoted( player.highQuality() ? "h" : "l" ) - << ',' - << std::quoted( "w" ) << ':' << Quantize( Rad2Deg( player.visibleAngle() ), DIR_PREC ) - << '}'; -#endif } @@ -746,18 +700,9 @@ SerializerMonitorJSON::serializePlayerFocusPoint( std::ostream & os, const Player & player ) const { os << ','; -#ifdef USE_FLAT_STYLE os << std::quoted( "fdist" ) << ':' << Quantize( player.focusDist(), POS_PREC ) << ',' << std::quoted( "fdir" ) << ':' << Quantize( Rad2Deg( player.focusDir() ), DIR_PREC ); -#else - os << std::quoted( "focus_point" ) << ':' - << '{' - << std::quoted( "dist" ) << ':' << Quantize( player.focusDist(), POS_PREC ) - << ',' - << std::quoted( "dir" ) << ':' << Quantize( Rad2Deg( player.focusDir() ), DIR_PREC ); - << '}'; -#endif } @@ -765,27 +710,14 @@ void SerializerMonitorJSON::serializePlayerStamina( std::ostream & os, const Player & player ) const { - os << ','; -#ifdef USE_FLAT_STYLE - os << std::quoted( "stamina" ) << ':' << player.stamina() + os << ',' + << std::quoted( "stamina" ) << ':' << player.stamina() << ',' << std::quoted( "effort" ) << ':' << player.effort() << ',' << std::quoted( "recovery" ) << ':' << player.recovery() << ',' << std::quoted( "capacity" ) << ':' << player.staminaCapacity(); -#else - os << std::quoted( "stamina" ) << ':' - << '{'; - os << std::quoted( "v" ) << ':' << player.stamina() - << ',' - << std::quoted( "e" ) << ':' << player.effort() - << ',' - << std::quoted( "r" ) << ':' << player.recovery() - << ',' - << std::quoted( "c" ) << ':' << player.staminaCapacity(); - os << '}'; -#endif } @@ -795,19 +727,10 @@ void SerializerMonitorJSON::serializePlayerFocus( std::ostream & os, if ( player.isEnabled() && player.getFocusTarget() ) { - os << ','; -#ifdef USE_FLAT_STYLE - os << std::quoted( "fside" ) << ':' << std::quoted( to_string( player.getFocusTarget()->side() ) ) + os << ',' + << std::quoted( "fside" ) << ':' << std::quoted( to_string( player.getFocusTarget()->side() ) ) << ',' << std::quoted( "fnum" ) << ':' << player.getFocusTarget()->unum(); -#else - os << std::quoted( "focus" ) << ':' - << '{' - << std::quoted( "s" ) << ':' << std::quoted( to_string( player.getFocusTarget()->side() ) ) - << ',' - << std::quoted( "n" ) << ':' << player.getFocusTarget()->unum() - << '}'; -#endif } } @@ -817,23 +740,9 @@ SerializerMonitorJSON::serializePlayerCounts( std::ostream & os, const Player & player ) const { - os << ','; - os << std::quoted( "count" ) << ':' -#if 0 - << '[' << player.kickCount() - << ',' << player.dashCount() - << ',' << player.turnCount() - << ',' << player.catchCount() - << ',' << player.moveCount() - << ',' << player.turnNeckCount() - << ',' << player.changeViewCount() - << ',' << player.sayCount() - << ',' << player.tackleCount() - << ',' << player.arm().getCounter() - << ',' << player.attentiontoCount() - << ']'; -#else - << '{' + os << ',' + // << std::quoted( "count" ) << ':' + // << '{' // begin object << std::quoted( "kick" ) << ':' << player.kickCount() << ',' << std::quoted( "dash" ) << ':' << player.dashCount() @@ -857,8 +766,8 @@ SerializerMonitorJSON::serializePlayerCounts( std::ostream & os, << std::quoted( "attentionto" ) << ':' << player.attentiontoCount() << ',' << std::quoted( "change_focus" ) << ':' << player.changeFocusCount() - << '}'; -#endif + // << '}'// end object + ; } @@ -876,24 +785,16 @@ SerializerMonitorJSON::serializeTeamGraphic( std::ostream & os, } os << '{' - << std::quoted( "type" ) << ':' << std::quoted( "team_graphic" ); + << std::quoted( "team_graphic" ) << ':'; + + os << '{'; // begin body - os << ','; os << std::quoted( "side" ) << ':' << std::quoted( to_string( side ) ); os << ','; -#ifdef USE_FLAT_STYLE os << std::quoted( "x" ) << ':' << x << ',' << std::quoted( "y" ) << ':' << y; -#else - os << std::quoted( "index" ) << ':' - << '{' - << std::quoted( "x" ) << ':' << x - << ',' - << std::quoted( "y" ) << ':' << y - << '}'; -#endif os << ','; os << std::quoted( "xpm" ) << ':' @@ -908,7 +809,9 @@ SerializerMonitorJSON::serializeTeamGraphic( std::ostream & os, } os << ']'; // end xpm array - os << '}'; + os << '}'; // end body + + os << '}'; // end team_graphic } void @@ -918,9 +821,9 @@ SerializerMonitorJSON::serializeMsg( std::ostream & os, const char * msg ) const { os << '{' - << std::quoted( "type" ) << ':' << std::quoted( "msg" ); + << std::quoted( "msg" ) << ':'; - os << ','; + os << '{'; // begin object time_to_json( os, time, stime ); os << ','; @@ -929,6 +832,8 @@ SerializerMonitorJSON::serializeMsg( std::ostream & os, os << ','; os << std::quoted( "message" ) << ':' << std::quoted( msg ); + os << '}'; // end object + os << '}'; } diff --git a/src/serializeronlinecoachstdv14.cpp b/src/serializeronlinecoachstdv14.cpp index 50daec3b..fd0109b6 100644 --- a/src/serializeronlinecoachstdv14.cpp +++ b/src/serializeronlinecoachstdv14.cpp @@ -65,6 +65,7 @@ RegHolder v15 = SerializerOnlineCoach::factory().autoReg( &SerializerOnlineCoach RegHolder v16 = SerializerOnlineCoach::factory().autoReg( &SerializerOnlineCoachStdv14::create, 16 ); RegHolder v17 = SerializerOnlineCoach::factory().autoReg( &SerializerOnlineCoachStdv14::create, 17 ); RegHolder v18 = SerializerOnlineCoach::factory().autoReg( &SerializerOnlineCoachStdv14::create, 18 ); +RegHolder v19 = SerializerOnlineCoach::factory().autoReg( &SerializerOnlineCoachStdv14::create, 19 ); } } diff --git a/src/serializerplayerstdv18.cpp b/src/serializerplayerstdv18.cpp index ed02ca7f..cc4cc296 100644 --- a/src/serializerplayerstdv18.cpp +++ b/src/serializerplayerstdv18.cpp @@ -130,6 +130,7 @@ SerializerPlayerStdv18::create() namespace { RegHolder v18 = SerializerPlayer::factory().autoReg( &SerializerPlayerStdv18::create, 18 ); +RegHolder v19 = SerializerPlayer::factory().autoReg( &SerializerPlayerStdv18::create, 19 ); } } diff --git a/src/serverparam.cpp b/src/serverparam.cpp index c77e9f04..35168430 100644 --- a/src/serverparam.cpp +++ b/src/serverparam.cpp @@ -377,6 +377,12 @@ namespace { // 17.0.0 constexpr double MAX_CATCH_ANGLE = +90.0; constexpr double MIN_CATCH_ANGLE = -90.0; + +// 19.0.0 +constexpr double DIST_NOISE_RATE = 0.0125; +constexpr double FOCUS_DIST_NOISE_RATE = 0.0125; +constexpr double LAND_DIST_NOISE_RATE = 0.00125; +constexpr double LAND_FOCUS_DIST_NOISE_RATE = 0.00125; } // XXX @@ -946,12 +952,16 @@ ServerParam::addParams() addParam( "max_catch_angle", M_max_catch_angle, "", 17 ); addParam( "min_catch_angle", M_min_catch_angle, "", 17 ); + // v19 + addParam( "dist_noise_rate", M_dist_noise_rate, "", 19 ); + addParam( "focus_dist_noise_rate", M_focus_dist_noise_rate, "", 19 ); + addParam( "land_dist_noise_rate", M_land_dist_noise_rate, "", 19 ); + addParam( "land_focus_dist_noise_rate", M_land_focus_dist_noise_rate, "", 19 ); + // XXX // addParam( "random_seed", M_random_seed, "", 999 ); // addParam( "long_kick_power_factor", M_long_kick_power_factor, "", 999 ); // addParam( "long_kick_delay", M_long_kick_delay, "", 999 ); - - } void @@ -1464,6 +1474,11 @@ ServerParam::setDefaults() M_kickable_area = M_player_size + M_kickable_margin + M_ball_size; M_control_radius_width = M_control_radius - M_player_size; + // 19.0.0 + M_dist_noise_rate = DIST_NOISE_RATE; + M_focus_dist_noise_rate = FOCUS_DIST_NOISE_RATE; + M_land_dist_noise_rate = LAND_DIST_NOISE_RATE; + M_land_focus_dist_noise_rate = LAND_FOCUS_DIST_NOISE_RATE; // std::string module_dir = S_MODULE_DIR; // for ( std::string::size_type pos = module_dir.find( "//" ); // pos != std::string::npos; diff --git a/src/serverparam.h b/src/serverparam.h index b7884454..0470cd1c 100644 --- a/src/serverparam.h +++ b/src/serverparam.h @@ -626,6 +626,12 @@ class ServerParam { double M_long_kick_power_factor; int M_long_kick_delay; + // 19.0.0 + double M_dist_noise_rate; + double M_focus_dist_noise_rate; + double M_land_dist_noise_rate; + double M_land_focus_dist_noise_rate; + private: // setters & getters @@ -984,6 +990,11 @@ class ServerParam { double longKickPowerFactor() const { return M_long_kick_power_factor; } int longKickDelay() const { return M_long_kick_delay; } + // v19 + double distNoiseRate() const { return M_dist_noise_rate; } + double focusDistNoiseRate() const { return M_focus_dist_noise_rate; } + double landDistNoiseRate() const { return M_land_dist_noise_rate; } + double landFocusDistNoiseRate() const { return M_land_focus_dist_noise_rate; } }; #endif diff --git a/src/stadium.cpp b/src/stadium.cpp index 60a7e3c9..e355d0f6 100644 --- a/src/stadium.cpp +++ b/src/stadium.cpp @@ -790,10 +790,12 @@ void Stadium::step() { // + // apply command effects // reset command flags // for ( PlayerCont::reference p : M_players ) { + p->applyLegsEffect(); p->resetCommandFlags(); p->incArmAge(); } diff --git a/src/visualsendercoach.cpp b/src/visualsendercoach.cpp index 8911d20f..50790532 100644 --- a/src/visualsendercoach.cpp +++ b/src/visualsendercoach.cpp @@ -371,6 +371,7 @@ RegHolder vc15 = VisualSenderCoach::factory().autoReg( &create< VisualSenderCoac RegHolder vc16 = VisualSenderCoach::factory().autoReg( &create< VisualSenderCoachV13 >, 16 ); RegHolder vc17 = VisualSenderCoach::factory().autoReg( &create< VisualSenderCoachV13 >, 17 ); RegHolder vc18 = VisualSenderCoach::factory().autoReg( &create< VisualSenderCoachV13 >, 18 ); +RegHolder vc19 = VisualSenderCoach::factory().autoReg( &create< VisualSenderCoachV13 >, 19 ); } } diff --git a/src/visualsenderplayer.cpp b/src/visualsenderplayer.cpp index 5d1281eb..99475a3f 100644 --- a/src/visualsenderplayer.cpp +++ b/src/visualsenderplayer.cpp @@ -23,6 +23,7 @@ #include #endif + #include "visualsenderplayer.h" #include "stadium.h" @@ -30,6 +31,270 @@ namespace rcss { +/** + * @class NoisyObservation + * @brief Represents a noisy observation made by an observer player. + * + * This class provides a base interface for calculating distances, and velocities + * for noisy observations. It is meant to be inherited by specific observation classes. + */ +class NoisyObservation { +private: + const Player & M_observer; + +protected: + NoisyObservation() = delete; + + /** + * @brief Constructs a NoisyObservation object. + * + * This constructor initializes a NoisyObservation object with the given player. + * + * @param player The player object to observe. + */ + explicit + NoisyObservation( const Player & player ) + : M_observer( player ) + { } + + const Player & observer() const + { + return M_observer; + } + +public: + virtual + ~NoisyObservation() = default; + + /** + * Calculates the noisy distance between the observer and the target movable object. + * + * @param actual_dist The actual distance between the observer and the target movable object. + * @param focus_dist The focus distance between the focus point and the target movable object. + * @return The calculated noisy distance. + */ + virtual + double calcDist( const double actual_dist, + const double focus_dist ) const = 0; + /** + * Calculates the noisy distance between the observer and the target landmark object. + * + * @param actual_dist The actual distance between the observer and the target landmark object. + * @param focus_dist The focus distance between the focus point and the target landmark object. + * @return The calculated noisy distance. + */ + virtual + double calcDistLandmark( const double actual_dist, + const double focus_dist ) const = 0; + + /** + * Calculates the change in distance and direction based on the object's velocity, position, actual distance, and noisy distance. + * + * @param obj_vel The velocity of the target object. + * @param obj_pos The position of the target object. + * @param actual_dist The actual distance between the observer and the target object. + * @param noisy_dist The noisy distance between the observer and the target object. + * @param dist_chg Pointer to a variable that will store the calculated change in distance. + * @param dir_chg Pointer to a variable that will store the calculated change in direction. + */ + virtual + void calcVel( const PVector & obj_vel, + const PVector & obj_pos, + const double actual_dist, + const double noisy_dist, + double * dist_chg, + double * dir_chg ) const = 0; + +}; + +/** + * @class QuantizeObservation + * @brief A class that represents a quantized observation of a player. + * + * This class is derived from the NoisyObservation class and provides methods for calculating + * quantized distances and velocities based on actual distances and positions. + */ +class QuantizeObservation + : public NoisyObservation { +private: + +protected: + QuantizeObservation() = delete; + +public: + explicit + QuantizeObservation( const Player & player ) + : NoisyObservation( player ) + { } + + virtual + ~QuantizeObservation() = default; + +private: + + /** + * Calculates the observed distance based on the actual distance, focus distance, and quantization step. + * + * @param actual_dist The actual distance. + * @param focus_dist The focus distance. + * @param qstep The quantization step used for quantizing the distances. + * @return The observed distance calculated based on the given parameters. + */ + double calcDistImpl( const double actual_dist, + const double focus_dist, + const double qstep ) const + { + const double quant_dist = std::exp( Quantize( std::log( actual_dist + EPS ), qstep ) ); + const double quant_focus_dist = std::exp( Quantize( std::log( focus_dist + EPS ), qstep ) ); + const double observed_dist = std::max( 0.0, + actual_dist - ( ( focus_dist - quant_focus_dist ) + ( actual_dist - quant_dist ) ) / 2.0 ); + + return Quantize( observed_dist, 0.1 ); + } + +public: + double calcDist( const double actual_dist, + const double focus_dist ) const override + { + return calcDistImpl( actual_dist, focus_dist, observer().distQStep() ); + } + + double calcDistLandmark( const double actual_dist, + const double focus_dist ) const override + { + return calcDistImpl( actual_dist, focus_dist, observer().landDistQStep() ); + } + + void calcVel( const PVector & obj_vel, + const PVector & obj_pos, + const double actual_dist, + const double noisy_dist, + double * dist_chg, + double * dir_chg ) const override + { + if ( actual_dist != 0.0 ) + { + const PVector vtmp = obj_vel - observer().vel(); + const PVector etmp = ( obj_pos - observer().pos() ) /= actual_dist; + + *dist_chg = vtmp.x * etmp.x + vtmp.y * etmp.y; + // dir_chg = RAD2DEG * ( vtmp.y * etmp.x + // - vtmp.x * etmp.y ) / actual_dist; + *dir_chg = vtmp.y * etmp.x - vtmp.x * etmp.y; + *dir_chg /= actual_dist; + *dir_chg *= RAD2DEG; + + *dir_chg = ( *dir_chg == 0.0 + ? 0.0 + : Quantize( *dir_chg, observer().dirQStep() ) ); + *dist_chg = noisy_dist * Quantize( *dist_chg / actual_dist, 0.02 ); + } + else + { + *dir_chg = 0.0; + *dist_chg = 0.0; + } + } +}; + + +/** + * @class GaussianObservation + * @brief Represents a Gaussian observation model for player observations. + * + * The GaussianObservation class is a concrete implementation of the NoisyObservation class. + * It calculates the noisy distance and velocity changes based on the actual distance and focus distance. + * The noise rates are determined by the player's type. + */ +class GaussianObservation + : public NoisyObservation { +private: + + GaussianObservation() = delete; + +public: + explicit + GaussianObservation( const Player & player ) + : NoisyObservation( player ) + { } + + + virtual + ~GaussianObservation() = default; + +private: + /** + * Calculates the distance with noise based on the actual distance, focus distance, + * distance noise rate, and focus distance noise rate. + * + * @param actual_dist The actual distance. + * @param focus_dist The focus distance. + * @param dist_noise_rate The distance noise rate. + * @param focus_dist_noise_rate The focus distance noise rate. + * @return he observed distance calculated based on the given parameters. + */ + double calcDistImpl( const double actual_dist, + const double focus_dist, + const double dist_noise_rate, + const double focus_dist_noise_rate ) const + { + const double std_dev = actual_dist * dist_noise_rate + focus_dist * focus_dist_noise_rate; + + return std::max( 0.0, ndrand( actual_dist, std_dev ) ); + } + +public: + double calcDist( const double actual_dist, + const double focus_dist ) const override + { + return calcDistImpl( actual_dist, + focus_dist, + observer().playerType()->distNoiseRate(), + observer().playerType()->focusDistNoiseRate() ); + } + + double calcDistLandmark( const double actual_dist, + const double focus_dist ) const override + { + return calcDistImpl( actual_dist, + focus_dist, + observer().playerType()->landDistNoiseRate(), + observer().playerType()->landFocusDistNoiseRate() ); + } + + void calcVel( const PVector & obj_vel, + const PVector & obj_pos, + const double actual_dist, + const double noisy_dist, + double * dist_chg, + double * dir_chg ) const override + { + if ( actual_dist != 0.0 ) + { + const PVector vtmp = obj_vel - observer().vel(); + PVector etmp = ( obj_pos - observer().pos() ) /= actual_dist; + + *dist_chg = vtmp.x * etmp.x + vtmp.y * etmp.y; + *dir_chg = vtmp.y * etmp.x - vtmp.x * etmp.y; + *dir_chg /= actual_dist; + *dir_chg *= RAD2DEG; + + *dir_chg = ( *dir_chg == 0.0 + ? 0.0 + : Quantize( *dir_chg, observer().dirQStep() ) ); + //*dist_chg += ( noisy_dist - actual_dist ); + *dist_chg *= ( noisy_dist / actual_dist ); + *dist_chg = Quantize( *dist_chg, 0.01 ); + } + else + { + *dir_chg = 0.0; + *dist_chg = 0.0; + } + } +}; + + /*! //=================================================================== // @@ -52,8 +317,11 @@ VisualSenderPlayer::VisualSenderPlayer( const Params & params ) M_serializer( params.M_serializer ), M_self( params.M_self ), M_stadium( params.M_stadium ), - M_sendcnt( 0 ) + M_sendcnt( 0 ), + M_noisy_observation( new QuantizeObservation( M_self ) ), + M_cached_focus_point( 0.0, 0.0 ) { + //std::cerr << "create VisualSenderPlayer" << std::endl; } @@ -106,6 +374,11 @@ VisualSenderPlayerV1::sendVisual() return; } + if ( self().isGaussianSee() ) + { + M_noisy_observation = std::shared_ptr< const NoisyObservation >( new GaussianObservation( self() ) ); + } + updateCache(); serializer().serializeVisualBegin( transport(), stadium().time() ); @@ -206,14 +479,16 @@ void VisualSenderPlayerV1::sendLowFlag( const PObject & flag ) { const double ang = calcRadDir( flag ); + const double un_quant_dist = calcUnQuantDist( flag ); - if ( std::fabs( ang ) < self().visibleAngle() * 0.5 ) + if ( std::fabs( ang ) < self().visibleAngle() * 0.5 + && un_quant_dist < self().playerType()->landMaxObservationLength() ) { serializer().serializeVisualObject( transport(), calcName( flag ), calcDegDir( ang ) ); } - else if ( calcUnQuantDist( flag ) <= self().VISIBLE_DISTANCE ) + else if ( un_quant_dist <= self().VISIBLE_DISTANCE ) { serializer().serializeVisualObject( transport(), calcCloseName( flag ), @@ -225,64 +500,56 @@ void VisualSenderPlayerV1::sendHighFlag( const PObject & flag ) { const double ang = calcRadDir( flag ); - //const double un_quant_dist = calcUnQuantDist( flag ); - double un_quant_dist = self().pos().distance2( flag.pos() ); + const double actual_dist = calcUnQuantDist( flag ); + const double noisy_dist = calcNoisyDistLandmark( flag, actual_dist ); - if ( std::fabs( ang ) < self().visibleAngle() * 0.5 ) + if ( std::fabs( ang ) < self().visibleAngle() * 0.5 + && actual_dist < self().playerType()->landMaxObservationLength() ) { - un_quant_dist = std::sqrt( un_quant_dist ); - const double quant_dist - = calcQuantDist( un_quant_dist, self().landDistQStep() ); - - //const double prob = ( ( quant_dist - UNUM_FAR_LENGTH ) - // / ( UNUM_TOOFAR_LENGTH - UNUM_FAR_LENGTH ) ); - const double prob = ( ( quant_dist - self().unumFarLength() ) - / ( self().unumTooFarLength() - self().unumFarLength() ) ); - - if ( decide( prob ) ) + if ( decide( calcNoFlagVelProb( noisy_dist ) ) ) { serializer().serializeVisualObject( transport(), calcName( flag ), - quant_dist, + noisy_dist, calcDegDir( ang ) ); } else { double dist_chg, dir_chg; - calcVel( PVector(), flag.pos(), - un_quant_dist, quant_dist, - dist_chg, dir_chg ); + calcNoisyVel( PVector(), flag.pos(), actual_dist, noisy_dist, &dist_chg, &dir_chg ); + serializer().serializeVisualObject( transport(), calcName( flag ), - quant_dist, + noisy_dist, calcDegDir( ang ), dist_chg, dir_chg ); } } - else if ( un_quant_dist <= self().VISIBLE_DISTANCE2 ) + else if ( actual_dist <= self().VISIBLE_DISTANCE ) { - //un_quant_dist = std::sqrt( un_quant_dist ); serializer().serializeVisualObject( transport(), calcCloseName( flag ), - calcQuantDist( std::sqrt( un_quant_dist ), - self().landDistQStep() ), + noisy_dist, calcDegDir( ang ) ); } } + void VisualSenderPlayerV1::sendLowBall( const MPObject & ball ) { const double ang = calcRadDir( ball ); + const double un_quant_dist = calcUnQuantDist( ball ); - if( std::fabs( ang ) < self().visibleAngle() * 0.5 ) + if( std::fabs( ang ) < self().visibleAngle() * 0.5 + && un_quant_dist < self().playerType()->ballMaxObservationLength()) { serializer().serializeVisualObject( transport(), calcName( ball ), calcDegDir( ang ) ); } - else if( calcUnQuantDist( ball ) <= self().VISIBLE_DISTANCE ) + else if( un_quant_dist <= self().VISIBLE_DISTANCE ) { serializer().serializeVisualObject( transport(), calcCloseName( ball ), @@ -295,47 +562,37 @@ void VisualSenderPlayerV1::sendHighBall( const MPObject & ball ) { const double ang = calcRadDir( ball ); - //const double un_quant_dist = calcUnQuantDist( ball ); - double un_quant_dist = self().pos().distance2( ball.pos() ); + const double actual_dist = calcUnQuantDist( ball ); + const double noisy_dist = noisyObservation().calcDist( actual_dist, ball.pos().distance( cachedFocusPoint() ) ); - if ( std::fabs( ang ) < self().visibleAngle() * 0.5 ) + if ( std::fabs( ang ) < self().visibleAngle() * 0.5 + && actual_dist < self().playerType()->ballMaxObservationLength() ) { - un_quant_dist = std::sqrt( un_quant_dist ); - const double quant_dist = calcQuantDist( un_quant_dist, - self().distQStep() ); - - //double prob = ( ( quant_dist - UNUM_FAR_LENGTH ) - // / ( UNUM_TOOFAR_LENGTH - UNUM_FAR_LENGTH ) ); - double prob = ( ( quant_dist - self().unumFarLength() ) - / ( self().unumTooFarLength() - self().unumFarLength() ) ); - - if ( decide( prob ) ) + if ( decide( calcNoBallVelProb( noisy_dist ) ) ) { serializer().serializeVisualObject( transport(), calcName( ball ), - quant_dist, + noisy_dist, calcDegDir( ang ) ); } else { double dist_chg, dir_chg; - calcVel( ball.vel(), ball.pos(), - un_quant_dist, quant_dist, - dist_chg, dir_chg ); + calcNoisyVel( ball.vel(), ball.pos(), actual_dist, noisy_dist, &dist_chg, &dir_chg ); + serializer().serializeVisualObject( transport(), calcName( ball ), - quant_dist, + noisy_dist, calcDegDir( ang ), dist_chg, dir_chg ); } } - else if ( un_quant_dist <= self().VISIBLE_DISTANCE2 ) + else if ( actual_dist <= self().VISIBLE_DISTANCE ) { serializer().serializeVisualObject( transport(), calcCloseName( ball ), - calcQuantDist( std::sqrt( un_quant_dist ), - self().distQStep() ), + noisy_dist, calcDegDir( ang ) ); } } @@ -344,19 +601,14 @@ void VisualSenderPlayerV1::sendLowPlayer( const Player & player ) { const double ang = calcRadDir( player ); - //const double un_quant_dist = calcUnQuantDist( player ); - const double un_quant_dist2 = self().pos().distance2( player.pos() ); + const double actual_dist = calcUnQuantDist( player ); - if ( std::fabs( ang ) < self().visibleAngle() * 0.5 ) + if ( std::fabs( ang ) < self().visibleAngle() * 0.5 + && actual_dist < self().playerType()->playerMaxObservationLength() ) { - const double quant_dist = calcQuantDist( std::sqrt( un_quant_dist2 ), - self().distQStep() ); - - //double prob = ( ( quant_dist - TEAM_FAR_LENGTH ) - // / ( TEAM_TOOFAR_LENGTH - TEAM_FAR_LENGTH ) ); - double prob = ( ( quant_dist - self().teamFarLength() ) - / ( self().teamTooFarLength() - self().teamFarLength() ) ); - if ( decide( prob ) ) + const double noisy_dist = calcNoisyDist( player, actual_dist ); + + if ( decide( calcNoTeamProb( noisy_dist ) ) ) { serializer().serializeVisualObject( transport(), calcTFarName( player ), @@ -364,11 +616,7 @@ VisualSenderPlayerV1::sendLowPlayer( const Player & player ) } else { - //prob = ( ( quant_dist - UNUM_FAR_LENGTH ) - // / ( UNUM_TOOFAR_LENGTH - UNUM_FAR_LENGTH ) ); - prob = ( ( quant_dist - self().unumFarLength() ) - / ( self().unumTooFarLength() - self().unumFarLength() ) ); - if ( decide( prob ) ) + if ( decide( calcNoUnumProb( noisy_dist ) ) ) { serializer().serializeVisualObject( transport(), calcUFarName( player ), @@ -382,7 +630,7 @@ VisualSenderPlayerV1::sendLowPlayer( const Player & player ) } } } - else if ( un_quant_dist2 <= self().VISIBLE_DISTANCE2 ) + else if ( actual_dist <= self().VISIBLE_DISTANCE ) { serializer().serializeVisualObject( transport(), calcCloseName( player ), @@ -390,73 +638,57 @@ VisualSenderPlayerV1::sendLowPlayer( const Player & player ) } } - void VisualSenderPlayerV1::sendHighPlayer( const Player & player ) { const double ang = calcRadDir( player ); + const double actual_dist = self().pos().distance( player.pos() ); + const double noisy_dist = calcNoisyDist( player, actual_dist ); - //const double un_quant_dist = calcUnQuantDist( player ); - double un_quant_dist = self().pos().distance2( player.pos() ); - - if ( std::fabs( ang ) < self().visibleAngle() * 0.5 ) + if ( std::fabs( ang ) < self().visibleAngle() * 0.5 + && actual_dist < self().playerType()->playerMaxObservationLength() ) { - un_quant_dist = std::sqrt( un_quant_dist ); - const double quant_dist = calcQuantDist( un_quant_dist, - self().distQStep() ); - //double prob = ( ( quant_dist - TEAM_FAR_LENGTH ) - // / ( TEAM_TOOFAR_LENGTH - TEAM_FAR_LENGTH ) ); - double prob = ( ( quant_dist - self().teamFarLength() ) - / ( self().teamTooFarLength() - self().teamFarLength() ) ); - - if ( decide( prob ) ) + if ( decide( calcNoTeamProb( noisy_dist ) ) ) { + // no team information serializer().serializeVisualObject( transport(), calcTFarName( player ), - quant_dist, + noisy_dist, calcDegDir( ang ) ); } else { - //prob = ( ( quant_dist - UNUM_FAR_LENGTH ) - // / ( UNUM_TOOFAR_LENGTH - UNUM_FAR_LENGTH ) ); - prob = ( ( quant_dist - self().unumFarLength() ) - / ( self().unumTooFarLength() - self().unumFarLength() ) ); - - if ( decide( prob ) ) + if ( decide( calcNoUnumProb( noisy_dist ) ) ) { + // no unum information serializePlayer( player, calcUFarName( player ), - quant_dist, + noisy_dist, calcDegDir( ang ) ); } else { double dist_chg, dir_chg; - calcVel( player.vel(), player.pos(), - un_quant_dist, quant_dist, - dist_chg, dir_chg ); + calcNoisyVel( player.vel(), player.pos(), actual_dist, noisy_dist, &dist_chg, &dir_chg ); + serializePlayer( player, calcPlayerName( player ), - quant_dist, + noisy_dist, calcDegDir( ang ), dist_chg, dir_chg ); } } } - else if ( un_quant_dist <= player.VISIBLE_DISTANCE2 ) + else if ( actual_dist <= player.VISIBLE_DISTANCE ) { - //un_quant_dist = std::sqrt( un_quant_dist ); serializer().serializeVisualObject( transport(), calcCloseName( player ), - calcQuantDist( std::sqrt( un_quant_dist ), - self().distQStep() ), + noisy_dist, calcDegDir( ang ) ); } } - bool VisualSenderPlayerV1::sendLine( const PObject & line ) { @@ -590,41 +822,67 @@ VisualSenderPlayerV1::serializeHighLine( const std::string & name, serializer().serializeVisualObject( transport(), name, dist, dir ); } + +double +VisualSenderPlayerV1::calcNoisyDist( const PObject & obj, + const double dist ) const +{ + return noisyObservation().calcDist( dist, obj.pos().distance( cachedFocusPoint() ) ); +} + +double +VisualSenderPlayerV1::calcNoisyDistLandmark( const PObject & obj, + const double dist ) const +{ + return noisyObservation().calcDistLandmark( dist, obj.pos().distance( cachedFocusPoint() ) ); +} + void -VisualSenderPlayerV1::calcVel( const PVector & obj_vel, - const PVector & obj_pos, - const double & un_quant_dist, - const double & quant_dist, - double& dist_chg, - double& dir_chg ) const +VisualSenderPlayerV1::calcNoisyVel( const PVector & obj_vel, + const PVector & obj_pos, + const double actual_dist, + const double noisy_dist, + double * dist_chg, + double * dir_chg ) const { - if ( un_quant_dist != 0.0 ) - { - const PVector vtmp = obj_vel - self().vel(); - PVector etmp = obj_pos - self().pos(); - etmp /= un_quant_dist; - - dist_chg = vtmp.x * etmp.x + vtmp.y * etmp.y; -// dir_chg = RAD2DEG * ( vtmp.y * etmp.x -// - vtmp.x * etmp.y ) / un_quant_dist; - dir_chg = vtmp.y * etmp.x - vtmp.x * etmp.y; - dir_chg /= un_quant_dist; - dir_chg *= RAD2DEG; - - dir_chg = ( dir_chg == 0.0 - ? 0.0 - : Quantize( dir_chg, self().dirQStep() ) ); - dist_chg = ( quant_dist - * Quantize( dist_chg - / un_quant_dist, 0.02 ) ); - } - else - { - dir_chg = 0.0; - dist_chg = 0.0; - } + noisyObservation().calcVel( obj_vel, obj_pos, actual_dist, noisy_dist, dist_chg, dir_chg ); } +// void +// VisualSenderPlayerV1::calcVel( const PVector & obj_vel, +// const PVector & obj_pos, +// const double & actual_dist, +// const double & quant_dist, +// double& dist_chg, +// double& dir_chg ) const +// { +// if ( actual_dist != 0.0 ) +// { +// const PVector vtmp = obj_vel - self().vel(); +// PVector etmp = obj_pos - self().pos(); +// etmp /= actual_dist; + +// dist_chg = vtmp.x * etmp.x + vtmp.y * etmp.y; +// // dir_chg = RAD2DEG * ( vtmp.y * etmp.x +// // - vtmp.x * etmp.y ) / actual_dist; +// dir_chg = vtmp.y * etmp.x - vtmp.x * etmp.y; +// dir_chg /= actual_dist; +// dir_chg *= RAD2DEG; + +// dir_chg = ( dir_chg == 0.0 +// ? 0.0 +// : Quantize( dir_chg, self().dirQStep() ) ); +// dist_chg = ( quant_dist +// * Quantize( dist_chg +// / actual_dist, 0.02 ) ); +// } +// else +// { +// dir_chg = 0.0; +// dist_chg = 0.0; +// } +// } + void VisualSenderPlayerV1::serializePlayer( const Player &, const std::string & name, @@ -863,8 +1121,8 @@ VisualSenderPlayerV8::calcPointDir( const Player & player ) // of this range. double sigma = self().pos().distance( player.pos() ) / self().playerType()->teamTooFarLength(); - // / 60.0; // this should be replaced by the line below. - // // / ServerParam::instance().getTeamTooFarLength (); + // / 60.0; // this should be replaced by the line below. + // // / ServerParam::instance().getTeamTooFarLength (); sigma = std::pow( sigma, 4 ); // 4 should be parameterized // sigma is now a range between 0 and 1.0 @@ -1037,10 +1295,8 @@ VisualSenderPlayerV13::~VisualSenderPlayerV13() */ VisualSenderPlayerV18::VisualSenderPlayerV18( const Params & params ) - : VisualSenderPlayerV13( params ), - M_focus_point( 0.0, 0.0 ) + : VisualSenderPlayerV13( params ) { - } VisualSenderPlayerV18::~VisualSenderPlayerV18() @@ -1048,287 +1304,10 @@ VisualSenderPlayerV18::~VisualSenderPlayerV18() } - void VisualSenderPlayerV18::updateCache() { - M_focus_point = self().focusPoint(); -} - - -void -VisualSenderPlayerV18::sendLowFlag( const PObject & flag ) -{ - const double ang = calcRadDir( flag ); - const double un_quant_dist = calcUnQuantDist( flag ); - - if ( std::fabs( ang ) < self().visibleAngle() * 0.5 - && un_quant_dist < self().playerType()->flagMaxObservationLength() ) - { - serializer().serializeVisualObject( transport(), - calcName( flag ), - calcDegDir( ang ) ); - } - else if ( un_quant_dist <= self().VISIBLE_DISTANCE ) - { - serializer().serializeVisualObject( transport(), - calcCloseName( flag ), - calcDegDir( ang ) ); - } -} - -void -VisualSenderPlayerV18::sendHighFlag( const PObject & flag ) -{ - const double ang = calcRadDir( flag ); - const double un_quant_dist = calcUnQuantDist( flag ); - const double quant_dist = calcQuantDistFocusPoint( flag, un_quant_dist, self().landDistQStep() ); - - if ( std::fabs( ang ) < self().visibleAngle() * 0.5 - && un_quant_dist < self().playerType()->flagMaxObservationLength() ) - { - double prob = 0.0; - if ( self().playerType()->flagChgTooFarLength() > self().playerType()->flagChgFarLength() ) - { - prob = ( ( quant_dist - self().playerType()->flagChgFarLength() ) - / ( self().playerType()->flagChgTooFarLength() - self().playerType()->flagChgFarLength() ) ); - } - - if ( decide( prob ) ) - { - serializer().serializeVisualObject( transport(), - calcName( flag ), - quant_dist, - calcDegDir( ang ) ); - } - else - { - double dist_chg, dir_chg; - calcVel( PVector(), flag.pos(), - un_quant_dist, quant_dist, - dist_chg, dir_chg ); - serializer().serializeVisualObject( transport(), - calcName( flag ), - quant_dist, - calcDegDir( ang ), - dist_chg, - dir_chg ); - } - } - else if ( un_quant_dist <= self().VISIBLE_DISTANCE ) - { - serializer().serializeVisualObject( transport(), - calcCloseName( flag ), - quant_dist, - calcDegDir( ang ) ); - } -} - - -void -VisualSenderPlayerV18::sendLowBall( const MPObject & ball ) -{ - const double ang = calcRadDir( ball ); - const double un_quant_dist = calcUnQuantDist( ball ); - - if( std::fabs( ang ) < self().visibleAngle() * 0.5 - && un_quant_dist < self().playerType()->ballMaxObservationLength()) - { - serializer().serializeVisualObject( transport(), - calcName( ball ), - calcDegDir( ang ) ); - } - else if( un_quant_dist <= self().VISIBLE_DISTANCE ) - { - serializer().serializeVisualObject( transport(), - calcCloseName( ball ), - calcDegDir( ang ) ); - } -} - - -void -VisualSenderPlayerV18::sendHighBall( const MPObject & ball ) -{ - const double ang = calcRadDir( ball ); - const double un_quant_dist = calcUnQuantDist( ball ); - const double quant_dist = calcQuantDistFocusPoint( ball, - un_quant_dist, - self().distQStep() ); - if ( std::fabs( ang ) < self().visibleAngle() * 0.5 - && un_quant_dist < self().playerType()->ballMaxObservationLength() ) - { - double prob = 0.0; - if ( self().playerType()->ballVelTooFarLength() > self().playerType()->ballVelFarLength() ) - { - prob = ( ( quant_dist - self().playerType()->ballVelFarLength() ) - / ( self().playerType()->ballVelTooFarLength() - self().playerType()->ballVelFarLength() ) ); - } - - if ( decide( prob ) ) - { - serializer().serializeVisualObject( transport(), - calcName( ball ), - quant_dist, - calcDegDir( ang ) ); - } - else - { - double dist_chg, dir_chg; - calcVel( ball.vel(), ball.pos(), - un_quant_dist, quant_dist, - dist_chg, dir_chg ); - serializer().serializeVisualObject( transport(), - calcName( ball ), - quant_dist, - calcDegDir( ang ), - dist_chg, - dir_chg ); - } - } - else if ( un_quant_dist <= self().VISIBLE_DISTANCE ) - { - serializer().serializeVisualObject( transport(), - calcCloseName( ball ), - quant_dist, - calcDegDir( ang ) ); - } -} - - -void -VisualSenderPlayerV18::sendLowPlayer( const Player & player ) -{ - const double ang = calcRadDir( player ); - const double un_quant_dist = calcUnQuantDist( player ); - - if ( std::fabs( ang ) < self().visibleAngle() * 0.5 - && un_quant_dist < self().playerType()->playerMaxObservationLength() ) - { - const double quant_dist = calcQuantDist( un_quant_dist, - self().distQStep() ); - double prob = 0.0; - if ( self().playerType()->teamTooFarLength() > self().playerType()->teamFarLength() ) - { - prob = ( ( quant_dist - self().playerType()->teamFarLength() ) - / ( self().playerType()->teamTooFarLength() - self().playerType()->teamFarLength() ) ); - } - - if ( decide( prob ) ) - { - serializer().serializeVisualObject( transport(), - calcTFarName( player ), - calcDegDir( ang ) ); - } - else - { - prob = 0.0; - if ( self().playerType()->unumTooFarLength() > self().playerType()->unumFarLength() ) - { - prob = ( ( quant_dist - self().playerType()->unumFarLength() ) - / ( self().playerType()->unumTooFarLength() - self().playerType()->unumFarLength() ) ); - } - - if ( decide( prob ) ) - { - serializer().serializeVisualObject( transport(), - calcUFarName( player ), - calcDegDir( ang ) ); - } - else - { - serializer().serializeVisualObject( transport(), - calcPlayerName( player ), - calcDegDir( ang ) ); - } - } - } - else if ( un_quant_dist <= self().VISIBLE_DISTANCE ) - { - serializer().serializeVisualObject( transport(), - calcCloseName( player ), - calcDegDir( ang ) ); - } -} - - -void -VisualSenderPlayerV18::sendHighPlayer( const Player & player ) -{ - const double ang = calcRadDir( player ); - const double un_quant_dist = self().pos().distance( player.pos() ); - const double quant_dist = calcQuantDistFocusPoint( player, - un_quant_dist, - self().distQStep() ); - - if ( std::fabs( ang ) < self().visibleAngle() * 0.5 - && un_quant_dist < self().playerType()->playerMaxObservationLength() ) - { - double prob = 0.0; - if ( self().playerType()->teamTooFarLength() > self().playerType()->teamFarLength() ) - { - prob = ( ( quant_dist - self().playerType()->teamFarLength() ) - / ( self().playerType()->teamTooFarLength() - self().playerType()->teamFarLength() ) ); - } - - if ( decide( prob ) ) - { - // no team information - serializer().serializeVisualObject( transport(), - calcTFarName( player ), - quant_dist, - calcDegDir( ang ) ); - } - else - { - prob = 0.0; - if ( self().playerType()->unumTooFarLength() > self().playerType()->unumFarLength() ) - { - prob = ( ( quant_dist - self().playerType()->unumFarLength() ) - / ( self().playerType()->unumTooFarLength() - self().playerType()->unumFarLength() ) ); - } - - if ( decide( prob ) ) - { - // no unum information - serializePlayer( player, - calcUFarName( player ), - quant_dist, - calcDegDir( ang ) ); - } - else - { - double dist_chg, dir_chg; - calcVel( player.vel(), player.pos(), - un_quant_dist, quant_dist, - dist_chg, dir_chg ); - serializePlayer( player, - calcPlayerName( player ), - quant_dist, - calcDegDir( ang ), - dist_chg, - dir_chg ); - } - } - } - else if ( un_quant_dist <= player.VISIBLE_DISTANCE ) - { - serializer().serializeVisualObject( transport(), - calcCloseName( player ), - quant_dist, - calcDegDir( ang ) ); - } -} - -double -VisualSenderPlayerV18::calcQuantDistFocusPoint( const PObject & obj, - const double unquant_dist, - const double qstep ) -{ - const double unquant_dist_focus_point = obj.pos().distance( M_focus_point ); - const double quant_dist_focus_point = std::exp( Quantize( std::log( unquant_dist_focus_point + EPS ), qstep ) ); - - return Quantize( std::max( 0.0, unquant_dist - ( unquant_dist_focus_point - quant_dist_focus_point ) ), 0.1 ); + setCachedFocusPoint( self().focusPoint() ); } /*! @@ -1365,6 +1344,7 @@ RegHolder vp15 = VisualSenderPlayer::factory().autoReg( &create< VisualSenderPla RegHolder vp16 = VisualSenderPlayer::factory().autoReg( &create< VisualSenderPlayerV13 >, 16 ); RegHolder vp17 = VisualSenderPlayer::factory().autoReg( &create< VisualSenderPlayerV13 >, 17 ); RegHolder vp18 = VisualSenderPlayer::factory().autoReg( &create< VisualSenderPlayerV18 >, 18 ); +RegHolder vp19 = VisualSenderPlayer::factory().autoReg( &create< VisualSenderPlayerV18 >, 19 ); } } diff --git a/src/visualsenderplayer.h b/src/visualsenderplayer.h index 3b3c1ac8..0f737a9a 100644 --- a/src/visualsenderplayer.h +++ b/src/visualsenderplayer.h @@ -37,6 +37,7 @@ class Stadium; namespace rcss { class SerializerPlayer; +class NoisyObservation; /*! //=================================================================== @@ -82,6 +83,10 @@ class VisualSenderPlayer int M_sendcnt; +protected: + std::shared_ptr< const NoisyObservation > M_noisy_observation; + PVector M_cached_focus_point; + public: typedef std::shared_ptr< VisualSenderPlayer > Ptr; typedef Ptr (*Creator)( const VisualSenderPlayer::Params & ); @@ -104,6 +109,11 @@ class VisualSenderPlayer return *M_serializer; } + const NoisyObservation & noisyObservation() const + { + return *M_noisy_observation; + } + const Player & self() const { @@ -131,10 +141,15 @@ class VisualSenderPlayer M_sendcnt = 0; } - virtual - void updateCache() - { } + const PVector & cachedFocusPoint() const + { + return M_cached_focus_point; + } + void setCachedFocusPoint( const PVector & pos ) + { + M_cached_focus_point = pos; + } }; @@ -247,6 +262,42 @@ class VisualSenderPlayerV1 void sendLines(); protected: + + virtual + void updateCache() + { + setCachedFocusPoint( self().pos() ); + } + + double calcNoVelProb( const double dist ) const + { + return ( ( dist - self().unumFarLength() ) / ( self().unumTooFarLength() - self().unumFarLength() ) ); + } + + virtual + double calcNoFlagVelProb( const double dist ) const + { + return calcNoVelProb( dist ); + } + + virtual + double calcNoBallVelProb( const double dist ) const + { + return calcNoVelProb( dist ); + } + + virtual + double calcNoTeamProb( const double dist ) const + { + return ( ( dist - self().teamFarLength() ) / ( self().teamTooFarLength() - self().teamFarLength() ) ); + } + + virtual + double calcNoUnumProb( const double dist ) const + { + return calcNoVelProb( dist ); + } + virtual void sendLowFlag( const PObject & flag ); @@ -311,6 +362,17 @@ class VisualSenderPlayerV1 return self().pos().distance( obj.pos() ); } + double calcNoisyDist( const PObject & obj, + const double dist ) const; + double calcNoisyDistLandmark( const PObject & obj, + const double dist ) const; + void calcNoisyVel( const PVector & obj_vel, + const PVector & obj_pos, + const double actual_dist, + const double noisy_dist, + double * dist_chg, + double * dir_chg ) const; + double calcQuantDist( const double & dist, const double & qstep ) const { @@ -327,13 +389,12 @@ class VisualSenderPlayerV1 qstep ) ), 0.1 ); } - - void calcVel( const PVector & obj_vel, - const PVector & obj_pos, - const double & un_quant_dist, - const double & quant_dist, - double & dist_chg, - double & dir_chg ) const; + // void calcVel( const PVector & obj_vel, + // const PVector & obj_pos, + // const double & un_quant_dist, + // const double & quant_dist, + // double & dist_chg, + // double & dir_chg ) const; bool decide( const double & prob ) { @@ -648,8 +709,6 @@ class VisualSenderPlayerV13 class VisualSenderPlayerV18 : public VisualSenderPlayerV13 { -private: - PVector M_focus_point; public: VisualSenderPlayerV18( const Params & params ); @@ -663,24 +722,32 @@ class VisualSenderPlayerV18 void updateCache() override; virtual - void sendLowFlag( const PObject & flag ) override; - virtual - void sendHighFlag( const PObject & flag ) override; + double calcNoFlagVelProb( double dist ) const override + { + return ( ( dist - self().playerType()->landVelFarLength() ) + / ( self().playerType()->landVelTooFarLength() - self().playerType()->landVelFarLength() ) ); + } virtual - void sendLowBall( const MPObject & ball ) override; - virtual - void sendHighBall( const MPObject & ball ) override; + double calcNoBallVelProb( double dist ) const override + { + return ( ( dist - self().playerType()->ballVelFarLength() ) + / ( self().playerType()->ballVelTooFarLength() - self().playerType()->ballVelFarLength() ) ); + } virtual - void sendLowPlayer( const Player & player ) override; - virtual - void sendHighPlayer( const Player & player ) override; + double calcNoTeamProb( double dist ) const override + { + return ( ( dist - self().playerType()->teamFarLength() ) + / ( self().playerType()->teamTooFarLength() - self().playerType()->teamFarLength() ) ); + } virtual - double calcQuantDistFocusPoint( const PObject & obj, - const double unquant_dist, - const double q_step ); + double calcNoUnumProb( double dist ) const override + { + return ( ( dist - self().playerType()->unumFarLength() ) + / ( self().playerType()->unumTooFarLength() - self().playerType()->unumFarLength() ) ); + } }; }