From fd29d159836cb9b616cec74543554ffb29e9daad Mon Sep 17 00:00:00 2001 From: dbisig Date: Sun, 6 Sep 2020 16:59:30 +0200 Subject: [PATCH] first commit --- README.md | 45 + addon_config.mk | 74 + src/dab_flock_acceleration_behavior.cpp | 110 + src/dab_flock_acceleration_behavior.h | 101 + src/dab_flock_add_agents_event.cpp | 70 + src/dab_flock_add_agents_event.h | 42 + src/dab_flock_add_space_event.cpp | 201 ++ src/dab_flock_add_space_event.h | 61 + src/dab_flock_agent.cpp | 702 +++++ src/dab_flock_agent.h | 433 +++ src/dab_flock_agent_id_behavior.cpp | 65 + src/dab_flock_agent_id_behavior.h | 83 + src/dab_flock_alignment_behavior.cpp | 141 + src/dab_flock_alignment_behavior.h | 104 + src/dab_flock_behavior.cpp | 352 +++ src/dab_flock_behavior.h | 203 ++ src/dab_flock_behavior_includes.h | 51 + src/dab_flock_behavior_list.cpp | 188 ++ src/dab_flock_behavior_list.h | 153 + src/dab_flock_boundary_mirror_behavior.cpp | 100 + src/dab_flock_boundary_mirror_behavior.h | 100 + src/dab_flock_boundary_repulsion_behavior.cpp | 117 + src/dab_flock_boundary_repulsion_behavior.h | 99 + src/dab_flock_boundary_wrap_behavior.cpp | 94 + src/dab_flock_boundary_wrap_behavior.h | 93 + src/dab_flock_circular_behavior.cpp | 112 + src/dab_flock_circular_behavior.h | 101 + src/dab_flock_clear_simulation_event.cpp | 62 + src/dab_flock_clear_simulation_event.h | 40 + src/dab_flock_cohesion_behavior.cpp | 150 + src/dab_flock_cohesion_behavior.h | 99 + src/dab_flock_com.cpp | 2068 +++++++++++++ src/dab_flock_com.h | 484 +++ src/dab_flock_cone_vision_behavior.cpp | 128 + src/dab_flock_cone_vision_behavior.h | 101 + src/dab_flock_copy_behavior.cpp | 75 + src/dab_flock_copy_behavior.h | 86 + src/dab_flock_damping_behavior.cpp | 98 + src/dab_flock_damping_behavior.h | 95 + ...b_flock_distance_field_follow_behavior.cpp | 148 + ...dab_flock_distance_field_follow_behavior.h | 109 + src/dab_flock_env.cpp | 227 ++ src/dab_flock_env.h | 178 ++ src/dab_flock_env_agent_interact_behavior.cpp | 97 + src/dab_flock_env_agent_interact_behavior.h | 53 + src/dab_flock_env_behavior.cpp | 158 + src/dab_flock_env_behavior.h | 112 + src/dab_flock_env_clamp_behavior.cpp | 107 + src/dab_flock_env_clamp_behavior.h | 53 + src/dab_flock_env_decay_behavior.cpp | 101 + src/dab_flock_env_decay_behavior.h | 52 + src/dab_flock_env_diffusion_behavior.cpp | 199 ++ src/dab_flock_env_diffusion_behavior.h | 52 + ...ab_flock_env_gierer_meinhardt_behavior.cpp | 122 + src/dab_flock_env_gierer_meinhardt_behavior.h | 57 + src/dab_flock_env_gray_scott_behavior.cpp | 118 + src/dab_flock_env_gray_scott_behavior.h | 54 + src/dab_flock_env_parameter.cpp | 361 +++ src/dab_flock_env_parameter.h | 257 ++ src/dab_flock_euler_integration.cpp | 84 + src/dab_flock_euler_integration.h | 79 + src/dab_flock_evasion_behavior.cpp | 126 + src/dab_flock_evasion_behavior.h | 93 + src/dab_flock_event_includes.h | 35 + src/dab_flock_grid_avg_behavior.cpp | 132 + src/dab_flock_grid_avg_behavior.h | 97 + src/dab_flock_line_follow_behavior.cpp | 334 ++ src/dab_flock_line_follow_behavior.h | 98 + ...lock_neighbor_direction_store_behavior.cpp | 106 + ..._flock_neighbor_direction_store_behavior.h | 94 + ...flock_neighbor_distance_store_behavior.cpp | 91 + ...b_flock_neighbor_distance_store_behavior.h | 94 + ...ab_flock_neighbor_index_store_behavior.cpp | 91 + src/dab_flock_neighbor_index_store_behavior.h | 93 + ...lock_neighbor_parameter_store_behavior.cpp | 104 + ..._flock_neighbor_parameter_store_behavior.h | 78 + src/dab_flock_neighbor_store_behavior.cpp | 93 + src/dab_flock_neighbor_store_behavior.h | 96 + src/dab_flock_orbit_behavior.cpp | 177 ++ src/dab_flock_orbit_behavior.h | 121 + src/dab_flock_osc_control.cpp | 949 ++++++ src/dab_flock_osc_control.h | 158 + src/dab_flock_parameter.cpp | 388 +++ src/dab_flock_parameter.h | 358 +++ src/dab_flock_parameter_combine_behavior.cpp | 81 + src/dab_flock_parameter_combine_behavior.h | 87 + src/dab_flock_parameter_list.cpp | 185 ++ src/dab_flock_parameter_list.h | 182 ++ src/dab_flock_parameter_mag_behavior.cpp | 73 + src/dab_flock_parameter_mag_behavior.h | 88 + src/dab_flock_parameter_map_behavior.cpp | 98 + src/dab_flock_parameter_map_behavior.h | 98 + src/dab_flock_parameter_print_behavior.cpp | 64 + src/dab_flock_parameter_print_behavior.h | 90 + src/dab_flock_parameter_scale_behavior.cpp | 94 + src/dab_flock_parameter_scale_behavior.h | 97 + ..._parameter_threshold_to_event_behavior.cpp | 161 + ...ck_parameter_threshold_to_event_behavior.h | 152 + src/dab_flock_randomize_behavior.cpp | 80 + src/dab_flock_randomize_behavior.h | 87 + src/dab_flock_remove_agents_event.cpp | 101 + src/dab_flock_remove_agents_event.h | 47 + src/dab_flock_reset_behavior.cpp | 85 + src/dab_flock_reset_behavior.h | 92 + src/dab_flock_restore_simulation_event.cpp | 68 + src/dab_flock_restore_simulation_event.h | 42 + src/dab_flock_save_simulation_event.cpp | 70 + src/dab_flock_save_simulation_event.h | 42 + src/dab_flock_serialize.cpp | 2719 +++++++++++++++++ src/dab_flock_serialize.h | 147 + src/dab_flock_set_parameter_event.cpp | 359 +++ src/dab_flock_set_parameter_event.h | 66 + src/dab_flock_set_simulation_rate_event.cpp | 62 + src/dab_flock_set_simulation_rate_event.h | 40 + src/dab_flock_simulation.cpp | 427 +++ src/dab_flock_simulation.h | 280 ++ src/dab_flock_spiral_behavior.cpp | 135 + src/dab_flock_spiral_behavior.h | 99 + src/dab_flock_stats.cpp | 73 + src/dab_flock_stats.h | 80 + src/dab_flock_swarm.cpp | 1995 ++++++++++++ src/dab_flock_swarm.h | 897 ++++++ src/dab_flock_swarm_behavior.cpp | 344 +++ src/dab_flock_swarm_behavior.h | 182 ++ src/dab_flock_target_parameter_behavior.cpp | 115 + src/dab_flock_target_parameter_behavior.h | 104 + src/dab_flock_text_tools.cpp | 189 ++ src/dab_flock_text_tools.h | 48 + src/dab_flock_visual.cpp | 739 +++++ src/dab_flock_visual.h | 159 + src/dab_flock_visual_agent_shape.cpp | 166 + src/dab_flock_visual_agent_shape.h | 68 + src/dab_flock_visual_agent_trail.cpp | 151 + src/dab_flock_visual_agent_trail.h | 65 + src/dab_flock_visual_event_includes.h | 16 + src/dab_flock_visual_grid_space.cpp | 170 ++ src/dab_flock_visual_grid_space.h | 62 + src/dab_flock_visual_hide_space_event.cpp | 49 + src/dab_flock_visual_hide_space_event.h | 42 + src/dab_flock_visual_hide_swarm_event.cpp | 49 + src/dab_flock_visual_hide_swarm_event.h | 42 + src/dab_flock_visual_neighbor_space.cpp | 144 + src/dab_flock_visual_neighbor_space.h | 58 + src/dab_flock_visual_show_space_event.cpp | 67 + src/dab_flock_visual_show_space_event.h | 46 + src/dab_flock_visual_show_swarm_event.cpp | 80 + src/dab_flock_visual_show_swarm_event.h | 50 + src/dab_flock_visual_swarm.cpp | 340 +++ src/dab_flock_visual_swarm.h | 76 + 149 files changed, 27529 insertions(+) create mode 100644 README.md create mode 100644 addon_config.mk create mode 100644 src/dab_flock_acceleration_behavior.cpp create mode 100644 src/dab_flock_acceleration_behavior.h create mode 100644 src/dab_flock_add_agents_event.cpp create mode 100644 src/dab_flock_add_agents_event.h create mode 100644 src/dab_flock_add_space_event.cpp create mode 100644 src/dab_flock_add_space_event.h create mode 100644 src/dab_flock_agent.cpp create mode 100644 src/dab_flock_agent.h create mode 100644 src/dab_flock_agent_id_behavior.cpp create mode 100644 src/dab_flock_agent_id_behavior.h create mode 100644 src/dab_flock_alignment_behavior.cpp create mode 100644 src/dab_flock_alignment_behavior.h create mode 100644 src/dab_flock_behavior.cpp create mode 100644 src/dab_flock_behavior.h create mode 100644 src/dab_flock_behavior_includes.h create mode 100644 src/dab_flock_behavior_list.cpp create mode 100644 src/dab_flock_behavior_list.h create mode 100644 src/dab_flock_boundary_mirror_behavior.cpp create mode 100644 src/dab_flock_boundary_mirror_behavior.h create mode 100644 src/dab_flock_boundary_repulsion_behavior.cpp create mode 100644 src/dab_flock_boundary_repulsion_behavior.h create mode 100644 src/dab_flock_boundary_wrap_behavior.cpp create mode 100644 src/dab_flock_boundary_wrap_behavior.h create mode 100644 src/dab_flock_circular_behavior.cpp create mode 100644 src/dab_flock_circular_behavior.h create mode 100644 src/dab_flock_clear_simulation_event.cpp create mode 100644 src/dab_flock_clear_simulation_event.h create mode 100644 src/dab_flock_cohesion_behavior.cpp create mode 100644 src/dab_flock_cohesion_behavior.h create mode 100644 src/dab_flock_com.cpp create mode 100644 src/dab_flock_com.h create mode 100644 src/dab_flock_cone_vision_behavior.cpp create mode 100644 src/dab_flock_cone_vision_behavior.h create mode 100644 src/dab_flock_copy_behavior.cpp create mode 100644 src/dab_flock_copy_behavior.h create mode 100644 src/dab_flock_damping_behavior.cpp create mode 100644 src/dab_flock_damping_behavior.h create mode 100644 src/dab_flock_distance_field_follow_behavior.cpp create mode 100644 src/dab_flock_distance_field_follow_behavior.h create mode 100644 src/dab_flock_env.cpp create mode 100644 src/dab_flock_env.h create mode 100644 src/dab_flock_env_agent_interact_behavior.cpp create mode 100644 src/dab_flock_env_agent_interact_behavior.h create mode 100644 src/dab_flock_env_behavior.cpp create mode 100644 src/dab_flock_env_behavior.h create mode 100644 src/dab_flock_env_clamp_behavior.cpp create mode 100644 src/dab_flock_env_clamp_behavior.h create mode 100644 src/dab_flock_env_decay_behavior.cpp create mode 100644 src/dab_flock_env_decay_behavior.h create mode 100644 src/dab_flock_env_diffusion_behavior.cpp create mode 100644 src/dab_flock_env_diffusion_behavior.h create mode 100644 src/dab_flock_env_gierer_meinhardt_behavior.cpp create mode 100644 src/dab_flock_env_gierer_meinhardt_behavior.h create mode 100644 src/dab_flock_env_gray_scott_behavior.cpp create mode 100644 src/dab_flock_env_gray_scott_behavior.h create mode 100644 src/dab_flock_env_parameter.cpp create mode 100644 src/dab_flock_env_parameter.h create mode 100644 src/dab_flock_euler_integration.cpp create mode 100644 src/dab_flock_euler_integration.h create mode 100644 src/dab_flock_evasion_behavior.cpp create mode 100644 src/dab_flock_evasion_behavior.h create mode 100644 src/dab_flock_event_includes.h create mode 100644 src/dab_flock_grid_avg_behavior.cpp create mode 100644 src/dab_flock_grid_avg_behavior.h create mode 100644 src/dab_flock_line_follow_behavior.cpp create mode 100644 src/dab_flock_line_follow_behavior.h create mode 100644 src/dab_flock_neighbor_direction_store_behavior.cpp create mode 100644 src/dab_flock_neighbor_direction_store_behavior.h create mode 100644 src/dab_flock_neighbor_distance_store_behavior.cpp create mode 100644 src/dab_flock_neighbor_distance_store_behavior.h create mode 100644 src/dab_flock_neighbor_index_store_behavior.cpp create mode 100644 src/dab_flock_neighbor_index_store_behavior.h create mode 100644 src/dab_flock_neighbor_parameter_store_behavior.cpp create mode 100644 src/dab_flock_neighbor_parameter_store_behavior.h create mode 100644 src/dab_flock_neighbor_store_behavior.cpp create mode 100644 src/dab_flock_neighbor_store_behavior.h create mode 100644 src/dab_flock_orbit_behavior.cpp create mode 100644 src/dab_flock_orbit_behavior.h create mode 100644 src/dab_flock_osc_control.cpp create mode 100644 src/dab_flock_osc_control.h create mode 100644 src/dab_flock_parameter.cpp create mode 100644 src/dab_flock_parameter.h create mode 100644 src/dab_flock_parameter_combine_behavior.cpp create mode 100644 src/dab_flock_parameter_combine_behavior.h create mode 100644 src/dab_flock_parameter_list.cpp create mode 100644 src/dab_flock_parameter_list.h create mode 100644 src/dab_flock_parameter_mag_behavior.cpp create mode 100644 src/dab_flock_parameter_mag_behavior.h create mode 100644 src/dab_flock_parameter_map_behavior.cpp create mode 100644 src/dab_flock_parameter_map_behavior.h create mode 100644 src/dab_flock_parameter_print_behavior.cpp create mode 100644 src/dab_flock_parameter_print_behavior.h create mode 100644 src/dab_flock_parameter_scale_behavior.cpp create mode 100644 src/dab_flock_parameter_scale_behavior.h create mode 100644 src/dab_flock_parameter_threshold_to_event_behavior.cpp create mode 100644 src/dab_flock_parameter_threshold_to_event_behavior.h create mode 100644 src/dab_flock_randomize_behavior.cpp create mode 100644 src/dab_flock_randomize_behavior.h create mode 100644 src/dab_flock_remove_agents_event.cpp create mode 100644 src/dab_flock_remove_agents_event.h create mode 100644 src/dab_flock_reset_behavior.cpp create mode 100644 src/dab_flock_reset_behavior.h create mode 100644 src/dab_flock_restore_simulation_event.cpp create mode 100644 src/dab_flock_restore_simulation_event.h create mode 100644 src/dab_flock_save_simulation_event.cpp create mode 100644 src/dab_flock_save_simulation_event.h create mode 100644 src/dab_flock_serialize.cpp create mode 100644 src/dab_flock_serialize.h create mode 100644 src/dab_flock_set_parameter_event.cpp create mode 100644 src/dab_flock_set_parameter_event.h create mode 100644 src/dab_flock_set_simulation_rate_event.cpp create mode 100644 src/dab_flock_set_simulation_rate_event.h create mode 100644 src/dab_flock_simulation.cpp create mode 100644 src/dab_flock_simulation.h create mode 100644 src/dab_flock_spiral_behavior.cpp create mode 100644 src/dab_flock_spiral_behavior.h create mode 100644 src/dab_flock_stats.cpp create mode 100644 src/dab_flock_stats.h create mode 100644 src/dab_flock_swarm.cpp create mode 100644 src/dab_flock_swarm.h create mode 100644 src/dab_flock_swarm_behavior.cpp create mode 100644 src/dab_flock_swarm_behavior.h create mode 100644 src/dab_flock_target_parameter_behavior.cpp create mode 100644 src/dab_flock_target_parameter_behavior.h create mode 100644 src/dab_flock_text_tools.cpp create mode 100644 src/dab_flock_text_tools.h create mode 100644 src/dab_flock_visual.cpp create mode 100644 src/dab_flock_visual.h create mode 100644 src/dab_flock_visual_agent_shape.cpp create mode 100644 src/dab_flock_visual_agent_shape.h create mode 100644 src/dab_flock_visual_agent_trail.cpp create mode 100644 src/dab_flock_visual_agent_trail.h create mode 100644 src/dab_flock_visual_event_includes.h create mode 100644 src/dab_flock_visual_grid_space.cpp create mode 100644 src/dab_flock_visual_grid_space.h create mode 100644 src/dab_flock_visual_hide_space_event.cpp create mode 100644 src/dab_flock_visual_hide_space_event.h create mode 100644 src/dab_flock_visual_hide_swarm_event.cpp create mode 100644 src/dab_flock_visual_hide_swarm_event.h create mode 100644 src/dab_flock_visual_neighbor_space.cpp create mode 100644 src/dab_flock_visual_neighbor_space.h create mode 100644 src/dab_flock_visual_show_space_event.cpp create mode 100644 src/dab_flock_visual_show_space_event.h create mode 100644 src/dab_flock_visual_show_swarm_event.cpp create mode 100644 src/dab_flock_visual_show_swarm_event.h create mode 100644 src/dab_flock_visual_swarm.cpp create mode 100644 src/dab_flock_visual_swarm.h diff --git a/README.md b/README.md new file mode 100644 index 0000000..16eff96 --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +**Edit a file, create a new file, and clone from Bitbucket in under 2 minutes** + +When you're done, you can delete the content in this README and update the file with details for others getting started with your repository. + +*We recommend that you open this README in another tab as you perform the tasks below. You can [watch our video](https://youtu.be/0ocf7u76WSo) for a full demo of all the steps in this tutorial. Open the video in a new tab to avoid leaving Bitbucket.* + +--- + +## Edit a file + +You’ll start by editing this README file to learn how to edit a file in Bitbucket. + +1. Click **Source** on the left side. +2. Click the README.md link from the list of files. +3. Click the **Edit** button. +4. Delete the following text: *Delete this line to make a change to the README from Bitbucket.* +5. After making your change, click **Commit** and then **Commit** again in the dialog. The commit page will open and you’ll see the change you just made. +6. Go back to the **Source** page. + +--- + +## Create a file + +Next, you’ll add a new file to this repository. + +1. Click the **New file** button at the top of the **Source** page. +2. Give the file a filename of **contributors.txt**. +3. Enter your name in the empty file space. +4. Click **Commit** and then **Commit** again in the dialog. +5. Go back to the **Source** page. + +Before you move on, go ahead and explore the repository. You've already seen the **Source** page, but check out the **Commits**, **Branches**, and **Settings** pages. + +--- + +## Clone a repository + +Use these steps to clone from SourceTree, our client for using the repository command-line free. Cloning allows you to work on your files locally. If you don't yet have SourceTree, [download and install first](https://www.sourcetreeapp.com/). If you prefer to clone from the command line, see [Clone a repository](https://confluence.atlassian.com/x/4whODQ). + +1. You’ll see the clone button under the **Source** heading. Click that button. +2. Now click **Check out in SourceTree**. You may need to create a SourceTree account or log in. +3. When you see the **Clone New** dialog in SourceTree, update the destination path and name if you’d like to and then click **Clone**. +4. Open the directory you just created to see your repository’s files. + +Now that you're more familiar with your Bitbucket repository, go ahead and add a new file locally. You can [push your change back to Bitbucket with SourceTree](https://confluence.atlassian.com/x/iqyBMg), or you can [add, commit,](https://confluence.atlassian.com/x/8QhODQ) and [push from the command line](https://confluence.atlassian.com/x/NQ0zDQ). \ No newline at end of file diff --git a/addon_config.mk b/addon_config.mk new file mode 100644 index 0000000..c0f1947 --- /dev/null +++ b/addon_config.mk @@ -0,0 +1,74 @@ +# All variables and this file are optional, if they are not present the PG and the +# makefiles will try to parse the correct values from the file system. +# +# Variables that specify exclusions can use % as a wildcard to specify that anything in +# that position will match. A partial path can also be specified to, for example, exclude +# a whole folder from the parsed paths from the file system +# +# Variables can be specified using = or += +# = will clear the contents of that variable both specified from the file or the ones parsed +# from the file system +# += will add the values to the previous ones in the file or the ones parsed from the file +# system +# +# The PG can be used to detect errors in this file, just create a new project with this addon +# and the PG will write to the console the kind of error and in which line it is + +meta: + ADDON_NAME = ofxDabFlock + ADDON_DESCRIPTION = Flocking Simulation + ADDON_AUTHOR = Daniel Bisig / ICST + ADDON_TAGS = "flocking" "simulation" + +common: + # dependencies with other addons, a list of them separated by spaces + # or use += in several lines + # ADDON_DEPENDENCIES = + + # include search paths, this will be usually parsed from the file system + # but if the addon or addon libraries need special search paths they can be + # specified here separated by spaces or one per line using += + # ADDON_INCLUDES = + + # any special flag that should be passed to the compiler when using this + # addon + # ADDON_CFLAGS = + + # any special flag that should be passed to the linker when using this + # addon, also used for system libraries with -lname + # ADDON_LDFLAGS = + + # linux only, any library that should be included in the project using + # pkg-config + # ADDON_PKG_CONFIG_LIBRARIES = + + # osx/iOS only, any framework that should be included in the project + # ADDON_FRAMEWORKS = + + # source files, these will be usually parsed from the file system looking + # in the src folders in libs and the root of the addon. if your addon needs + # to include files in different places or a different set of files per platform + # they can be specified here + # ADDON_SOURCES = + + # some addons need resources to be copied to the bin/data folder of the project + # specify here any files that need to be copied, you can use wildcards like * and ? + # ADDON_DATA = + + # when parsing the file system looking for libraries exclude this for all or + # a specific platform + # ADDON_LIBS_EXCLUDE = + + ADDON_DEPENDENCIES = + ADDON_DEPENDENCIES += "ofxDabBase" + ADDON_DEPENDENCIES += "ofxDabEvent" + ADDON_DEPENDENCIES += "ofxDabMath" + ADDON_DEPENDENCIES += "ofxDabGeom" + ADDON_DEPENDENCIES += "ofxDabOsc" + ADDON_DEPENDENCIES += "ofxDabSpace" + ADDON_DEPENDENCIES += "ofxAssimpModelLoader" + ADDON_DEPENDENCIES += "ofxJSON" + + + ADDON_INCLUDES = + ADDON_INCLUDES += ../../libs/eigen3/include/ diff --git a/src/dab_flock_acceleration_behavior.cpp b/src/dab_flock_acceleration_behavior.cpp new file mode 100644 index 0000000..1b6b290 --- /dev/null +++ b/src/dab_flock_acceleration_behavior.cpp @@ -0,0 +1,110 @@ +/** \file dab_flock_acceleration_behavior.cpp + */ + +#include "dab_flock_acceleration_behavior.h" +#include "dab_flock_parameter.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +AccelerationBehavior::AccelerationBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "AccelerationBehavior"; +} + +AccelerationBehavior::AccelerationBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "AccelerationBehavior"; + + if( mInputParameters.size() < 3 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size() ) + " input parameters supplied, " + std::to_string(3) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__); + if( mInputParameters[1]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[1]->name() + " dim " + std::to_string(mInputParameters[1]->dim()) + " must match output parameter " + mOutputParameters[1]->name() + " dim " + std::to_string(mOutputParameters[1]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[2]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[2]->name() + " dim " + std::to_string(mInputParameters[2]->dim()) + " must match output parameter " + mOutputParameters[1]->name() + " dim " + std::to_string(mOutputParameters[1]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + + // input parameters + mMassPar = mInputParameters[0]; + mVelocityPar = mInputParameters[1]; + mForcePar = mInputParameters[2]; + + // output parameters + mAcceleration = mOutputParameters[0]; + + // create internal parameters + mMaxLinearAccelerationPar = createInternalParameter("maxLinearAcceleration", mOutputParameters[0]->dim(), 0.5); + mMaxAngularAccelerationPar = createInternalParameter("maxAngularAcceleration", mOutputParameters[0]->dim(), 0.5); + + // remaining stuff + unsigned int dim = mForcePar->dim(); + mPrefAccel.resize(dim, 1); + mLinearAccel.resize(dim, 1); + mAngularAccel.resize(dim, 1); +} + +AccelerationBehavior::~AccelerationBehavior() +{} + +Behavior* +AccelerationBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new AccelerationBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new AccelerationBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +AccelerationBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new AccelerationBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +AccelerationBehavior::act() +{ + //std::cout << "AccelerationBehavior begin: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + + if(mActivePar->value() <= 0.0) return; + + float& mass = mMassPar->value(); + Eigen::VectorXf& velocity = mVelocityPar->values(); + Eigen::VectorXf& force = mForcePar->values(); + float& maxLinearAcceleration = mMaxLinearAccelerationPar->value(); + float& maxAngularAcceleration = mMaxAngularAccelerationPar->value(); + Eigen::VectorXf& acceleration = mAcceleration->backupValues(); + + Eigen::VectorXf& prefAccel = mPrefAccel; + Eigen::VectorXf& linearAccel = mLinearAccel; + Eigen::VectorXf& angularAccel = mAngularAccel; + + prefAccel = force / mass; + linearAccel = velocity; + linearAccel.normalize(); + + float dotProd = prefAccel.dot(linearAccel); + linearAccel *= dotProd; + angularAccel = prefAccel - linearAccel; + + linearAccel.cwiseMax(maxLinearAcceleration); + angularAccel.cwiseMax(maxAngularAcceleration); + + acceleration = (linearAccel + angularAccel); + + //std::cout << "AccelerationBehavior end: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + + //assert(std::isnan(acceleration[0]) == false && "isNan"); +} \ No newline at end of file diff --git a/src/dab_flock_acceleration_behavior.h b/src/dab_flock_acceleration_behavior.h new file mode 100644 index 0000000..fbf63e2 --- /dev/null +++ b/src/dab_flock_acceleration_behavior.h @@ -0,0 +1,101 @@ +/** \file dab_flock_acceleration_behavior.h + * \class dab::flock::AccelerationBehavior acceleration behavior + * \brief acceleration behavior + * + * Behavior for calculating an Agent 's acceleration from a force acting on it.\n + * can limit the resulting acceleration by clamping its linear and angular components.\n + * \n + * Input Parameter:\n + * type: mass dim: 1D neighbors: ignore\n + * type: velocity dim: nD neighbors: ignore\n + * type: force dim: nD neighbors: ignore\n + * \n + * Output Parameter:\n + * type: acceleration dim: nD write: replace\n + * \n + * Internal Parameter:\n + * name: xxx_maxLinearAcceleration dim: 1D defaultValue: 0.5\n + * name: xxx_maxAngularAcceleration dim: 1D defaultValue: 0.5\n + * name: xxx_active dim: 1D defaultValue: 1.0\n + * \n + * Created by Daniel Bisig on 4/17/07. + * Ported to OpenFrameworks by Daniel Bisig on 01/10/2017 + */ + +#ifndef _dab_flock_acceleration_behavior_h_ +#define _dab_flock_acceleration_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class AccelerationBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + AccelerationBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + AccelerationBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~AccelerationBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior action + */ + virtual void act(); + +protected: + Parameter* mMassPar; /// \brief mass parameter (input) + Parameter* mVelocityPar; /// \brief velocity parameter (input) + Parameter* mForcePar; /// \brief force parameter (input) + Parameter* mAcceleration; /// \brief acceleration parameter (output) + Parameter* mMaxLinearAccelerationPar; /// \brief maximum linear acceleration parameter (internal) + Parameter* mMaxAngularAccelerationPar; /// \brief maximum angular acceleration parameter (internal) + + Eigen::VectorXf mPrefAccel; /// \brief preferred acceleration + Eigen::VectorXf mLinearAccel; /// \brief linear acceleration + Eigen::VectorXf mAngularAccel; /// \brief angular acceleration +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_add_agents_event.cpp b/src/dab_flock_add_agents_event.cpp new file mode 100644 index 0000000..17d0035 --- /dev/null +++ b/src/dab_flock_add_agents_event.cpp @@ -0,0 +1,70 @@ +/** \file dab_flock_add_agents_event.cpp + */ + +#include "dab_flock_add_agents_event.h" + +using namespace dab; +using namespace dab::flock; + +AddAgentsEvent::AddAgentsEvent(const std::string& pSwarmName, unsigned int pAgentCount) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mAgentCount(pAgentCount) +{} + +AddAgentsEvent::AddAgentsEvent(double pTime, const std::string& pSwarmName, unsigned int pAgentCount) +: event::Event(pTime, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mAgentCount(pAgentCount) +{} + +AddAgentsEvent::AddAgentsEvent(const AddAgentsEvent& pEvent) +: event::Event( pEvent ) +, mSwarmName( pEvent.mSwarmName ) +, mAgentCount( pEvent.mAgentCount ) +{} + +AddAgentsEvent::AddAgentsEvent(double pTime, const AddAgentsEvent& pEvent) +: event::Event( pTime, pEvent ) +, mSwarmName( pEvent.mSwarmName ) +, mAgentCount( pEvent.mAgentCount ) +{} + +AddAgentsEvent::~AddAgentsEvent() +{} + +event::Event* +AddAgentsEvent::copy() const +{ + return new AddAgentsEvent( *this ); +} + +event::Event* +AddAgentsEvent::copy( double pTime ) const +{ + return new AddAgentsEvent( pTime, *this ); +} + +void +AddAgentsEvent::execute() throw (Exception) +{ + //std::cout << "AddAgentsEvent::execute() begin\n"; + + mStarted = true; + mFinished = false; + + try + { + Swarm* swarm = Simulation::get().swarm(mSwarmName); + swarm->addAgents(mAgentCount); + } + catch(Exception& e) + { + Simulation::get().exceptionReport( e ); + } + + mStarted = false; + mFinished = true; + + //std::cout << "AddAgentsEvent::execute() end\n"; +} \ No newline at end of file diff --git a/src/dab_flock_add_agents_event.h b/src/dab_flock_add_agents_event.h new file mode 100644 index 0000000..d387532 --- /dev/null +++ b/src/dab_flock_add_agents_event.h @@ -0,0 +1,42 @@ +/** \file dab_flock_add_agents_event.h + * + * Created by Daniel Bisig on 1/28/09. + * Ported to OpenFrameworks by Daniel Bisig on 13/10/2017. + */ + +#ifndef _dab_flock_add_agents_event_h_ +#define _dab_flock_add_agents_event_h_ + +#include "dab_flock_simulation.h" +#include "dab_flock_swarm.h" +#include "dab_event.h" + +namespace dab +{ + +namespace flock +{ + +class AddAgentsEvent : public event::Event +{ +public: + AddAgentsEvent(const std::string& pSwarmName, unsigned int pAgentCount); + AddAgentsEvent(double pTime, const std::string& pSwarmName, unsigned int pAgentCount); + AddAgentsEvent(const AddAgentsEvent& pEvent); + AddAgentsEvent(double pTime, const AddAgentsEvent& pEvent); + virtual ~AddAgentsEvent(); + + event::Event* copy() const; + event::Event* copy( double pTime ) const; + void execute() throw (Exception); + +protected: + std::string mSwarmName; + unsigned int mAgentCount; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_add_space_event.cpp b/src/dab_flock_add_space_event.cpp new file mode 100644 index 0000000..be869e3 --- /dev/null +++ b/src/dab_flock_add_space_event.cpp @@ -0,0 +1,201 @@ +/** \file dab_flock_add_space_event.cpp + */ + +#include "dab_flock_add_space_event.h" +#include "dab_space.h" +#include "dab_space_manager.h" +#include "dab_space_alg_permanent_neighbors.h" +#include "dab_space_alg_ntree.h" +#include "dab_space_alg_kdtree.h" +#include "dab_space_alg_rtree.h" +#include "dab_space_alg_ann.h" +#include "dab_space_alg_grid.h" + +using namespace dab; +using namespace dab::flock; + +AddSpaceEvent::AddSpaceEvent() +: event::Event() +{} + +AddSpaceEvent::AddSpaceEvent(const std::string& pSpaceName, space::SpaceAlgType pSpaceAlgType, unsigned int pSpaceDim) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSpaceName(pSpaceName) +, mSpaceAlgType(pSpaceAlgType) +, mSpaceDim(pSpaceDim) +{} + +AddSpaceEvent::AddSpaceEvent(const std::string& pSpaceName, space::SpaceAlgType pSpaceAlgType, const Eigen::VectorXf& pMinPos, const Eigen::VectorXf& pMaxPos) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSpaceName(pSpaceName) +, mSpaceAlgType(pSpaceAlgType) +, mSpaceDim(pMinPos.rows()) +, mMinPos(pMinPos) +, mMaxPos(pMaxPos) +{} + +AddSpaceEvent::AddSpaceEvent(const std::string& pSpaceName, space::SpaceAlgType pSpaceAlgType, unsigned int pGridValueDim, const dab::Array& pGridSubdivisionCount, const Eigen::VectorXf& pMinPos, const Eigen::VectorXf& pMaxPos, space::GridAlg::GridNeighborMode pGridNeighborMode, space::GridAlg::GridUpdateMode pGridUpdateMode) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSpaceName(pSpaceName) +, mSpaceAlgType(pSpaceAlgType) +, mSpaceDim(pMinPos.rows()) +, mMinPos(pMinPos) +, mMaxPos(pMaxPos) +, mGridValueDim(pGridValueDim) +, mGridSubdivisionCount(pGridSubdivisionCount) +, mGridNeighborMode(pGridNeighborMode) +, mGridUpdateMode(pGridUpdateMode) +{} + +AddSpaceEvent::AddSpaceEvent(const std::string& pSpaceName, space::SpaceAlgType pSpaceAlgType, const std::string& pGridName, space::GridAlg::GridNeighborMode pGridNeighborMode, space::GridAlg::GridUpdateMode pGridUpdateMode) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSpaceName(pSpaceName) +, mSpaceAlgType(pSpaceAlgType) +, mGridName(pGridName) +, mGridNeighborMode(pGridNeighborMode) +, mGridUpdateMode(pGridUpdateMode) +{} + +AddSpaceEvent::AddSpaceEvent(double pTime, const std::string& pSpaceName, space::SpaceAlgType pSpaceAlgType, unsigned int pSpaceDim) +: event::Event(pTime, -1.0, event::RelativeTime) +, mSpaceName(pSpaceName) +, mSpaceAlgType(pSpaceAlgType) +, mSpaceDim(pSpaceDim) +{} + +AddSpaceEvent::AddSpaceEvent(double pTime, const std::string& pSpaceName, space::SpaceAlgType pSpaceAlgType, const Eigen::VectorXf& pMinPos, const Eigen::VectorXf& pMaxPos) +: event::Event(pTime, -1.0, event::RelativeTime) +, mSpaceName(pSpaceName) +, mSpaceAlgType(pSpaceAlgType) +, mSpaceDim(pMinPos.rows()) +, mMinPos(pMinPos) +, mMaxPos(pMaxPos) +{} + +AddSpaceEvent::AddSpaceEvent(double pTime, const std::string& pSpaceName, space::SpaceAlgType pSpaceAlgType, unsigned int pGridValueDim, const dab::Array& pGridSubdivisionCount, const Eigen::VectorXf& pMinPos, const Eigen::VectorXf& pMaxPos, space::GridAlg::GridNeighborMode pGridNeighborMode, space::GridAlg::GridUpdateMode pGridUpdateMode) +: event::Event(pTime, -1.0, event::RelativeTime) +, mSpaceName(pSpaceName) +, mSpaceAlgType(pSpaceAlgType) +, mSpaceDim(pMinPos.rows()) +, mMinPos(pMinPos) +, mMaxPos(pMaxPos) +, mGridValueDim(pGridValueDim) +, mGridSubdivisionCount(pGridSubdivisionCount) +, mGridNeighborMode(pGridNeighborMode) +, mGridUpdateMode(pGridUpdateMode) +{} + +AddSpaceEvent::AddSpaceEvent(double pTime, const std::string& pSpaceName, space::SpaceAlgType pSpaceAlgType, const std::string& pGridName, space::GridAlg::GridNeighborMode pGridNeighborMode, space::GridAlg::GridUpdateMode pGridUpdateMode) +: event::Event(pTime, -1.0, event::RelativeTime) +, mSpaceName(pSpaceName) +, mSpaceAlgType(pSpaceAlgType) +, mGridName(pGridName) +, mGridNeighborMode(pGridNeighborMode) +, mGridUpdateMode(pGridUpdateMode) +{} + +AddSpaceEvent::AddSpaceEvent( const AddSpaceEvent& pEvent ) +: event::Event( pEvent ) +, mSpaceName( pEvent.mSpaceName ) +, mSpaceAlgType( pEvent.mSpaceAlgType ) +, mSpaceDim( pEvent.mSpaceDim ) +, mMinPos( pEvent.mMinPos ) +, mMaxPos( pEvent.mMaxPos ) +, mGridName( pEvent.mGridName ) +, mGridValueDim( pEvent.mGridValueDim ) +, mGridSubdivisionCount( pEvent.mGridSubdivisionCount ) +, mGridNeighborMode( pEvent.mGridNeighborMode ) +, mGridUpdateMode( pEvent.mGridUpdateMode ) +{} + +AddSpaceEvent::AddSpaceEvent( double pTime, const AddSpaceEvent& pEvent ) +: event::Event( pTime, pEvent ) +, mSpaceName( pEvent.mSpaceName ) +, mSpaceAlgType( pEvent.mSpaceAlgType ) +, mSpaceDim( pEvent.mSpaceDim ) +, mMinPos( pEvent.mMinPos ) +, mMaxPos( pEvent.mMaxPos ) +, mGridName( pEvent.mGridName ) +, mGridValueDim( pEvent.mGridValueDim ) +, mGridSubdivisionCount( pEvent.mGridSubdivisionCount ) +, mGridNeighborMode( pEvent.mGridNeighborMode ) +, mGridUpdateMode( pEvent.mGridUpdateMode ){} + +AddSpaceEvent::~AddSpaceEvent() +{} + +event::Event* +AddSpaceEvent::copy() const +{ + return new AddSpaceEvent( *this ); +} + +event::Event* +AddSpaceEvent::copy( double pTime ) const +{ + return new AddSpaceEvent( pTime, *this ); +} + +void +AddSpaceEvent::execute() throw (Exception) +{ + mStarted = true; + mFinished = false; + + try + { + space::SpaceAlg* spaceAlg = nullptr; + + if( mSpaceAlgType == space::PermanentNeighborsAlgType ) + { + if( mMinPos == mMaxPos ) spaceAlg = new space::PermanentNeighborsAlg( mSpaceDim ); + else spaceAlg = new space::PermanentNeighborsAlg( mMinPos, mMaxPos ); + } + else if( mSpaceAlgType == space::NTreeAlgType ) + { + if( mMinPos == mMaxPos ) spaceAlg = new space::NTreeAlg( mSpaceDim ); + else spaceAlg = new space::NTreeAlg( mMinPos, mMaxPos ); + } + else if( mSpaceAlgType == space::KDTreeAlgType ) + { + if( mMinPos == mMaxPos ) spaceAlg = new space::KDTreeAlg( mSpaceDim ); + else spaceAlg = new space::KDTreeAlg( mMinPos, mMaxPos ); + } + else if( mSpaceAlgType == space::ANNAlgType ) + { + if( mMinPos == mMaxPos ) spaceAlg = new space::ANNAlg( mSpaceDim ); + else spaceAlg = new space::ANNAlg( mMinPos, mMaxPos ); + } + else if( mSpaceAlgType == space::RTreeAlgType ) + { + spaceAlg = new space::RTreeAlg( mMinPos, mMaxPos ); + + static_cast( spaceAlg )->setClosestPointType(space::ClosestPointShape); + } + else if( mSpaceAlgType == space::GridAlgType ) + { + if(mGridName.empty()) spaceAlg = new space::GridAlg( mGridValueDim, mGridSubdivisionCount, mMinPos, mMaxPos, mGridNeighborMode, mGridUpdateMode ); + else + { + // /* + // // TODO + // Simulation::get().space().spaceGrid( mSpaceGridName ) + // Simulation::get().space()(new space::GridSpace(mSpaceName, Simulation::get().space().spaceGrid( mSpaceGridName ), mNeighborMode, mUpdateMode)); + // */ + } + } + + if( spaceAlg == nullptr ) throw Exception( "FLOCK ERROR: failed to create algorithm for space " + mSpaceName, __FILE__, __FUNCTION__, __LINE__ ); + else + { + Simulation::get().space().addSpace( std::shared_ptr< space::Space>(new space::Space( mSpaceName, spaceAlg ))); + } + } + catch(Exception& e) + { + Simulation::get().exceptionReport( e ); + } + + mStarted = false; + mFinished = true; +} \ No newline at end of file diff --git a/src/dab_flock_add_space_event.h b/src/dab_flock_add_space_event.h new file mode 100644 index 0000000..8777df3 --- /dev/null +++ b/src/dab_flock_add_space_event.h @@ -0,0 +1,61 @@ +/** \file dab_flock_add_space_event.h + * + * Created by Daniel Bisig on 02/09/09. + * Ported to OpenFrameworks by Daniel Bisig on 24/10/2017. + */ + +#ifndef _dab_flock_add_space_event_h_ +#define _dab_flock_add_space_event_h_ + +#include "dab_flock_simulation.h" +#include "dab_flock_swarm.h" +#include "dab_space_types.h" +#include "dab_space_alg.h" +#include "dab_space_alg_grid.h" +#include "dab_event.h" + +namespace dab +{ + +namespace flock +{ + +class AddSpaceEvent : public event::Event +{ +public: + AddSpaceEvent(const std::string& pSpaceName, space::SpaceAlgType pSpaceAlgType, unsigned int pSpaceDim); + AddSpaceEvent(const std::string& pSpaceName, space::SpaceAlgType pSpaceAlgType, const Eigen::VectorXf& pMinPos, const Eigen::VectorXf& pMaxPos); + AddSpaceEvent(const std::string& pSpaceName, space::SpaceAlgType pSpaceAlgType, unsigned int pGridValueDim, const dab::Array& pGridSubdivisionCount, const Eigen::VectorXf& pMinPos, const Eigen::VectorXf& pMaxPos, space::GridAlg::GridNeighborMode pGridNeighborMode, space::GridAlg::GridUpdateMode pGridUpdateMode); + AddSpaceEvent(const std::string& pSpaceName, space::SpaceAlgType pSpaceAlgType, const std::string& pGridName, space::GridAlg::GridNeighborMode pGridNeighborMode, space::GridAlg::GridUpdateMode pGridUpdateMode); + AddSpaceEvent(double pTime, const std::string& pSpaceName, space::SpaceAlgType pSpaceAlgType, unsigned int pSpaceDim); + AddSpaceEvent(double pTime, const std::string& pSpaceName, space::SpaceAlgType pSpaceAlgType, const Eigen::VectorXf& pMinPos, const Eigen::VectorXf& pMaxPos); + AddSpaceEvent(double pTime, const std::string& pSpaceName, space::SpaceAlgType pSpaceAlgType, unsigned int pGridValueDim, const dab::Array& pGridSubdivisionCount, const Eigen::VectorXf& pMinPos, const Eigen::VectorXf& pMaxPos, space::GridAlg::GridNeighborMode pGridNeighborMode, space::GridAlg::GridUpdateMode pGridUpdateMode); + AddSpaceEvent(double pTime, const std::string& pSpaceName, space::SpaceAlgType pSpaceAlgType, const std::string& pGridName, space::GridAlg::GridNeighborMode pGridNeighborMode, space::GridAlg::GridUpdateMode pGridUpdateMode); + AddSpaceEvent( const AddSpaceEvent& pEvent ); + AddSpaceEvent( double pTime, const AddSpaceEvent& pEvent ); + virtual ~AddSpaceEvent(); + + event::Event* copy() const; + event::Event* copy( double pTime ) const; + void execute() throw (Exception); + +protected: + AddSpaceEvent(); + + std::string mSpaceName; + space::SpaceAlgType mSpaceAlgType; + unsigned int mSpaceDim; + Eigen::VectorXf mMinPos; + Eigen::VectorXf mMaxPos; + unsigned int mGridValueDim; + dab::Array mGridSubdivisionCount; + space::GridAlg::GridNeighborMode mGridNeighborMode; + space::GridAlg::GridUpdateMode mGridUpdateMode; + std::string mGridName; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_agent.cpp b/src/dab_flock_agent.cpp new file mode 100644 index 0000000..8eb9ed6 --- /dev/null +++ b/src/dab_flock_agent.cpp @@ -0,0 +1,702 @@ +/** \file dab_flock_agent.cpp + */ + +#include "dab_flock_agent.h" +#include "dab_flock_simulation.h" +#include "dab_space_neighbor_group_alg.h" + +using namespace dab; +using namespace dab::flock; + +const std::string Agent::sClassName = "Agent"; +unsigned int Agent::sInstanceCount = 0; + +Agent::Agent() +: mIndex( sInstanceCount++ ) +{ + mName = sClassName + std::to_string(mIndex);"\n"; + + addParameter( new Parameter( this, "active", Eigen::Matrix(1.0) ) ); +} + +Agent::Agent(const std::string& pName) +: mIndex( sInstanceCount++ ) +, mName(pName) +{ + addParameter( new Parameter( this, "active", Eigen::Matrix(1.0) ) ); +} + +Agent::Agent(const Agent& pAgent) +: mIndex( sInstanceCount++ ) +{ + mName = sClassName + std::to_string(mIndex); + + // copy parameters + unsigned int parCount = pAgent.parameterCount(); + for(unsigned int i=0; icreate( _behavior->name(), this ) ); + } +} + +Agent::Agent(const std::string& pName, const Agent& pAgent) +: mIndex( sInstanceCount++ ) +, mName(pName) +{ + // copy parameters + unsigned int parCount = pAgent.parameterCount(); + for(unsigned int i=0; icreate( _behavior->name(), this ) ); + } +} + +Agent::~Agent() +{} + +unsigned int +Agent::index() const +{ + return mIndex; +} + +const std::string& +Agent::name() const +{ + return mName; +} + +unsigned int +Agent::parameterCount() const +{ + return mParameterList.parameterCount(); +} + +bool +Agent::checkParameter(const std::string& pParameterName) const +{ + return mParameterList.contains(pParameterName); +} + +unsigned int +Agent::parameterIndex(const std::string& pParameterName) const throw (Exception) +{ + try + { + return mParameterList.parameterIndex(pParameterName); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed get parameter index for parameter name " + pParameterName, __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +Parameter* +Agent::parameter(unsigned int pParameterIndex) throw (Exception) +{ + try + { + return mParameterList.parameter(pParameterIndex); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to get parameter for parameter index " + std::to_string(pParameterIndex), __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +const Parameter* +Agent::parameter(unsigned int pParameterIndex) const throw (Exception) +{ + try + { + return mParameterList.parameter(pParameterIndex); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to get parameter for parameter index " + std::to_string(pParameterIndex), __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +Parameter* +Agent::parameter(const std::string& pParameterName) throw (Exception) +{ + try + { + return mParameterList.parameter(pParameterName); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to get parameter for parameter name " + pParameterName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +const Parameter* +Agent::parameter(const std::string& pParameterName) const throw (Exception) +{ + try + { + return mParameterList.parameter(pParameterName); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to get parameter for parameter name " + pParameterName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::addParameter(Parameter* pParameter) throw (Exception) +{ + try + { + mParameterList.addParameter(pParameter); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to add parameter " + pParameter->name(), __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::addParameter(const std::string& pName, unsigned int pDim) throw (Exception) +{ + try + { + addParameter( new Parameter(this, pName, pDim) ); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to add parameter " + pName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::addParameter(const std::string& pName, unsigned int pDim, float pValue) throw (Exception) +{ + try + { + Eigen::VectorXf parValue(pDim); + parValue.setConstant(pValue); + addParameter( new Parameter(this, pName, parValue ) ); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to add parameter " + pName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::addParameter(const std::string& pName, const std::initializer_list& pValues) throw (Exception) +{ + try + { + addParameter( new Parameter(this, pName, pValues) ); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to add parameter " + pName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::addParameter(const std::string& pName, const Eigen::VectorXf& pValues) throw (Exception) +{ + try + { + addParameter( new Parameter(this, pName, pValues) ); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to add parameter " + pName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::removeParameter(const std::string& pParameterName) throw (Exception) +{ + try + { + mParameterList.removeParameter( pParameterName ); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to remove parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::setParameterValue(const std::string& pParameterName, float pParameterValue) throw (Exception) +{ + try + { + parameter(pParameterName)->set(pParameterValue); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to set value for parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} +void +Agent::setParameterValues(const std::string& pParameterName, const std::initializer_list& pParameterValues) throw (Exception) +{ + try + { + parameter(pParameterName)->set(pParameterValues); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to set value for parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::setParameterValues(const std::string& pParameterName, const Eigen::VectorXf& pParameterValues) throw (Exception) +{ + try + { + parameter(pParameterName)->set(pParameterValues); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to set value for parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::set(const std::string& pParameterName, float pParameterValue) throw (Exception) +{ + try + { + parameter(pParameterName)->set(pParameterValue); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to set value for parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::set(const std::string& pParameterName, const std::initializer_list& pParameterValues) throw (Exception) +{ + try + { + parameter(pParameterName)->set(pParameterValues); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to set value for parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::set(const std::string& pParameterName, const Eigen::VectorXf& pParameterValues) throw (Exception) +{ + try + { + parameter(pParameterName)->set(pParameterValues); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to set value for parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::randomize(const std::string& pParameterName, float pMinParameterValue, float pMaxParameterValue) throw (Exception) +{ + try + { + parameter(pParameterName)->randomize(pMinParameterValue, pMaxParameterValue); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to randomize value for parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::randomize(const std::string& pParameterName, const std::initializer_list& pMinParameterValues, const std::initializer_list& pMaxParameterValues) throw (Exception) +{ + try + { + parameter(pParameterName)->randomize(pMinParameterValues, pMaxParameterValues); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to randomize value for parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::randomize(const std::string& pParameterName, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues) throw (Exception) +{ + try + { + parameter(pParameterName)->randomize(pMinParameterValues, pMaxParameterValues); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to randomize value for parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::assignNeighbors(const std::string& pParameterName, const std::string& pSpaceName, bool pVisible, space::NeighborGroupAlg* pNeighborGroupAlg ) throw (Exception) +{ + try + { + std::shared_ptr space = space::SpaceManager::get().space(pSpaceName); + Parameter* parameter = mParameterList.parameter(pParameterName); + + if( space->checkObject( parameter ) == true ) space->setObject( parameter, pVisible, pNeighborGroupAlg ); + else space->addObject( parameter, pVisible, pNeighborGroupAlg); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to assign neighbors for parameter " + pParameterName + " and space " + pSpaceName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::assignNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible = false ) throw (Exception) +{ + try + { + std::shared_ptr space = space::SpaceManager::get().space(pSpaceName); + Parameter* parameter = mParameterList.parameter(pParameterName); + + if( space->checkObject( parameter ) == true ) space->setObject( parameter, pVisible, nullptr ); + else space->addObject( parameter, pVisible, nullptr); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to assign neighbors for parameter " + pParameterName + " and space " + pSpaceName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Agent::assignNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible, float pNeighborRadius, int pMaxNeighborCount, bool pReplaceNeighborMode ) +{ + try + { + std::shared_ptr space = space::SpaceManager::get().space(pSpaceName ); + Parameter* parameter = mParameterList.parameter(pParameterName ); + + if( space->checkObject( parameter ) == true ) space->setObject( parameter, pVisible, new space::NeighborGroupAlg( pNeighborRadius, pMaxNeighborCount, pReplaceNeighborMode ) ); + else space->addObject( parameter, pVisible, new space::NeighborGroupAlg( pNeighborRadius, pMaxNeighborCount, pReplaceNeighborMode ) ); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to assign neighbors for parameter " + pParameterName + " and space " + pSpaceName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +unsigned int +Agent::behaviorCount() const +{ + return mBehaviorList.behaviorCount(); +} + +bool +Agent::checkBehavior(const std::string& pBehaviorName) const +{ + return mBehaviorList.contains(pBehaviorName); +} + +Behavior* +Agent::behavior(unsigned int pBehaviorIndex) throw (Exception) +{ + try + { + return mBehaviorList.behavior(pBehaviorIndex); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to get behaviour for behaviour index " + std::to_string(pBehaviorIndex), __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +const Behavior* +Agent::behavior(unsigned int pBehaviorIndex) const throw (Exception) +{ + try + { + return mBehaviorList.behavior(pBehaviorIndex); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to get behaviour for behaviour index " + std::to_string(pBehaviorIndex), __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +Behavior* +Agent::behavior(const std::string& pBehaviorName) throw (Exception) +{ + try + { + return mBehaviorList.behavior(pBehaviorName); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to get behaviour for behaviour name " + pBehaviorName, __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +const Behavior* +Agent::behavior(const std::string& pBehaviorName) const throw (Exception) +{ + try + { + return mBehaviorList.behavior(pBehaviorName); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to get behaviour for behaviour name " + pBehaviorName, __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +Agent::addBehavior(Behavior* pBehavior) throw (Exception) +{ + try + { + mBehaviorList.addBehavior(pBehavior); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to add behaviour " + pBehavior->name(), __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +Agent::addBehavior(const std::string& pBehaviorName, const Behavior& pBehavior) throw (Exception) +{ + Behavior* _behavior = nullptr; + + try + { + _behavior = pBehavior.create(pBehaviorName, this); + mBehaviorList.addBehavior(_behavior); + } + catch(Exception& e) + { + if(_behavior != nullptr) delete _behavior; + + e += Exception("FLOCK ERROR: failed to add behaviour " + pBehaviorName, __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +Agent::addBehavior(const std::string& pBehaviorName, unsigned int pBehaviorPosition, const Behavior& pBehavior) throw (Exception) +{ + Behavior* _behavior = nullptr; + + try + { + _behavior = pBehavior.create(pBehaviorName, this); + mBehaviorList.addBehavior(_behavior, pBehaviorPosition); + } + catch(Exception& e) + { + if(_behavior != nullptr) delete _behavior; + + e += Exception("FLOCK ERROR: failed to add behaviour " + pBehaviorName, __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +Agent::addBehavior(const std::string& pBehaviorName, const std::string& pSuccessorBehaviorName, const Behavior& pBehavior) throw (Exception) +{ + Behavior* _behavior = nullptr; + + try + { + int pSuccessorBehaviorPosition = mBehaviorList.behaviorIndex(pSuccessorBehaviorName); + _behavior = pBehavior.create(pBehaviorName, this); + mBehaviorList.addBehavior(_behavior, pSuccessorBehaviorPosition); + } + catch (Exception& e) + { + if(_behavior != nullptr) delete _behavior; + + e += Exception("FLOCK ERROR: failed to add behaviour " + pBehaviorName + " in front of behaviour " + pSuccessorBehaviorName, __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +Agent::moveBehavior(const std::string& pBehaviorName, unsigned int pBehaviorPosition) throw (Exception) +{ + try + { + int oldBehaviorPosition = mBehaviorList.behaviorIndex(pBehaviorName); + mBehaviorList.moveBehavior(oldBehaviorPosition, pBehaviorPosition); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to move behaviour " + pBehaviorName + " to position " + std::to_string(pBehaviorPosition), __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +Agent::moveBehavior(const std::string& pBehaviorName, const std::string& pSuccessorBehaviorName) throw (Exception) +{ + try + { + int oldBehaviorPosition = mBehaviorList.behaviorIndex(pBehaviorName); + int newBehaviorPosition = mBehaviorList.behaviorIndex(pSuccessorBehaviorName); + + //std::cout << "oldBehaviorPosition " << oldBehaviorPosition << " newBehaviorPosition " << newBehaviorPosition << "\n"; + + if( oldBehaviorPosition == newBehaviorPosition ) return; + else if( oldBehaviorPosition < newBehaviorPosition ) mBehaviorList.moveBehavior(oldBehaviorPosition, newBehaviorPosition - 1 ); + else mBehaviorList.moveBehavior(oldBehaviorPosition, newBehaviorPosition ); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to move behaviour " + pBehaviorName + " in front of behaviour " + pSuccessorBehaviorName, __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +Agent::removeBehavior(const std::string& pBehaviorName) throw (Exception) +{ + try + { + mBehaviorList.removeBehavior(pBehaviorName); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to remove behaviour " + pBehaviorName, __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +Agent::act() +{ + //std::cout << "agent " << mName.toStdString() << " act\n"; + + if( mParameterList.parameter(0)->value() == 0.0 ) return; // check if agent is active + + mBehaviorList.act(); +} + +void +Agent::flush() +{ + mParameterList.flush(); +} + +Agent::operator std::string() const +{ + return info(0); +} + +std::string +Agent::info(int pPropagationLevel) const +{ + std::stringstream ss; + + ss << mName << "\n"; + + if(pPropagationLevel == 0) + { + ss << "parameter Count " << std::to_string(mParameterList.parameterCount()) << "\n"; + } + else if(pPropagationLevel == 1) + { + ss << "parameters:\n"; + int parCount = mParameterList.parameterCount(); + for(int pI=0; pIname() << " : " << par->values().transpose() << "\n"; + } + } + else + { + ss << "ParameterList\n"; + ss << mParameterList.info(pPropagationLevel - 1) << "\n"; + } + + if(pPropagationLevel == 0) + { + ss << "behavior Count " << mBehaviorList.behaviorCount() << "\n"; + } + else if(pPropagationLevel == 1) + { + ss << "behaviors\n"; + int behaviorCount = mBehaviorList.behaviorCount(); + for(int bI=0; bIname() << " in: " << beh->inputParameterString() << " out: " << beh->outputParameterString() << "\n"; + } + } + else + { + ss << "BehaviorList\n"; + ss << mBehaviorList.info(pPropagationLevel - 1) << "\n"; + } + + +// if(pPropagationLevel != 0) +// { +// ss << "BehaviorList\n"; +// ss << mBehaviorList.info(pPropagationLevel - 1) << "\n"; +// } +// else +// { +// ss << "behavior Count " << mBehaviorList.behaviorCount() << "\n"; +// } + + return ss.str(); +} \ No newline at end of file diff --git a/src/dab_flock_agent.h b/src/dab_flock_agent.h new file mode 100644 index 0000000..cde8b52 --- /dev/null +++ b/src/dab_flock_agent.h @@ -0,0 +1,433 @@ +/** \file dab_flock_agent.h + * \class dab::flock::Agent agent class + * \brief agent class + * + * + * Created by Daniel Bisig on 3/23/07. + * Ported to OpenFrameworks by Daniel Bisig on 3/08/17. + */ + +#ifndef _dab_flock_agent_h_ +#define _dab_flock_agent_h_ + +#include +#include "dab_exception.h" +#include "dab_flock_parameter_list.h" +#include "dab_flock_behavior_list.h" + +namespace dab +{ + +namespace flock +{ + +class NeighborListAlg; + +class Agent +{ +public: + /** + \brief default name + */ + static const std::string sClassName; + + /** + \brief number of agent instances + */ + static unsigned int sInstanceCount; + + /** + \brief default constructor + */ + Agent(); + + /** + \brief create agent + \param pName name of agent + */ + Agent(const std::string& pName); + + /** + \brief copy constructor + \param pAgent agent to copy properties and behaviors from + */ + Agent(const Agent& pAgent); + + /** + \brief copy constructor + \param pName name of agent + \param pAgent agent to copy properties and behaviors from + */ + Agent(const std::string& pName, const Agent& pAgent); + + /** + \brief destructor + */ + virtual ~Agent(); + + /** + \brief return agent index + \return agent index + */ + unsigned int index() const; + + /** + \brief return agent name + \returns agent name + */ + const std::string& name() const; + + /** + \brief return number of parameters the agent contains (first level parameters only + \return number of parameters the agent contains + */ + unsigned int parameterCount() const; + + /** + \brief check if agent has parameter + \param pParameterName parameter name + \return true if agent possesses a particular parameter + */ + bool checkParameter(const std::string& pParameterName) const; + + /** + \brief return parameter index + \param pParameterName parameter name + \return parameter index + \exception Exception parameter does not exist + */ + unsigned int parameterIndex(const std::string& pParameterName) const throw (Exception); + + /** + \brief get parameter + \param pParameterIndex parameter index + \return parameter + \exception Exception parameter does not exist + */ + Parameter* parameter(unsigned int pParameterIndex) throw (Exception); + + /** + \brief get parameter + \param pParameterIndex parameter index + \return parameter + \exception Exception parameter does not exist + */ + const Parameter* parameter(unsigned int pParameterIndex) const throw (Exception); + + /** + \brief get parameter + \param pParameterName parameter name + \return parameter + \exception Exception parameter does not exist + */ + Parameter* parameter(const std::string& pParameterName) throw (Exception); + + /** + \brief get parameter + \param pParameterName parameter name + \return parameter + \exception Exception parameter does not exist + */ + const Parameter* parameter(const std::string& pParameterName) const throw (Exception); + + /** + \brief add parameter + \param pParameter parameter + \exception Exception parameter name already exists + */ + virtual void addParameter(Parameter* pParameter) throw (Exception); + + /** + \brief create parameter + \param pName parameter name + \param pDim dimension of parameter (> 0) + \exception Exception parameter name already exists + */ + virtual void addParameter(const std::string& pName, unsigned int pDim) throw (Exception); + + /** + \brief create parameter + \param pName parameter name + \param pDim dimension of parameter (> 0) + \param pValue uniform parameter value + \exception Exception parameter name already exists + */ + virtual void addParameter(const std::string& pName, unsigned int pDim, float pValue) throw (Exception); + + /** + \brief create parameter + \param pName parameter name + \param pValues parameter values + \exception Exception parameter name already exists + */ + virtual void addParameter(const std::string& pName, const std::initializer_list& pValues) throw (Exception); + + /** + \brief create parameter + \param pName parameter name + \param pValues parameter values + \exception Exception parameter name already exists + */ + virtual void addParameter(const std::string& pName, const Eigen::VectorXf& pValues) throw (Exception); + + /** + \brief create parameter + \param pParameterName parameter name + \exception Exception failed to remove parameter + */ + virtual void removeParameter(const std::string& pParameterName) throw (Exception); + + /** + \brief set parameter value + \param pParameterName parameter name + \param pParameterValue parameter value + \exception Exception parameter name not found + */ + void setParameterValue(const std::string& pParameterName, float pParameterValue) throw (Exception); + + /** + \brief set parameter values + \param pParameterName parameter name + \param pParameterValues parameter values + \exception Exception parameter name is not found or parameter values has wrong dimension + */ + void setParameterValues(const std::string& pParameterName, const std::initializer_list& pParameterValues) throw (Exception); + + /** + \brief set parameter values + \param pParameterName parameter name + \param pParameterValues parameter values + \exception Exception parameter name is not found or parameter values has wrong dimension + */ + void setParameterValues(const std::string& pParameterName, const Eigen::VectorXf& pParameterValues) throw (Exception); + + /** + \brief set parameter values + \param pParameterName parameter name + \param pParameterValue parameter value + \exception Exception parameter name is not found + */ + virtual void set(const std::string& pParameterName, float pParameterValue) throw (Exception); + + /** + \brief set parameter values + \param pParameterName parameter name + \param pParameterValues parameter values + \exception Exception parameter name is not found or parameter values has wrong dimension + */ + virtual void set(const std::string& pParameterName, const std::initializer_list& pParameterValues) throw (Exception); + + /** + \brief set parameter values + \param pParameterName parameter name + \param pParameterValues parameter values + \exception Exception parameter name is not found or parameter values has wrong dimension + */ + virtual void set(const std::string& pParameterName, const Eigen::VectorXf& pParameterValues) throw (Exception); + + /** + \brief randomize parameter value + \param pParameterName parameter name + \param pMinParameterValue minimum parameter value + \param pMaxParameterValue maximum parameter value + \exception Exception parameter name not found + */ + virtual void randomize(const std::string& pParameterName, float pMinParameterValue, float pMaxParameterValue) throw (Exception); + + /** + \brief randomize parameter values + \param pParameterName parameter name + \param pMinParameterValues minimum parameter values + \param pMaxParameterValues maximum parameter values + \exception Exception parameter name not found or parameter values has wrong dimension + */ + virtual void randomize(const std::string& pParameterName, const std::initializer_list& pMinParameterValues, const std::initializer_list& pMaxParameterValues) throw (Exception); + + /** + \brief randomize parameter values + \param pParameterName parameter name + \param pMinParameterValues minimum parameter values + \param pMaxParameterValues maximum parameter values + \exception Exception parameter name not found or parameter values has wrong dimension + */ + virtual void randomize(const std::string& pParameterName, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues) throw (Exception); + + /** + \brief assign neighbors for a parameter + \param pParameterName parameter name + \param pSpaceName name of neighbor space + \param pVisible whether parameter is visible + \param pNeighborGroupAlg neighbor group algorithm + \exception Exception parameter not found, space not found, parameter and space dimension mismatch + */ + virtual void assignNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible, space::NeighborGroupAlg* pNeighborGroupAlg ) throw (Exception); + + /** + \brief assign neighbors for a parameter + \param pParameterName parameter name + \param pSpaceName name of neighbor space + \param pVisible whether parameter is visible + \exception Exception parameter not found, space not found, parameter and space dimension mismatch + + simpified assignNeighbors method that passes NULL for NeighborGroupAlg + */ + virtual void assignNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible ) throw (Exception); + + /** + \brief assign neighbors for a parameter + \param pParameterName parameter name + \param pSpaceName name of neighbor space + \param pVisible whether parameter is visible + \param pNeighborRadius radius within which neighbors are searched + \param pMaxNeighborCount maximum number of neighbors in neighbor list if >= 0 (-1: no limit) + \param pReplaceNeighborMode replace more distant neighbors with closer neighbors if true + \exception FlockException parameter not found, space not found, parameter and space dimension mismatch + + simpified assignNeighbors method that automaticall creates a NeighborGroupAlg. + */ + virtual void assignNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible, float pNeighborRadius, int pMaxNeighborCount, bool pReplaceNeighborMode ); + + /** + \brief return number of behaviors + \return number of behaviors + */ + unsigned int behaviorCount() const; + + /** + \brief check if agent has behavior + \param pBehaviorName behavior name + \return true if agent possesses a particular behavior + */ + bool checkBehavior(const std::string& pBehaviorName) const; + + /** + \brief get behavior + \param pBehaviorIndex behavior index + \return behavior + \exception Exception behavior does not exist + */ + Behavior* behavior(unsigned int pBehaviorIndex) throw (Exception); + + /** + \brief get behavior + \param pBehaviorIndex behavior index + \return behavior + \exception Exception behavior does not exist + */ + const Behavior* behavior(unsigned int pBehaviorIndex) const throw (Exception); + + /** + \brief get behavior + \param pBehaviorName behavior name + \return behavior + \exception Exception behavior not found + */ + Behavior* behavior(const std::string& pBehaviorName) throw (Exception); + + /** + \brief get behavior + \param pBehaviorName behavior name + \return behavior + \exception Exception behavior not found + */ + const Behavior* behavior(const std::string& pBehaviorName) const throw (Exception); + + /** + \brief add behavior + \param pBehavior behavior + \exception Exception behavior already exists + */ + virtual void addBehavior(Behavior* pBehavior) throw (Exception); + + /** + \brief add behavior + \param pBehaviorName behavior name + \param pBehavior behavior + \exception Exception behavior already exists or Illegal Behavior Parameters + */ + virtual void addBehavior(const std::string& pBehaviorName, const Behavior& pBehavior) throw (Exception); + + /** + \brief add behavior + \param pBehaviorName behavior name + \param pBehaviorPosition behavior position + \param pBehavior behavior + \exception Exception behavior already exists or Illegal Behavior Parameters + */ + virtual void addBehavior(const std::string& pBehaviorName, unsigned int pBehaviorPosition, const Behavior& pBehavior) throw (Exception); + + /** + \brief add behavior + \param pBehaviorName behavior name + \param pSuccessorBehaviorName name of behavior in front of which the new behavior is inserted + \param pBehavior behavior + \exception Exception behavior already exists or Illegal Behavior Parameters + */ + virtual void addBehavior(const std::string& pBehaviorName, const std::string& pSuccessorBehaviorName, const Behavior& pBehavior) throw (Exception); + + /** + \brief move behavior + \param pBehaviorName behavior name + \param pBehaviorPosition behavior position + \exception Exception behavior not found + */ + virtual void moveBehavior(const std::string& pBehaviorName, unsigned int pBehaviorPosition) throw (Exception); + + /** + \brief move behavior + \param pBehaviorName behavior name + \param pSuccessorBehaviorName name of behavior in front of which the new behavior is inserted + \exception Exception behavior not found + */ + virtual void moveBehavior(const std::string& pBehaviorName, const std::string& pSuccessorBehaviorName) throw (Exception); + + /** + \brief remove behavior + \param pBehaviorName behavior name + \exception Exception failed to remove behavior + */ + virtual void removeBehavior(const std::string& pBehaviorName) throw (Exception); + + /** + \brief perform behaviors + */ + virtual void act(); + + /** + \brief update parameters + */ + virtual void flush(); + + /** + \brief print agent information + */ + virtual operator std::string() const; + + /** + \brief print agent information + \param pPropagationLevel how far the propagation method proceeds through composite classes (-1: unlimited, 0: no proceeding, >0: limited proceeding) + */ + virtual std::string info(int pPropagationLevel = 0) const; + + /** + \brief print agent information + */ + friend std::ostream& operator<< (std::ostream& pOstream, const Agent& pAgent) + { + pOstream << pAgent.info(); + + return pOstream; + }; + +protected: + std::string mName; /// \brief agent name + unsigned int mIndex; /// \brief agent index + ParameterList mParameterList; /// \brief list of parameters + BehaviorList mBehaviorList; /// \brief list of behaviors +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_agent_id_behavior.cpp b/src/dab_flock_agent_id_behavior.cpp new file mode 100644 index 0000000..183255a --- /dev/null +++ b/src/dab_flock_agent_id_behavior.cpp @@ -0,0 +1,65 @@ +/** \file dab_flock_agent_id_behavior.cpp + */ + +#include "dab_flock_agent_id_behavior.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +AgentIdBehavior::AgentIdBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "AgentIdBehavior"; +} + +AgentIdBehavior::AgentIdBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "AgentIdBehavior"; + + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters[0]->dim() != 1 ) throw Exception( "FLOCK ERROR: output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()) + " must match be " + std::to_string(1), __FILE__, __FUNCTION__, __LINE__ ); + + // output parameter + mIdPar = mOutputParameters[0]; +} + +AgentIdBehavior::~AgentIdBehavior() +{} + +Behavior* +AgentIdBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new AgentIdBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new AgentIdBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +AgentIdBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new AgentIdBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +AgentIdBehavior::act() +{ + //std::cout << "AgentIdBehavior begin: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + if(mActivePar->value() <= 0.0) return; + + mIdPar->set( static_cast( mAgent->index() ) ); +} \ No newline at end of file diff --git a/src/dab_flock_agent_id_behavior.h b/src/dab_flock_agent_id_behavior.h new file mode 100644 index 0000000..39232a2 --- /dev/null +++ b/src/dab_flock_agent_id_behavior.h @@ -0,0 +1,83 @@ +/** \file dab_flock_agent_id_behavior.h + * \class dab::flock::AgentIdBehavior agent id behavior + * \brief agent id behavior + * + * The Behavior stores agent id in output parameter\n + * \n + * Input Parameter:\n + * \n + * Output Parameter:\n + * type: output dim: 1 write: replace\n + * \n + * Created by Daniel Bisig on 6/22/11. + * Ported to OpenFrameworks by Daniel Bisig on 01/10/2017 + */ + +#ifndef _dab_flock_agent_id_behavior_h_ +#define _dab_flock_agent_id_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class AgentIdBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + AgentIdBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + AgentIdBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~AgentIdBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mIdPar; /// \brief reset parameter (output) +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_alignment_behavior.cpp b/src/dab_flock_alignment_behavior.cpp new file mode 100644 index 0000000..9762a34 --- /dev/null +++ b/src/dab_flock_alignment_behavior.cpp @@ -0,0 +1,141 @@ +/** \file dab_flock_alignment_behavior.cpp + */ + +#include "dab_flock_alignment_behavior.h" +#include "dab_flock_parameter.h" +#include "dab_flock_agent.h" +#include "dab_space_neighbor_relation.h" + +using namespace dab; +using namespace dab::flock; + +AlignmentBehavior::AlignmentBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "AlignmentBehavior"; +} + +AlignmentBehavior::AlignmentBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "AlignmentBehavior"; + + if( mInputParameters.size() < 2 && ( mInputParameters.size() < 1 && mNeighborInputParameterNames.size() > 0 ) ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(2) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters.size() > 1 && mInputParameters[0]->dim() != mInputParameters[1]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match input parameter " + mInputParameters[1]->name() + " dim " + std::to_string(mInputParameters[1]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mInputNeighborGroups.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputNeighborGroups.size()) + " neighbor groups supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mPositionPar = mInputParameters[0]; + + if( mNeighborInputParameterNames.size() > 0 ) // new parameter version: position@positionspace:velocity + { + mVelocityPar = mAgent->parameter( mNeighborInputParameterNames[0] ); + } + else // old parameter version: position:positionspace velocity + { + mVelocityPar = mInputParameters[1]; + } + + // output parameter + mForcePar = mOutputParameters[0]; + + // create internal parameters + mMinDistPar = createInternalParameter("minDist", { 0.0f } ); + mMaxDistPar = createInternalParameter("maxDist", { 0.5f } ); + mAmountPar = createInternalParameter("amount", { 0.1f } ); + + // input neighbor groups + mPositionNeighbors = mInputNeighborGroups[0]; + + // remaining stuff + unsigned int dim = mForcePar->dim(); + mAvgVelocity.resize(dim, 1); + mTmpForce.resize(dim, 1); +} + +AlignmentBehavior::~AlignmentBehavior() +{} + +Behavior* +AlignmentBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new AlignmentBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new AlignmentBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +AlignmentBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new AlignmentBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +AlignmentBehavior::act() +{ + //std::cout << "AlignmentBehavior::act()\n"; + + //std::cout << "AlignmentBehavior begin: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& position = mPositionPar->values(); + space::NeighborGroup& positionNeighbors = *mPositionNeighbors; + Eigen::VectorXf& velocity = mVelocityPar->values(); + const std::string& velocityName = mVelocityPar->name(); + + + Eigen::VectorXf& force = mForcePar->backupValues(); + float& minDist = mMinDistPar->value(); + float& maxDist = mMaxDistPar->value(); + float& amount = mAmountPar->value(); + Eigen::VectorXf& avgVelocity = mAvgVelocity; + Eigen::VectorXf& tmpForce = mTmpForce; + + unsigned int totalNeighborCount = positionNeighbors.neighborCount(); + unsigned int neighborCount = 0; + + float distance; + + avgVelocity.setConstant(0.0); + + //std::cout << "totalNeighborCount " << totalNeighborCount << "\n"; + + for(unsigned int i=0; i 0.0 && distance < minDist) continue; + if(maxDist > 0.0 && distance > maxDist) continue; + + Eigen::VectorXf& neighborVelocity = static_cast(positionNeighbors.neighbor(i))->agent()->parameter( velocityName )->values(); + + //std::cout << "agent " << mAgent->name().toStdString() << " pos " << position << " neighbor " << ( static_cast(positionNeighbors.neighbor(i))->agent()->name().toStdString() ) << " npos " << ( static_cast(positionNeighbors.neighbor(i))->agent()->parameter( mPositionPar->name() ).values() ) << " distance " << distance << "\n"; + + avgVelocity += neighborVelocity; + neighborCount++; + } + + if(neighborCount == 0) return; + + avgVelocity /= static_cast(neighborCount); + + tmpForce = avgVelocity - velocity; + tmpForce *= amount; + + force += tmpForce; +} \ No newline at end of file diff --git a/src/dab_flock_alignment_behavior.h b/src/dab_flock_alignment_behavior.h new file mode 100644 index 0000000..097839f --- /dev/null +++ b/src/dab_flock_alignment_behavior.h @@ -0,0 +1,104 @@ +/** \file dab_flock_alignment_behavior.h + * \class dab::flock::AlignmentBehavior velocity alignment behavior + * \brief velocity alignment behavior + * + * Behavior causes Agent to adapt its velocity to the velocities of its neighbors.\n + * The behavior derives a force vector to adapt the velocity.\n + * \n + * Input Parameter:\n + * type: position dim: nD neighbors: required\n + * type: velocity dim: nD neighbors: ignore\n + * \n + * Output Parameter:\n + * type: force dim: nD write: add\n + * \n + * Internal Parameter:\n + * name: xxx_mindist dim: 1D defaultValue: 0.0\n + * name: xxx_maxdist dim: 1D defaultValue: 0.5\n + * name: xxx_amount dim: 1D defaultValue: 0.1\n + * name: xxx_active dim: 1D defaultValue: 1.0\n + * \n + * Created by Daniel Bisig on 4/21/07. + * Ported to OpenFrameworks by Daniel Bisig on 13/10/2017. + */ + +#ifndef _dab_flock_alignment_behavior_h_ +#define _dab_flock_alignment_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class Agent; + +class AlignmentBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + AlignmentBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + AlignmentBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~AlignmentBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception FlockException wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mPositionPar; /// \brief position parameter (input) + Parameter* mVelocityPar; /// \brief velocity parameter (input) + Parameter* mForcePar; /// \brief force parameter (output) + Parameter* mMinDistPar; /// \brief minimum distance parameter (internal) + Parameter* mMaxDistPar; /// \brief maximum distance parameter (internal) + Parameter* mAmountPar; /// \brief behavior amount parameter (internal) + + space::NeighborGroup* mPositionNeighbors; /// \brief position neighbor group + + Eigen::VectorXf mAvgVelocity; /// \brief avg of neighboring velocities + Eigen::VectorXf mTmpForce; /// \brief temporary force +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_behavior.cpp b/src/dab_flock_behavior.cpp new file mode 100644 index 0000000..a99b219 --- /dev/null +++ b/src/dab_flock_behavior.cpp @@ -0,0 +1,352 @@ +/** \file iso_flock_behavior.cpp + */ + +#include "dab_flock_behavior.h" +#include "dab_flock_agent.h" +#include "dab_flock_swarm.h" +#include "dab_flock_parameter.h" +#include "dab_tokenizer.h" + +using namespace dab; +using namespace dab::flock; + +Behavior::Behavior() +: mAgent(nullptr) +{} + +Behavior::Behavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: mAgent(nullptr) +, mClassName( "Behavior" ) +, mInputParameterString(pInputParameterString) +, mOutputParameterString(pOutputParameterString) +{} + +Behavior::Behavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) +: mAgent(pAgent) +, mName(pBehaviorName) +, mClassName( "Behavior" ) +, mInputParameterString(pInputParameterString) +, mOutputParameterString(pOutputParameterString) +{ + //std::cout << "Behavior name " << pBehaviorName.toStdString() << " agent name " << pAgent->name().toStdString() << "\n"; + + mActivePar = createInternalParameter("active", { 1.0 }); + + createInputParameters(); + createOutputParameters(); +} + +Behavior::~Behavior() +{ + mInputParameters.clear(); + mInputNeighborGroups.clear(); + mOutputParameters.clear(); + + unsigned int internalParameterCount = mInternalParameters.size(); + for(unsigned int i=0; iremoveParameter( mInternalParameters[i]->name() ); + } + mInternalParameters.clear(); +} + +void +Behavior::createInputParameters() throw (Exception) +{ + try + { + Tokenizer& tokenizer = Tokenizer::get(); + std::vector inputParameterNames; + tokenizer.split(mInputParameterString, inputParameterNames, ' '); + unsigned int inputParameterCount = inputParameterNames.size(); + + for(unsigned int i=0; icheckParameter( parameterName ) ) parameter = mAgent->parameter(parameterName); + else // check if parameter is a SwarmParameter + { + Swarm* swarm = static_cast< Swarm* > (mAgent); + if( swarm->checkSwarmParameter( parameterName ) ) parameter = swarm->swarmParameter( parameterName ); + else throw Exception( "FLOCK ERROR: parameter " + parameterName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + } + + mInputParameters.push_back(parameter); + } + else // parameter_name @ space_name + { + std::string parameterName; + std::string spaceName; + std::string neighborParName; + Parameter* parameter; + + std::vector parSpacePairNames; + tokenizer.split(inputParameterNames[i], parSpacePairNames, '@'); + + parameterName = parSpacePairNames[0]; + + // check if parameter is an AgentParameter + if( mAgent->checkParameter( parameterName ) ) parameter = mAgent->parameter(parameterName); + else // check if parameter is a SwarmParameter + { + Swarm* swarm = static_cast< Swarm* > (mAgent); + if( swarm->checkSwarmParameter( parameterName ) ) parameter = swarm->swarmParameter( parameterName ); + else throw Exception( "FLOCK ERROR: parameter " + parameterName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + } + + mInputParameters.push_back(parameter); + + if(parSpacePairNames.size() > 1) // neighbors requested + { + for(unsigned int j=1; j spaceNeighborParPairNames; + tokenizer.split(parSpacePairNames[j], spaceNeighborParPairNames, ':'); + spaceName = spaceNeighborParPairNames[0]; + neighborParName = spaceNeighborParPairNames[1]; + } + else + { + spaceName = parSpacePairNames[j]; + neighborParName = ""; + } + + + if( parameter->checkNeighborGroup( spaceName ) == false ) throw Exception( "FLOCK ERROR: Parameter does not contain neighbor group " + spaceName, __FILE__, __FUNCTION__, __LINE__ ); + space::NeighborGroup* neighborGroup = parameter->neighborGroup(spaceName); + mInputNeighborGroups.push_back( neighborGroup ); + mNeighborInputParameterNames.push_back( neighborParName ); + } + } + } + } + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to create input parameters", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +Behavior::createOutputParameters() throw (Exception) +{ + try + { + Tokenizer& tokenizer = Tokenizer::get(); + std::vector outputParameterNames; + tokenizer.split(mOutputParameterString, outputParameterNames, ' '); + unsigned int outputParameterCount = outputParameterNames.size(); + + for(unsigned int i=0; icheckParameter( parameterName ) ) parameter = mAgent->parameter(parameterName); + else + { + Swarm* swarm = static_cast< Swarm* > (mAgent); + if( swarm->checkSwarmParameter( parameterName ) ) parameter = swarm->swarmParameter(parameterName); + else throw Exception( "FLOCK ERROR: parameter " + parameterName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + } + + mOutputParameters.push_back(parameter); + } + else // parameter_name @ space_name + { + std::string parameterName; + std::string spaceName; + std::string neighborParName; + Parameter* parameter; + + std::vector parSpacePairNames; + tokenizer.split(outputParameterNames[i], parSpacePairNames, '@'); + parameterName = parSpacePairNames[0]; + + if( mAgent->checkParameter( parameterName ) ) parameter = mAgent->parameter(parameterName); + else + { + Swarm* swarm = static_cast< Swarm* > (mAgent); + if( swarm->checkSwarmParameter( parameterName ) ) parameter = swarm->swarmParameter( parameterName ); + else throw Exception( "FLOCK ERROR: parameter " + parameterName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + } + + mOutputParameters.push_back(parameter); + + if(parSpacePairNames.size() > 1) // neighbors requested + { + for(unsigned int j=1; j spaceNeighborParPairNames; + tokenizer.split(parSpacePairNames[j], spaceNeighborParPairNames, ':'); + spaceName = spaceNeighborParPairNames[0]; + neighborParName = spaceNeighborParPairNames[1]; + } + else + { + spaceName = parSpacePairNames[j]; + neighborParName = ""; + } + + if( parameter->checkNeighborGroup( spaceName ) == false ) throw Exception( "FLOCK ERROR: Parameter does not contain neighbor group " + spaceName, __FILE__, __FUNCTION__, __LINE__ ); + + space::NeighborGroup* neighborGroup = parameter->neighborGroup(spaceName); + mOutputNeighborGroups.push_back( neighborGroup ); + mNeighborOutputParameterNames.push_back( neighborParName ); + } + } + } + } + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to create output parameters", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +Parameter* +Behavior::createInternalParameter(const std::string& pParameterName, const std::vector& pValues) +{ + std::string fullParameterName = mName + "_" + pParameterName; + Parameter* internalParameter; + + // create internal parameter only if it doesn't exist already + if( mAgent->checkParameter(fullParameterName) == true ) internalParameter = mAgent->parameter(fullParameterName); + else + { + internalParameter = new Parameter(mAgent, fullParameterName, pValues); + mInternalParameters.push_back(internalParameter); + mAgent->addParameter(internalParameter); + } + + return internalParameter; +} + +Parameter* +Behavior::createInternalParameter(const std::string& pParameterName, int pDim, float pValue ) +{ + std::string fullParameterName = mName + "_" + pParameterName; + Parameter* internalParameter; + + // create internal parameter only if it doesn't exist already + if( mAgent->checkParameter(fullParameterName) == true ) internalParameter = mAgent->parameter(fullParameterName); + else + { + Eigen::VectorXf values(pDim); + values.setConstant(pValue); + + internalParameter = new Parameter(mAgent, fullParameterName, values); + mInternalParameters.push_back(internalParameter); + mAgent->addParameter(internalParameter); + } + + return internalParameter; +} + +Parameter* +Behavior::createInternalParameter(const std::string& pParameterName, const std::initializer_list& pValues) +{ + std::string fullParameterName = mName + "_" + pParameterName; + Parameter* internalParameter; + + // create internal parameter only if it doesn't exist already + if( mAgent->checkParameter(fullParameterName) == true ) internalParameter = mAgent->parameter(fullParameterName); + else + { + internalParameter = new Parameter(mAgent, fullParameterName, pValues); + mInternalParameters.push_back(internalParameter); + mAgent->addParameter(internalParameter); + } + + return internalParameter; +} + +std::vector< Parameter* >& +Behavior::internalParameters() +{ + return mInternalParameters; +} + +const std::string& +Behavior::name() const +{ + return mName; +} + +std::string +Behavior::className() const +{ + return mClassName; +} + +const std::string& +Behavior::inputParameterString() const +{ + return mInputParameterString; +} + +const std::string& +Behavior::outputParameterString() const +{ + return mOutputParameterString; +} + +Behavior::operator std::string() const +{ + return info(); +} + +std::string +Behavior::info(int pPropagationLevel) const +{ + std::stringstream ss; + + ss << mName << ": "; + + unsigned int inputParameterCount = mInputParameters.size(); + if(inputParameterCount > 0) + { + ss << "Input: [ "; + for(unsigned int i=0; iname() << " "; + ss << "] "; + } + + unsigned int outputParameterCount = mOutputParameters.size(); + if(outputParameterCount > 0) + { + ss << "Output: [ "; + for(unsigned int i=0; iname() << " "; + ss << "] "; + } + + unsigned int internalParameterCount = mInternalParameters.size(); + if(internalParameterCount > 0) + { + ss << "Internal: [ "; + for(unsigned int i=0; iname() << " "; + ss << "] "; + } + + unsigned int inputNeighborGroupCount = mInputNeighborGroups.size(); + if(inputNeighborGroupCount > 0) + { + ss << "NeighborGroup: [ "; + for(unsigned int i=0; iname() << " "; + ss << "] "; + } + + return ss.str(); +} diff --git a/src/dab_flock_behavior.h b/src/dab_flock_behavior.h new file mode 100644 index 0000000..bdf0372 --- /dev/null +++ b/src/dab_flock_behavior.h @@ -0,0 +1,203 @@ +/** \file dab_flock_behavior.h + * \class dab::flock::Behavior behavior class + * \brief behavior class + * + * Abstract base class for agent behaviors.\n + * Any derived behavior class needs to implement an act methods, that is called once during each simulation step.\n + * \n + * Input Parameter:\n + * \n + * Output Parameter:\n + * \n + * Internal Parameter:\n + * name: xxx:active dim: 1D\n + * \n + * Created by Daniel Bisig on 3/23/07. + * Ported to OpenFrameworks by Daniel Bisig on 3/08/17. + */ + +#ifndef _dab_flock_behavior_h_ +#define _dab_flock_behavior_h_ + +#include "dab_flock_parameter.h" +#include "dab_space_neighbor_group.h" +#include +#include + +namespace dab +{ + +namespace flock +{ + +class Agent; +class Parameter; +class Behavior +{ + +friend class Swarm; + +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + Behavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent reference to agent to which this behavior is added + \param pBehaviorName behavior name + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + Behavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief destructor + */ + virtual ~Behavior(); + + /** + \brief create copy of behavior + \param pSwarm swarm this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pSwarm) const = 0; + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const = 0; + + /** + \brief return behavior name + \return behavior name + */ + const std::string& name() const; + + std::string className() const; + + /** + \brief return input parameter string + \return input parameter string + */ + const std::string& inputParameterString() const; + + /** + \brief return output parameter string + \return output parameter string + */ + const std::string& outputParameterString() const; + + /** + \brief perform behavior + */ + virtual void act() = 0; + + /** + \brief print behavior information + */ + virtual operator std::string() const; + + /** + \brief print behavior information + \param pPropagationLevel how far the propagation method proceeds through composite classes (-1: unlimited, 0: no proceeding, >0: limited proceeding) + */ + virtual std::string info(int pPropagationLevel = 0) const; + + /** + \brief retrieve textual behavior info + \param pOstream output text stream + \param pBehavior behavior + */ + friend std::ostream& operator << ( std::ostream& pOstream, const Behavior& pBehavior ) + { + pOstream << pBehavior.info(); + + return pOstream; + }; + +protected: + /** + \brief default constructor + */ + Behavior(); + + /** + \brief create input behavior parameters + \exception Exception failed to create input parameters + */ + virtual void createInputParameters() throw (Exception); + + /** + \brief create output behavior parameters + \exception Exception failed to create output parameters + */ + virtual void createOutputParameters() throw (Exception); + + /** + \brief create internal behavior parameter + \param pParameterName name of parameter + \param pValues values of parameter + \return parameter + + creates an internal behavior parameter which is visible at the level of the agent (i.e. other behaviors can access it).\n + the name of the parameter is constructed as follows: behaviorName_parameterName.\n + */ + Parameter* createInternalParameter(const std::string& pParameterName, const std::vector& pValues ); + + /** + \brief create internal behavior parameter + \param pParameterName name of parameter + \param pDim dimension of parameter + \param pValues value of parameter + \return parameter + + creates an internal behavior parameter which is visible at the level of the agent (i.e. other behaviors can access it).\n + the name of the parameter is constructed as follows: behaviorName_parameterName.\n + */ + Parameter* createInternalParameter(const std::string& pParameterName, int pDim, float pValue ); + + /** + \brief create internal behavior parameter + \param pParameterName name of parameter + \param pValues values of parameter + \return parameter + + creates an internal behavior parameter which is visible at the level of the agent (i.e. other behaviors can access it).\n + the name of the parameter is constructed as follows: behaviorName_parameterName.\n + */ + Parameter* createInternalParameter(const std::string& pParameterName, const std::initializer_list& pValues); + + /** + \brief return internal behavior parameters + \return internal behavior parameters + */ + std::vector< Parameter* >& internalParameters(); + + std::string mName; /// \brief behavior name + std::string mClassName; /// \brief behavior class name + Agent* mAgent; /// \brief agent this behavior belongs to + std::string mInputParameterString; /// \brief unparsed string containing all input parameter names + std::string mOutputParameterString; /// \brief unparsed string containing all output parameter names + std::vector mInputParameters; /// \brief input parameters (behavior reads from them) + std::vector mInputNeighborGroups; /// \brief input neighbor groups (behavior reads from them) + std::vector mNeighborInputParameterNames; /// \brief input parameter names for parameters that are retrieved via neighbor groups + std::vector mOutputParameters; /// \brief output parameters (behavior writes to them) + std::vector mOutputNeighborGroups; /// \brief output neighbor groups (behavior writes to them) + std::vector mNeighborOutputParameterNames; /// \brief output parameter names for parameters that are retrieved via neighbor groups + std::vector mInternalParameters; /// \brief internal parameters (including scales) + Parameter* mActivePar; /// \brief active parameter (internal) +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_behavior_includes.h b/src/dab_flock_behavior_includes.h new file mode 100644 index 0000000..d088fc3 --- /dev/null +++ b/src/dab_flock_behavior_includes.h @@ -0,0 +1,51 @@ +/** \file dab_flock_behavior_includes.h + * \brief a list of includes for custom behaviors + * + * Created by Daniel Bisig on 8/31/07. + * Ported to OpenFramerworks by Daniel Bisig on 01/10/2017. + */ + +#ifndef _dab_flock_behavior_includes_h_ +#define _dab_flock_behavior_includes_h_ + +#include "dab_flock_euler_integration.h" +#include "dab_flock_agent_id_behavior.h" +#include "dab_flock_acceleration_behavior.h" +#include "dab_flock_alignment_behavior.h" +#include "dab_flock_boundary_mirror_behavior.h" +#include "dab_flock_boundary_wrap_behavior.h" +#include "dab_flock_boundary_repulsion_behavior.h" +#include "dab_flock_cohesion_behavior.h" +#include "dab_flock_copy_behavior.h" +#include "dab_flock_damping_behavior.h" +#include "dab_flock_evasion_behavior.h" +#include "dab_flock_grid_avg_behavior.h" +#include "dab_flock_randomize_behavior.h" +#include "dab_flock_reset_behavior.h" +#include "dab_flock_spiral_behavior.h" +#include "dab_flock_line_follow_behavior.h" +#include "dab_flock_distance_field_follow_behavior.h" +#include "dab_flock_circular_behavior.h" +#include "dab_flock_parameter_mag_behavior.h" +#include "dab_flock_parameter_map_behavior.h" +#include "dab_flock_parameter_print_behavior.h" +#include "dab_flock_parameter_threshold_to_event_behavior.h" +#include "dab_flock_parameter_scale_behavior.h" +#include "dab_flock_cone_vision_behavior.h" +#include "dab_flock_neighbor_store_behavior.h" +#include "dab_flock_neighbor_index_store_behavior.h" +#include "dab_flock_neighbor_distance_store_behavior.h" +#include "dab_flock_neighbor_direction_store_behavior.h" +#include "dab_flock_neighbor_parameter_store_behavior.h" +#include "dab_flock_parameter_combine_behavior.h" +#include "dab_flock_target_parameter_behavior.h" +#include "dab_flock_orbit_behavior.h" +#include "dab_flock_env_agent_interact_behavior.h" +#include "dab_flock_env_clamp_behavior.h" +#include "dab_flock_env_decay_behavior.h" +#include "dab_flock_env_diffusion_behavior.h" +#include "dab_flock_env_gray_scott_behavior.h" +#include "dab_flock_env_gierer_meinhardt_behavior.h" +//#include "dab_flock_statistics_behavior.h" + +#endif \ No newline at end of file diff --git a/src/dab_flock_behavior_list.cpp b/src/dab_flock_behavior_list.cpp new file mode 100644 index 0000000..41641b3 --- /dev/null +++ b/src/dab_flock_behavior_list.cpp @@ -0,0 +1,188 @@ +/** \file dab_flock_behavior_list.cpp + */ + +#include "dab_flock_behavior_list.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +BehaviorList::BehaviorList() +{ + assert("illegal constructor"); +} + +BehaviorList::~BehaviorList() +{ + unsigned int behaviorCount = mBehaviors.size(); + + for(unsigned int i=0; i= mBehaviors.size() ) throw Exception( "FLOCK ERROR: behavior index " + std::to_string(pIndex) + " out of bounds", __FILE__, __FUNCTION__, __LINE__ ); + + return mBehaviors[pIndex]; +} + +const Behavior* +BehaviorList::behavior(unsigned int pIndex) const throw (Exception) +{ + if( pIndex >= mBehaviors.size() ) throw Exception( "FLOCK ERROR: behavior index " + std::to_string(pIndex) + " out of bounds", __FILE__, __FUNCTION__, __LINE__ ); + + return mBehaviors[pIndex]; +} + +Behavior* +BehaviorList::behavior(const std::string& pName) throw (Exception) +{ + + if(mBehaviors.contains(pName) == false) throw Exception( "FLOCK ERROR: behavior name " + pName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + return mBehaviors[pName]; +} + +const Behavior* +BehaviorList::behavior(const std::string& pName) const throw (Exception) +{ + if(mBehaviors.contains(pName) == false) throw Exception( "FLOCK ERROR: behavior name " + pName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + return mBehaviors[pName]; +} + +unsigned int +BehaviorList::behaviorIndex(const std::string& pName) throw (Exception) +{ + if(mBehaviors.contains(pName) == false) throw Exception( "FLOCK ERROR: behavior name " + pName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + return mBehaviors.index(pName); +} + +void +BehaviorList::addBehavior(Behavior* pBehavior) throw (Exception) +{ + if(mBehaviors.contains(pBehavior->name()) == true) throw Exception( "FLOCK ERROR: behavior name " + pBehavior->name() + " already exists", __FILE__, __FUNCTION__, __LINE__ ); + + try + { + mBehaviors.add( pBehavior->name(), pBehavior ); + } + catch (Exception& e) + { + e += Exception( "FLOCK ERROR: failed to add behavior " + pBehavior->name(), __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +BehaviorList::addBehavior(Behavior* pBehavior, unsigned int pBehaviorPosition) throw (Exception) +{ + if(mBehaviors.contains(pBehavior->name()) == true) throw Exception( "FLOCK ERROR: behavior name " + pBehavior->name() + " already exists", __FILE__, __FUNCTION__, __LINE__ ); + + if( pBehaviorPosition > mBehaviors.size() ) pBehaviorPosition = mBehaviors.size(); + + try + { + mBehaviors.insert( pBehavior->name(), pBehavior, pBehaviorPosition ); + } + catch (Exception& e) + { + e += Exception( "FLOCK ERROR: failed to add behavior " + pBehavior->name(), __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +BehaviorList::moveBehavior(unsigned int pOldBehaviorPosition, unsigned int pNewBehaviorPosition) throw (Exception) +{ + if( pOldBehaviorPosition > mBehaviors.size() ) pOldBehaviorPosition = mBehaviors.size(); + if( pNewBehaviorPosition > mBehaviors.size() ) pNewBehaviorPosition = mBehaviors.size(); + if( pOldBehaviorPosition == pNewBehaviorPosition ) return; + + + try + { + mBehaviors.move( pOldBehaviorPosition, pNewBehaviorPosition ); + } + catch (Exception& e) + { + e += Exception( "FLOCK ERROR: failed to move behavior at position " + std::to_string(pOldBehaviorPosition) + " to position " + std::to_string(pNewBehaviorPosition), __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +BehaviorList::removeBehavior(const std::string& pName) throw (Exception) +{ + if(mBehaviors.contains(pName) == false) throw Exception( "FLOCK ERROR: behavior name " + pName + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + + mBehaviors.remove(pName); +} + +void +BehaviorList::act() +{ + //std::cout << "BehaviorList::act() begin\n"; + + unsigned int behaviorCount = mBehaviors.size(); + for(unsigned int i=0; iact(); + + //std::cout << "behavior " << mBehaviors[i].name().toStdString() << " act end\n"; + } + + //std::cout << "BehaviorList::act() end\n"; +} + +BehaviorList::operator std::string() const +{ + return info(); +} + +std::string +BehaviorList::info(int pPropagationLevel) const +{ + std::stringstream ss; + + unsigned int behaviorCount = mBehaviors.size(); + + for(unsigned int i=0; i= 1) + { + ss << behavior->info(pPropagationLevel - 1) << "\n"; + } + } + + return ss.str(); +} \ No newline at end of file diff --git a/src/dab_flock_behavior_list.h b/src/dab_flock_behavior_list.h new file mode 100644 index 0000000..7041935 --- /dev/null +++ b/src/dab_flock_behavior_list.h @@ -0,0 +1,153 @@ +/** \file dab_flock_behavior_list.h + * + * Created by Daniel Bisig on 4/14/07. + * Ported to OpenFrameworks by Daniel Bisig on 3/08/17. + */ + +#ifndef _dab_flock_behavior_list_h_ +#define _dab_flock_behavior_list_h_ + +#include "dab_exception.h" +#include "dab_flock_behavior.h" +#include "dab_index_map.h" + +namespace dab +{ + +namespace flock +{ + +class Agent; + +class BehaviorList +{ +public: + /** + \brief default constructor + */ + BehaviorList(); + + /** + \brief destructor + */ + ~BehaviorList(); + + /** + \brief return number of behaviors this list contains + \return number of behaviors this list contains + */ + unsigned int behaviorCount() const; + + /** + \brief checks if behavior list contains behavior + \param pName behavior name + \return true, if behavior name exists + */ + bool contains(const std::string& pName) const; + + /** + \brief get behavior + \param pIndex behavior index + \return behavior + \exception Exception behavior not found + */ + Behavior* behavior(unsigned int pIndex) throw (Exception); + + /** + \brief get behavior + \param pIndex behavior index + \return behavior + \exception Exception behavior not found + */ + const Behavior* behavior(unsigned int pIndex) const throw (Exception); + + /** + \brief get behavior + \param pName behavior name + \return behavior + \exception Exception behavior not found + */ + Behavior* behavior(const std::string& pName) throw (Exception); + + /** + \brief get behavior + \param pName behavior name + \return behavior + \exception Exception behavior not found + */ + const Behavior* behavior(const std::string& pName) const throw (Exception); + + /** + \brief get behavior index + \param pName behavior name + \return behavior index + \exception Exception behavior not found + */ + unsigned int behaviorIndex(const std::string& pName) throw (Exception); + + /** + \brief add behavior + \param pBehavior behavior + \exception Exception behavior already exists + */ + void addBehavior(Behavior* pBehavior) throw (Exception); + + /** + \brief add behavior + \param pBehavior behavior + \param pBehaviorPosition behavior position + \exception Exception behavior already exists or Illegal Behavior Parameters + */ + void addBehavior(Behavior* pBehavior, unsigned int pBehaviorPosition) throw (Exception); + + /** + \brief move behavior + \param pOldBehaviorPosition old behavior position + \param pOldBehaviorPosition new behavior position + \exception FlockException behavior not found + */ + void moveBehavior(unsigned int pOldBehaviorPosition, unsigned int pNewBehaviorPosition) throw (Exception); + + /** + \brief remove behavior + \param pName behavior name + \exception FlockException behavior not found + */ + void removeBehavior(const std::string& pName) throw (Exception); + + /** + \brief perform behaviors + */ + void act(); + + /** + \brief print behavior list information + */ + virtual operator std::string() const; + + /** + \brief print behavior list information + \param pPropagationLevel how far the propagation method proceeds through composite classes (-1: unlimited, 0: no proceeding, >0: limited proceeding) + */ + virtual std::string info(int pPropagationLevel = 0) const; + + /** + \brief print behavior list information + */ + friend std::ostream& operator<< (std::ostream& pOstream, const BehaviorList& pBehaviorList) + { + pOstream << pBehaviorList.info(); + + return pOstream; + }; + + +protected: + IndexMap mBehaviors; ///\brief behaviors +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_boundary_mirror_behavior.cpp b/src/dab_flock_boundary_mirror_behavior.cpp new file mode 100644 index 0000000..692ffad --- /dev/null +++ b/src/dab_flock_boundary_mirror_behavior.cpp @@ -0,0 +1,100 @@ +/** \file dab_flock_boundary_mirror_behavior.cpp + */ + +#include "dab_flock_boundary_mirror_behavior.h" +#include "dab_flock_parameter.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +BoundaryMirrorBehavior::BoundaryMirrorBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "BoundaryMirrorBehavior"; +} + +BoundaryMirrorBehavior::BoundaryMirrorBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "BoundaryMirrorBehavior"; + + if( mInputParameters.size() < 3 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(3) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 2 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(2) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[1]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[1]->name() + " dim " + std::to_string(mInputParameters[1]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[2]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[2]->name() + " dim " + std::to_string(mInputParameters[2]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters[1]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: output parameter " + mOutputParameters[1]->name() + " dim " + std::to_string(mOutputParameters[1]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mDerivative0InPar = mInputParameters[0]; + mDerivative1InPar = mInputParameters[1]; + mDerivative2InPar = mInputParameters[2]; + + // output parameter + mDerivative1OutPar = mOutputParameters[0]; + mDerivative2OutPar = mOutputParameters[1]; + + // create internal parameters + mLowerBoundaryPar = createInternalParameter("lowerBoundary", mDerivative0InPar->dim(), -1.0); + mUpperBoundaryPar = createInternalParameter("upperBoundary", mDerivative0InPar->dim(), 1.0); +} + +BoundaryMirrorBehavior::~BoundaryMirrorBehavior() +{} + +Behavior* +BoundaryMirrorBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new BoundaryMirrorBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new BoundaryMirrorBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +BoundaryMirrorBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new BoundaryMirrorBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +BoundaryMirrorBehavior::act() +{ + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& derivative0In = mDerivative0InPar->values(); + Eigen::VectorXf& derivative1In = mDerivative1InPar->values(); + Eigen::VectorXf& derivative2In = mDerivative2InPar->values(); + Eigen::VectorXf& derivative1Out = mDerivative1OutPar->backupValues(); + Eigen::VectorXf& derivative2Out = mDerivative2OutPar->backupValues(); + Eigen::VectorXf& lowerBoundary = mLowerBoundaryPar->values(); + Eigen::VectorXf& upperBoundary = mUpperBoundaryPar->values(); + + unsigned int dim = derivative0In.rows(); + + for(unsigned int i=0; i upperBoundary[i] && derivative1In[i] > 0.0)) + { + derivative1Out[i] -= 2.0 * derivative1In[i]; + } + + if((derivative0In[i] < lowerBoundary[i] && derivative2In[i] < 0.0) || (derivative0In[i] > upperBoundary[i] && derivative2In[i] > 0.0)) + { + derivative2Out[i] -= 2.0 * derivative2In[i]; + } + } +} \ No newline at end of file diff --git a/src/dab_flock_boundary_mirror_behavior.h b/src/dab_flock_boundary_mirror_behavior.h new file mode 100644 index 0000000..1c6b320 --- /dev/null +++ b/src/dab_flock_boundary_mirror_behavior.h @@ -0,0 +1,100 @@ +/** \file dab_flock_boundary_mirror_behavior.h + * \class dab::flock::BoundaryMirrorBehavior creates reflective boundary for Agent 's position + * \brief creates reflective boundary for Agent 's position + * + * Behavior creates reflective boundary for Agent 's position.\n + * The behavior is normally meant to restrict an Agent 's position to a cubic region\n + * by reflecting the velocity and acceleration at the cube's boundaries.\n + * \n + * Input Parameter:\n + * type: position dim: nD neighbors: ignore\n + * type: velocity dim: nD neighbors: ignore\n + * type: acceleration dim: nD neighbors: ignore\n + * \n + * Output Parameter:\n + * type: velocity dim: nD write: add\n + * type: acceleration dim: nD write: add\n + * \n + * Internal Parameter:\n + * name: xxx_lowerBoundary dim: nD defaultValue: -1.0\n + * name: xxx_upperBoundary dim: nD defaultValue: 1.0\n + * name: xxx_active dim: 1D defaultValue: 1.0\n + * \n + * Created by Daniel Bisig on 4/19/07. + * Ported to OpenFrameworks by Daniel Bisig on 01/10/2017. + */ + +#ifndef _dab_flock_boundary_mirror_behavior_h_ +#define _dab_flock_boundary_mirror_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class BoundaryMirrorBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + BoundaryMirrorBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + BoundaryMirrorBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~BoundaryMirrorBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mDerivative0InPar; /// \brief zero order derivative parameter (input) + Parameter* mDerivative1InPar; /// \brief first order derivative parameter (input) + Parameter* mDerivative2InPar; /// \brief second order derivative parameter (input) + Parameter* mDerivative1OutPar; /// \brief first order derivative parameter (output) + Parameter* mDerivative2OutPar; /// \brief second order derivative parameter (output) + Parameter* mLowerBoundaryPar; /// \brief lower boundary parameter (internal) + Parameter* mUpperBoundaryPar; /// \brief upper boundary parameter (internal) +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_boundary_repulsion_behavior.cpp b/src/dab_flock_boundary_repulsion_behavior.cpp new file mode 100644 index 0000000..ec7affb --- /dev/null +++ b/src/dab_flock_boundary_repulsion_behavior.cpp @@ -0,0 +1,117 @@ +/** \file dab_flock_boundary_repulsion_behavior.cpp + */ + +#include "dab_flock_boundary_repulsion_behavior.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +BoundaryRepulsionBehavior::BoundaryRepulsionBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "BoundaryRepulsionBehavior"; +} + +BoundaryRepulsionBehavior::BoundaryRepulsionBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "BoundaryRepulsionBehavior"; + + if(mInputParameters.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if(mOutputParameters.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mPositionPar = mInputParameters[0]; + + // output parameter + mForcePar = mOutputParameters[0]; + + // create internal parameters + mLowerBoundaryPar = createInternalParameter("lowerBoundary", mInputParameters[0]->dim(), -1.0); + mUpperBoundaryPar = createInternalParameter("upperBoundary", mInputParameters[0]->dim(), 1.0); + mMaxDistPar = createInternalParameter("maxDist", { 1.0f } ); + mAmountPar = createInternalParameter("amount", { 0.1f }); + + // remaining stuff + unsigned int dim = mForcePar->dim(); + mTmpForce.resize(dim, 1); +} + +BoundaryRepulsionBehavior::~BoundaryRepulsionBehavior() +{} + +Behavior* +BoundaryRepulsionBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new BoundaryRepulsionBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new BoundaryRepulsionBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +BoundaryRepulsionBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new BoundaryRepulsionBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +BoundaryRepulsionBehavior::act() +{ + //std::cout << "BoundaryRepulsionBehavior begin: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& position = mPositionPar->values(); + Eigen::VectorXf& force = mForcePar->backupValues(); + Eigen::VectorXf& lowerBoundary = mLowerBoundaryPar->values(); + Eigen::VectorXf& upperBoundary = mUpperBoundaryPar->values(); + float& maxDist = mMaxDistPar->value(); + float& amount = mAmountPar->value(); + Eigen::VectorXf& tmpForce = mTmpForce; + + tmpForce.setConstant(0.0); + + unsigned int dim = position.rows(); + + for(unsigned int i=0; i upperBoundary[i] ) + { + tmpForce[i] -= fabs ( upperBoundary[i] - position[i] ) * amount; + } + else if(position[i] > upperBoundary[i] - maxDist) + { + tmpForce[i] -= fabs ( (position[i] - upperBoundary[i]) / maxDist ) * amount; + } + } + + //std::cout << "boundary repulsion lowerB " << lowerBoundary << " upperB " << upperBoundary << " maxDist " << maxDist << " amount " << amount << " pos " << position << " force " << tmpForce << "\n"; + + force += tmpForce; + + //std::cout << "BoundaryRepulsionBehavior end: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + //assert(std::isnan(force[0]) == false && "isNan"); +} \ No newline at end of file diff --git a/src/dab_flock_boundary_repulsion_behavior.h b/src/dab_flock_boundary_repulsion_behavior.h new file mode 100644 index 0000000..6df52ca --- /dev/null +++ b/src/dab_flock_boundary_repulsion_behavior.h @@ -0,0 +1,99 @@ +/** \file dab_flock_boundary_repulsion_behavior.h + * \class dab::flock::BoundaryRepulsionBehavior creates repulsive boundary for Agent 's position + * \brief creates repulsive boundary for Agent 's position + * + * Behavior creates repulsive boundary for Agent 's position.\n + * The behavior is normally meant to restrict an Agent 's position to a cubic region\n + * by pusing the agent away from the cube's boundaries.\n + * \n + * Input Parameter:\n + * type: position dim: nD neighbors: ignore\n + * \n + * Output Parameter:\n + * type: force dim: nD write: add\n + * \n + * Internal Parameter:\n + * name: xxx_lowerBoundary dim: nD defaultValue: -1.0\n + * name: xxx_upperBoundary dim: nD defaultValue: 1.0\n + * name: xxx_amount dim: 1D defaultValue: 0.1\n + * name: xxx_active dim: 1D defaultValue: 1.0\n + * \n + * Created by Daniel Bisig on 4/22/07. + * Ported to OpenFrameworks by Daniel Bisig on 01/10/2017. + */ + +#ifndef _dab_flock_boundary_repulsion_behavior_h_ +#define _dab_flock_boundary_repulsion_behavior_h_ + +#include "dab_flock_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class BoundaryRepulsionBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + BoundaryRepulsionBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + BoundaryRepulsionBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief destructor + */ + ~BoundaryRepulsionBehavior(); + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mPositionPar; /// \brief position parameter (input) + Parameter* mForcePar; /// \brief force parameter (output) + Parameter* mLowerBoundaryPar; /// \brief lower boundary parameter (internal) + Parameter* mUpperBoundaryPar; /// \brief upper boundary parameter (internal) + Parameter* mMaxDistPar; /// \brief maximum distance parameter (internal) + Parameter* mAmountPar; /// \brief behavior amount parameter (internal) + + Eigen::VectorXf mTmpForce; /// \brief temporary force + +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_boundary_wrap_behavior.cpp b/src/dab_flock_boundary_wrap_behavior.cpp new file mode 100644 index 0000000..30943c9 --- /dev/null +++ b/src/dab_flock_boundary_wrap_behavior.cpp @@ -0,0 +1,94 @@ +/** \file dab_flock_boundary_wrap_behavior.cpp + */ + +#include "dab_flock_boundary_wrap_behavior.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +BoundaryWrapBehavior::BoundaryWrapBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "BoundaryWrapBehavior"; +} + +BoundaryWrapBehavior::BoundaryWrapBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "BoundaryWrapBehavior"; + + if( mInputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mPositionInPar = mInputParameters[0]; + + // output parameter + mPositionOutPar = mOutputParameters[0]; + + // create internal parameters + mLowerBoundaryPar = createInternalParameter("lowerBoundary", mInputParameters[0]->dim(), -1.0); + mUpperBoundaryPar = createInternalParameter("upperBoundary", mInputParameters[0]->dim(), 1.0); +} + +BoundaryWrapBehavior::~BoundaryWrapBehavior() +{} + +Behavior* +BoundaryWrapBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new BoundaryWrapBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new BoundaryWrapBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +BoundaryWrapBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new BoundaryWrapBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +BoundaryWrapBehavior::act() +{ + //std::cout << "BoundaryRepulsionBehavior begin: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& inValues = mPositionInPar->values(); + Eigen::VectorXf& outValues = mPositionOutPar->backupValues(); + Eigen::VectorXf& lowerBoundary = mLowerBoundaryPar->values(); + Eigen::VectorXf& upperBoundary = mUpperBoundaryPar->values(); + + Eigen::VectorXf boundarySize = upperBoundary - lowerBoundary; + + unsigned int dim = inValues.rows(); + + outValues = inValues; + + for(unsigned int i=0; i upperBoundary[i]) + { + outValues[i] -= boundarySize[i]; + } + } +} \ No newline at end of file diff --git a/src/dab_flock_boundary_wrap_behavior.h b/src/dab_flock_boundary_wrap_behavior.h new file mode 100644 index 0000000..cb52783 --- /dev/null +++ b/src/dab_flock_boundary_wrap_behavior.h @@ -0,0 +1,93 @@ +/** \file dab_flock_boundary_wrap_behavior.h + * \class dab::flock::BoundaryWrapBehavior creates periodic boundary for Agent 's position + * \brief creates periodic boundary for Agent 's position + * + * Behavior creates periodic boundary for Agent 's position.\n + * The behavior is normally meant to restrict an Agent 's position to a cubic region\n + * by mirroring the position to the opposite site of the cube whenever it exceeds the cube's boundaries.\n + * \n + * Input Parameter:\n + * type: position dim: nD neighbors: ignore\n + * \n + * Output Parameter:\n + * type: position dim: nD write: replace\n + * \n + * Internal Parameter:\n + * name: xxx_lowerBoundary dim: nD defaultValue: -1.0\n + * name: xxx_upperBoundary dim: nD defaultValue: 1.0\n + * name: xxx_active dim: 1D defaultValue: 1.0\n + * \n + * Created by Daniel Bisig on 8/31/07. + * Ported to OpenFrameworks by Daniel Bisig on 01/10/2017. + */ + +#ifndef _dab_flock_boundary_wrap_behavior_h_ +#define _dab_flock_boundary_wrap_behavior_h_ + +#include "dab_flock_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class BoundaryWrapBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + BoundaryWrapBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + BoundaryWrapBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~BoundaryWrapBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mPositionInPar; /// \brief position parameter (input) + Parameter* mPositionOutPar; /// \brief position parameter (output) + Parameter* mLowerBoundaryPar; /// \brief lower boundary parameter (internal) + Parameter* mUpperBoundaryPar; /// \brief upper boundary parameter (internal) +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_circular_behavior.cpp b/src/dab_flock_circular_behavior.cpp new file mode 100644 index 0000000..4c65d4b --- /dev/null +++ b/src/dab_flock_circular_behavior.cpp @@ -0,0 +1,112 @@ +/** \file dab_flock_circular_behavior.cpp + */ + +#include "dab_flock_circular_behavior.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +CircularBehavior::CircularBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "CircularBehavior"; +} + +CircularBehavior::CircularBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +, mNormZVec( 0.0, 0.0, 1.0 ) +{ + mClassName = "CircularBehavior"; + + if( mInputParameters.size() < 2 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != 3 ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must be 3 ", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[1]->dim() != 3 ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[1]->name() + " dim " + std::to_string(mInputParameters[1]->dim()) + " must be 3 ", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mPosition = mInputParameters[0]; + mVelocity = mInputParameters[1]; + + // output parameter + mForce = mOutputParameters[0]; + + // create internal parameters + mCenterPositionPar = createInternalParameter("centerPosition", { 0.0f, 0.0f, 0.0f }); + mInnerRadiusPar = createInternalParameter("innerRadius", { 2.0f }); + mOuterRadiusPar = createInternalParameter("outerRadius", { 3.0f }); + mOrtAmountPar = createInternalParameter("ortAmount", {0.1f}); + mTanAmountPar = createInternalParameter("tanAmount", {0.1f}); +} + +CircularBehavior::~CircularBehavior() +{} + +Behavior* +CircularBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new CircularBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new CircularBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +CircularBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new CircularBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +CircularBehavior::act() +{ + //std::cout << "CopyBehavior begin: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& position = mPosition->values(); + Eigen::VectorXf& velocity = mVelocity->values(); + Eigen::VectorXf& force = mForce->backupValues(); + Eigen::VectorXf& centerPosition = mCenterPositionPar->values(); + + float& innerRadius = mInnerRadiusPar->value(); + float& outerRadius = mOuterRadiusPar->value(); + float& ortAmount = mOrtAmountPar->value(); + float& tanAmount = mTanAmountPar->value(); + + // calculate tangential force + mCenterVec = centerPosition - position; + + // calculate radial force + float posLength = mCenterVec.norm(); + mCenterVec.normalize(); + + mNormVelocity = velocity; + mNormVelocity.normalize(); + mCrossVec = mCenterVec.cross(mNormVelocity); + mCrossVec.normalize(); + mNormTangentVec = mCrossVec.cross(mCenterVec); + + force += mNormTangentVec * tanAmount; + + if(posLength < innerRadius) + { + force += mCenterVec * (posLength - innerRadius) * ortAmount; + } + else if(posLength > outerRadius) + { + force += mCenterVec * (posLength - outerRadius) * ortAmount; + } +} \ No newline at end of file diff --git a/src/dab_flock_circular_behavior.h b/src/dab_flock_circular_behavior.h new file mode 100644 index 0000000..b4853a8 --- /dev/null +++ b/src/dab_flock_circular_behavior.h @@ -0,0 +1,101 @@ +/** \file dab_flock_circular_behavior.h + * \class dan::flock::CircularBehavior cause Agent to move withing a ring + * \brief cause Agent to move withing a ring + * + * The Behavior causes Agent to move withing a ring\n + * Input Parameter:\n + * type: position dim: nD neighbors: ignore\n + * \n + * Output Parameter:\n + * type: force dim: nD write: add\n + * \n + * Internal Parameter:\n + * name: xxx_innerRadius dim: 1D defaultValue: 2.0\n + * name: xxx_outerRadius dim: 1D defaultValue: 3.0\n + * name: xxx_radialAmount dim: 1D defaultValue: 0.1\n + * name: xxx_active dim: 1D defaultValue: 1.0\n + * \n + * Created by Daniel Bisig, Tasuo Unemi, Koichiro Mori, John Flury on 11/16/07. + * Ported to OpenFrameworks by Daniel Bisig on 13/10/2017. + */ + +#ifndef _dab_flock_circular_behavior_h_ +#define _dab_flock_circular_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class CircularBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + CircularBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + CircularBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~CircularBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mPosition; /// \brief position parameter (input) + Parameter* mVelocity; /// \brief velocity parameter (input) + Parameter* mForce; /// \brief force parameter (output) + Parameter* mCenterPositionPar; /// \brief center position parameter (internal) + Parameter* mInnerRadiusPar; /// \brief inner radius parameter (internal) + Parameter* mOuterRadiusPar; /// \brief outer radius parameter (internal) + Parameter* mOrtAmountPar; /// \brief orthogonal amount parameter (internal) + Parameter* mTanAmountPar; /// \brief tangential amount parameter (internal) + Eigen::Vector3f mNormVelocity; /// \brief normalized velocity + Eigen::Vector3f mCenterVec; /// \brief vector pointing from agent position towards origin + Eigen::Vector3f mNormZVec; /// \brief noralized vector pointing in positive z-direction + Eigen::Vector3f mCrossVec; + Eigen::Vector3f mNormTangentVec; /// \brief normalized tangent vector to circle +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_clear_simulation_event.cpp b/src/dab_flock_clear_simulation_event.cpp new file mode 100644 index 0000000..cec4476 --- /dev/null +++ b/src/dab_flock_clear_simulation_event.cpp @@ -0,0 +1,62 @@ +/** \dab_flock_clear_simulation_event.cpp + */ + +#include "dab_flock_clear_simulation_event.h" +#include "dab_flock_simulation.h" + +using namespace dab; +using namespace dab::flock; + +ClearSimulationEvent::ClearSimulationEvent() +: event::Event(0.0, -1.0, event::RelativeTime) +{} + +ClearSimulationEvent::ClearSimulationEvent(double pTime) +: event::Event(pTime, -1.0, event::RelativeTime) +{} + +ClearSimulationEvent::ClearSimulationEvent( const ClearSimulationEvent& pEvent ) +: event::Event( pEvent ) +{} + +ClearSimulationEvent::ClearSimulationEvent( double pTime, const ClearSimulationEvent& pEvent ) +: event::Event( pTime, pEvent ) +{} + +ClearSimulationEvent::~ClearSimulationEvent() +{} + +event::Event* +ClearSimulationEvent::copy() const +{ + return new ClearSimulationEvent( *this ); +} + +event::Event* +ClearSimulationEvent::copy( double pTime ) const +{ + return new ClearSimulationEvent( pTime, *this ); +} + +void +ClearSimulationEvent::execute() throw (Exception) +{ + mStarted = true; + mFinished = false; + + try + { + //std::cout << "ClearSimulationEvent::execute() begin\n"; + + Simulation::get().clear(); + + //std::cout << "ClearSimulationEvent::execute() end\n"; + } + catch( Exception& e ) + { + Simulation::get().exceptionReport( e ); + } + + mStarted = false; + mFinished = true; +} \ No newline at end of file diff --git a/src/dab_flock_clear_simulation_event.h b/src/dab_flock_clear_simulation_event.h new file mode 100644 index 0000000..d7467ef --- /dev/null +++ b/src/dab_flock_clear_simulation_event.h @@ -0,0 +1,40 @@ +/** \file dab_flock_clear_simulation_event.h + * + * Created by Daniel Bisig on 5/20/10. + * Ported to OpenFrameworks by Daniel Bisig on 11/10/2017. + */ + +#ifndef _dab_flock_clear_simulation_event_h_ +#define _dab_flock_clear_simulation_event_h_ + +#include "dab_flock_simulation.h" +#include "dab_flock_swarm.h" +#include "dab_event.h" + +namespace dab +{ + +namespace flock +{ + +class ClearSimulationEvent : public event::Event +{ +public: + ClearSimulationEvent(); + ClearSimulationEvent(double pTime); + ClearSimulationEvent( const ClearSimulationEvent& pEvent ); + ClearSimulationEvent( double pTime, const ClearSimulationEvent& pEvent ); + virtual ~ClearSimulationEvent(); + + event::Event* copy() const; + event::Event* copy( double pTime ) const; + void execute() throw (Exception); + +protected: +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_cohesion_behavior.cpp b/src/dab_flock_cohesion_behavior.cpp new file mode 100644 index 0000000..5f0fc66 --- /dev/null +++ b/src/dab_flock_cohesion_behavior.cpp @@ -0,0 +1,150 @@ +/** \file dab_flock_cohesion_behavior.cpp + */ + +#include "dab_flock_cohesion_behavior.h" +#include "dab_flock_parameter.h" +#include "dab_flock_agent.h" +#include "dab_space_neighbor_relation.h" + +using namespace dab; +using namespace dab::flock; + +CohesionBehavior::CohesionBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "CohesionBehavior"; +} + +CohesionBehavior::CohesionBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "CohesionBehavior"; + + if( mInputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mInputNeighborGroups.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputNeighborGroups.size()) + " neighbor groups supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + + // input parameter + mPositionPar = mInputParameters[0]; + + // output parameter + mForcePar = mOutputParameters[0]; + + // create internal parameters + mMinDistPar = createInternalParameter("minDist", { 0.0f } ); + mMaxDistPar = createInternalParameter("maxDist", { 0.5f } ); + mAmountPar = createInternalParameter("amount", { 0.1f } ); + + // input neighbor groups + mPositionNeighbors = mInputNeighborGroups[0]; + + //std::cout << "cohesion neighbors: " << mPositionNeighbors->name().toStdString() << "\n"; + + // remaining stuff + unsigned int dim = mForcePar->dim(); + mAvgDirection.resize(dim, 1); + mTmpForce.resize(dim, 1); +} + +CohesionBehavior::~CohesionBehavior() +{} + +Behavior* +CohesionBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new CohesionBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new CohesionBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +CohesionBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new CohesionBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +CohesionBehavior::act() +{ + //std::cout << "CohesionBehavior::act() begin\n"; + + //std::cout << "CohesionBehavior begin: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& position = mPositionPar->values(); + space::NeighborGroup& positionNeighbors = *mPositionNeighbors; + Eigen::VectorXf& force = mForcePar->backupValues(); + float& minDist = mMinDistPar->value(); + float& maxDist = mMaxDistPar->value(); + float& amount = mAmountPar->value(); + + Eigen::VectorXf& avgDirection = mAvgDirection; + Eigen::VectorXf& tmpForce = mTmpForce; + + unsigned int totalNeighborCount = positionNeighbors.neighborCount(); + + unsigned int neighborCount = 0; + + //std::cout << "cohesion agent " << mAgent->name().toStdString() << " pos " << position << " neighborCount " << totalNeighborCount << "\n"; + + if(totalNeighborCount == 0) return; + + float distance; + float avgDistance; + float scale; + + avgDirection.setConstant(0.0); + + for(unsigned int i=0; iname().toStdString() << " pos " << position << " neighbor pos " << positionNeighbors.neighbor(i)->position() << " distance " << positionNeighbors.distance(i) << " minDist " << minDist << " maxDist " << maxDist << "\n"; + + //std::cout << " neighbor direction " << direction << "\n"; + + if(minDist > 0.0 && distance < minDist) continue; + if(maxDist > 0.0 && distance > maxDist) continue; + + avgDirection += direction; + neighborCount++; + + //std::cout << "agent " << mAgent->name().toStdString() << " light " << ( static_cast( positionNeighbors.neighbor(i) ) )->agent()->name().toStdString() << " " << positionNeighbors.neighbor(i)->position() << "\n"; + } + + if(neighborCount == 0) return; + + avgDirection /= static_cast(neighborCount); + + avgDistance = avgDirection.norm(); + if(maxDist > 0.0 && minDist > 0.0) scale = (avgDistance - minDist) / (maxDist - minDist); + else scale = 1.0; + + tmpForce = avgDirection; + + tmpForce.normalize(); + tmpForce *= scale; + tmpForce *= amount; + + //std::cout << "force " << tmpForce << "\n"; + + force += tmpForce; + + //std::cout << "CohesionBehavior::act() end\n"; +} \ No newline at end of file diff --git a/src/dab_flock_cohesion_behavior.h b/src/dab_flock_cohesion_behavior.h new file mode 100644 index 0000000..803ce87 --- /dev/null +++ b/src/dab_flock_cohesion_behavior.h @@ -0,0 +1,99 @@ +/** \file dab_flock_cohesion_behavior.h + * \class dab::flock::CohesionBehavior cause Agent to move towards center position of their neigbhors + * \brief cause Agent to move towards center position of their neigbhors + * + * The Behavior causes Agent to move towards center position of their neigbhors\n + * Input Parameter:\n + * type: position dim: nD neighbors: required\n + * \n + * Output Parameter:\n + * type: force dim: nD write: add\n + * \n + * Internal Parameter:\n + * name: xxx_minDist dim: 1D defaultValue: 0.0\n + * name: xxx_maxDist dim: 1D defaultValue: 0.5\n + * name: xxx_amount dim: 1D defaultValue: 0.1\n + * name: xxx_active dim: 1D defaultValue: 1.0\n + * \n + * Created by Daniel Bisig on 4/21/07. + * Ported to OpenFrameworks by Daniel Bisig on 13/10/2017. + */ + +#ifndef _dab_flock_cohesion_behavior_h_ +#define _dab_flock_cohesion_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class Agent; + +class CohesionBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + CohesionBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + CohesionBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~CohesionBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mPositionPar; /// \brief position parameter (input) + Parameter* mForcePar; /// \brief force parameter (output) + Parameter* mMinDistPar; /// \brief minimum distance parameter (internal) + Parameter* mMaxDistPar; /// \brief maximum distance parameter (internal) + Parameter* mAmountPar; /// \brief behaviour amount parameter (internal) + space::NeighborGroup* mPositionNeighbors; /// \brief position neighbor group + + Eigen::VectorXf mAvgDirection; /// \brief avg of neighboring value directions + Eigen::VectorXf mTmpForce; /// \brief temporary force +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_com.cpp b/src/dab_flock_com.cpp new file mode 100644 index 0000000..67a338c --- /dev/null +++ b/src/dab_flock_com.cpp @@ -0,0 +1,2068 @@ +/** \file dab_flock_com.cpp +*/ + +#include "dab_flock_com.h" +#include "dab_flock_simulation.h" +#include "dab_flock_swarm.h" +#include "dab_flock_parameter.h" +#include "dab_flock_osc_control.h" +#include "dab_exception.h" +#include "dab_osc_messenger.h" +#include "dab_osc_sender.h" + +using namespace dab; +using namespace dab::flock; + +#pragma mark parameter communication registration + +ParameterRegistration::ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval) + : mSwarmName(pSwarmName) + , mParameterName(pParameterName) + , mSenderName(pSenderName) + , mSendInterval(pSendInterval) + , mCurrentSendInterval(mSendInterval) + , mAgentRange({ -1, -1 }) + , mAgentGroupSize(1) + , mNormalise(false) + , mMaskValues(false) +{ +} + +ParameterRegistration::ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception) + : mSwarmName(pSwarmName) + , mParameterName(pParameterName) + , mSenderName(pSenderName) + , mSendInterval(pSendInterval) + , mCurrentSendInterval(mSendInterval) + , mAgentRange({ -1, -1 }) + , mAgentGroupSize(1) + , mNormalise(true) + , mMinParValue(pMinParValue) + , mMaxParValue(pMaxParValue) + , mParValueScale(pMaxParValue - pMinParValue) + , mParValueOffset(pMinParValue) + , mMaskValues(false) +{ + if (pMinParValue.rows() != pMaxParValue.rows()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of max value " + std::to_string(pMaxParValue.rows()), __FILE__, __FUNCTION__, __LINE__); + + unsigned int dim = mParValueScale.rows(); + for (unsigned int d = 0; d& pAgentRange) throw (Exception) + : mSwarmName(pSwarmName) + , mParameterName(pParameterName) + , mSenderName(pSenderName) + , mSendInterval(pSendInterval) + , mCurrentSendInterval(mSendInterval) + , mAgentRange(pAgentRange) + , mAgentGroupSize(1) + , mNormalise(false) + , mMaskValues(false) +{ + if (pAgentRange[1] >= 0 && pAgentRange[0] > pAgentRange[1]) throw Exception("FLOCK ERROR: illegal agent range, min value " + std::to_string(pAgentRange[0]) + " exceeds max value " + std::to_string(pAgentRange[1]), __FILE__, __FUNCTION__, __LINE__); +} + +ParameterRegistration::ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const std::array& pAgentRange, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception) + : mSwarmName(pSwarmName) + , mParameterName(pParameterName) + , mSenderName(pSenderName) + , mSendInterval(pSendInterval) + , mCurrentSendInterval(mSendInterval) + , mAgentRange(pAgentRange) + , mAgentGroupSize(1) + , mNormalise(true) + , mMinParValue(pMinParValue) + , mMaxParValue(pMaxParValue) + , mParValueScale(pMaxParValue - pMinParValue) + , mParValueOffset(pMinParValue) + , mMaskValues(false) +{ + if (pAgentRange[1] >= 0 && pAgentRange[0] > pAgentRange[1]) throw Exception("FLOCK ERROR: illegal agent range, min value " + std::to_string(pAgentRange[0]) + " exceeds max value " + std::to_string(pAgentRange[1]), __FILE__, __FUNCTION__, __LINE__); + if (pMinParValue.rows() != pMaxParValue.rows()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of max value " + std::to_string(pMaxParValue.rows()), __FILE__, __FUNCTION__, __LINE__); + + unsigned int dim = mParValueScale.rows(); + for (unsigned int d = 0; d& pAgentRange, unsigned int pAgentGroupSize) throw (Exception) + : mSwarmName(pSwarmName) + , mParameterName(pParameterName) + , mSenderName(pSenderName) + , mSendInterval(pSendInterval) + , mCurrentSendInterval(mSendInterval) + , mAgentRange(pAgentRange) + , mAgentGroupSize(pAgentGroupSize) + , mNormalise(false) + , mMaskValues(false) +{ + if (pAgentRange[1] >= 0 && pAgentRange[0] > pAgentRange[1]) throw Exception("FLOCK ERROR: illegal agent range, min value " + std::to_string(pAgentRange[0]) + " exceeds max value " + std::to_string(pAgentRange[1]), __FILE__, __FUNCTION__, __LINE__); +} + +ParameterRegistration::ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const std::array& pAgentRange, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception) + : mSwarmName(pSwarmName) + , mParameterName(pParameterName) + , mSenderName(pSenderName) + , mSendInterval(pSendInterval) + , mCurrentSendInterval(mSendInterval) + , mAgentRange(pAgentRange) + , mAgentGroupSize(pAgentGroupSize) + , mNormalise(true) + , mMinParValue(pMinParValue) + , mMaxParValue(pMaxParValue) + , mParValueScale(pMaxParValue - pMinParValue) + , mParValueOffset(pMinParValue) + , mMaskValues(false) +{ + if (pAgentRange[1] >= 0 && pAgentRange[0] > pAgentRange[1]) throw Exception("FLOCK ERROR: illegal agent range, min value " + std::to_string(pAgentRange[0]) + " exceeds max value " + std::to_string(pAgentRange[1]), __FILE__, __FUNCTION__, __LINE__); + if (pMinParValue.rows() != pMaxParValue.rows()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of max value " + std::to_string(pMaxParValue.rows()), __FILE__, __FUNCTION__, __LINE__); + + unsigned int dim = mParValueScale.rows(); + for (unsigned int d = 0; d& pParValueMask) + : mSwarmName(pSwarmName) + , mParameterName(pParameterName) + , mSenderName(pSenderName) + , mSendInterval(pSendInterval) + , mCurrentSendInterval(mSendInterval) + , mAgentRange({ -1, -1 }) + , mAgentGroupSize(1) + , mNormalise(false) + , mMaskValues(true) + , mParValueMask(pParValueMask) +{ +} + +ParameterRegistration::ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception) + : mSwarmName(pSwarmName) + , mParameterName(pParameterName) + , mSenderName(pSenderName) + , mSendInterval(pSendInterval) + , mCurrentSendInterval(mSendInterval) + , mAgentRange({ -1, -1 }) + , mAgentGroupSize(1) + , mNormalise(true) + , mMinParValue(pMinParValue) + , mMaxParValue(pMaxParValue) + , mParValueScale(pMaxParValue - pMinParValue) + , mParValueOffset(pMinParValue) + , mMaskValues(true) + , mParValueMask(pParValueMask) +{ + if (pMinParValue.rows() != pMaxParValue.rows()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of max value " + std::to_string(pMaxParValue.rows()), __FILE__, __FUNCTION__, __LINE__); + if (pMinParValue.rows() != mParValueMask.size()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of mask value " + std::to_string(pParValueMask.size()), __FILE__, __FUNCTION__, __LINE__); + + unsigned int dim = mParValueScale.rows(); + for (unsigned int d = 0; d& pAgentRange, const std::vector& pParValueMask) throw (Exception) + : mSwarmName(pSwarmName) + , mParameterName(pParameterName) + , mSenderName(pSenderName) + , mSendInterval(pSendInterval) + , mCurrentSendInterval(mSendInterval) + , mAgentRange(pAgentRange) + , mAgentGroupSize(1) + , mNormalise(false) + , mMaskValues(true) + , mParValueMask(pParValueMask) +{ + if (pAgentRange[1] >= 0 && pAgentRange[0] > pAgentRange[1]) throw Exception("FLOCK ERROR: illegal agent range, min value " + std::to_string(pAgentRange[0]) + " exceeds max value " + std::to_string(pAgentRange[1]), __FILE__, __FUNCTION__, __LINE__); +} + +ParameterRegistration::ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const std::array& pAgentRange, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception) + : mSwarmName(pSwarmName) + , mParameterName(pParameterName) + , mSenderName(pSenderName) + , mSendInterval(pSendInterval) + , mCurrentSendInterval(mSendInterval) + , mAgentRange(pAgentRange) + , mAgentGroupSize(1) + , mNormalise(true) + , mMinParValue(pMinParValue) + , mMaxParValue(pMaxParValue) + , mParValueScale(pMaxParValue - pMinParValue) + , mParValueOffset(pMinParValue) + , mMaskValues(true) + , mParValueMask(pParValueMask) +{ + if (pAgentRange[1] >= 0 && pAgentRange[0] > pAgentRange[1]) throw Exception("FLOCK ERROR: illegal agent range, min value " + std::to_string(pAgentRange[0]) + " exceeds max value " + std::to_string(pAgentRange[1]), __FILE__, __FUNCTION__, __LINE__); + if (pMinParValue.rows() != pMaxParValue.rows()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of max value " + std::to_string(pMaxParValue.rows()), __FILE__, __FUNCTION__, __LINE__); + if (pMinParValue.rows() != mParValueMask.size()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of mask value " + std::to_string(pParValueMask.size()), __FILE__, __FUNCTION__, __LINE__); + + unsigned int dim = mParValueScale.rows(); + for (unsigned int d = 0; d& pParValueMask) + : mSwarmName(pSwarmName) + , mParameterName(pParameterName) + , mSenderName(pSenderName) + , mSendInterval(pSendInterval) + , mCurrentSendInterval(mSendInterval) + , mAgentRange({ -1, -1 }) + , mAgentGroupSize(pAgentGroupSize) + , mNormalise(false) + , mMaskValues(true) + , mParValueMask(pParValueMask) +{} + +ParameterRegistration::ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception) + : mSwarmName(pSwarmName) + , mParameterName(pParameterName) + , mSenderName(pSenderName) + , mSendInterval(pSendInterval) + , mCurrentSendInterval(mSendInterval) + , mAgentRange({ -1, -1 }) + , mAgentGroupSize(pAgentGroupSize) + , mNormalise(true) + , mMinParValue(pMinParValue) + , mMaxParValue(pMaxParValue) + , mParValueScale(pMaxParValue - pMinParValue) + , mParValueOffset(pMinParValue) + , mMaskValues(true) + , mParValueMask(pParValueMask) +{ + if (pMinParValue.rows() != pMaxParValue.rows()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of max value " + std::to_string(pMaxParValue.rows()), __FILE__, __FUNCTION__, __LINE__); + if (pMinParValue.rows() != mParValueMask.size()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of mask value " + std::to_string(pParValueMask.size()), __FILE__, __FUNCTION__, __LINE__); + + unsigned int dim = mParValueScale.rows(); + for (unsigned int d = 0; d& pAgentRange, unsigned int pAgentGroupSize, const std::vector& pParValueMask) throw (Exception) + : mSwarmName(pSwarmName) + , mParameterName(pParameterName) + , mSenderName(pSenderName) + , mSendInterval(pSendInterval) + , mCurrentSendInterval(mSendInterval) + , mAgentRange(pAgentRange) + , mAgentGroupSize(pAgentGroupSize) + , mNormalise(false) + , mMaskValues(true) + , mParValueMask(pParValueMask) +{ + if (pAgentRange[1] >= 0 && pAgentRange[0] > pAgentRange[1]) throw Exception("FLOCK ERROR: illegal agent range, min value " + std::to_string(pAgentRange[0]) + " exceeds max value " + std::to_string(pAgentRange[1]), __FILE__, __FUNCTION__, __LINE__); +} + +ParameterRegistration::ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const std::array& pAgentRange, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception) + : mSwarmName(pSwarmName) + , mParameterName(pParameterName) + , mSenderName(pSenderName) + , mSendInterval(pSendInterval) + , mCurrentSendInterval(mSendInterval) + , mAgentRange(pAgentRange) + , mAgentGroupSize(pAgentGroupSize) + , mNormalise(true) + , mMinParValue(pMinParValue) + , mMaxParValue(pMaxParValue) + , mParValueScale(pMaxParValue - pMinParValue) + , mParValueOffset(pMinParValue) + , mMaskValues(true) + , mParValueMask(pParValueMask) +{ + if (pAgentRange[1] >= 0 && pAgentRange[0] > pAgentRange[1]) throw Exception("FLOCK ERROR: illegal agent range, min value " + std::to_string(pAgentRange[0]) + " exceeds max value " + std::to_string(pAgentRange[1]), __FILE__, __FUNCTION__, __LINE__); + if (pMinParValue.rows() != pMaxParValue.rows()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of max value " + std::to_string(pMaxParValue.rows()), __FILE__, __FUNCTION__, __LINE__); + if (pMinParValue.rows() != mParValueMask.size()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of mask value " + std::to_string(pParValueMask.size()), __FILE__, __FUNCTION__, __LINE__); + + unsigned int dim = mParValueScale.rows(); + for (unsigned int d = 0; d& pAgentRange) throw (Exception) +{ + if (pAgentRange[1] >= 0 && pAgentRange[0] > pAgentRange[1]) throw Exception("FLOCK ERROR: illegal agent range, min value " + std::to_string(pAgentRange[0]) + " exceeds max value " + std::to_string(pAgentRange[1]), __FILE__, __FUNCTION__, __LINE__); + + mSendInterval = pSendInterval; + mCurrentSendInterval = mSendInterval; + mAgentRange = pAgentRange; + mAgentGroupSize = 1; + mNormalise = false; + mMaskValues = false; +} + +void +ParameterRegistration::set(unsigned int pSendInterval, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception) +{ + if (pMinParValue.rows() != pMaxParValue.rows()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of max value " + std::to_string(pMaxParValue.rows()), __FILE__, __FUNCTION__, __LINE__); + + mSendInterval = pSendInterval; + mCurrentSendInterval = mSendInterval; + mAgentRange = { -1, -1 }; + mAgentGroupSize = 1; + mNormalise = true; + mMinParValue = pMinParValue; + mMaxParValue = pMaxParValue; + mParValueScale = pMaxParValue - pMinParValue; + mParValueOffset = pMinParValue; + mMaskValues = false; + + unsigned int dim = mParValueScale.rows(); + for (unsigned int d = 0; d& pAgentRange, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception) +{ + if (pAgentRange[1] >= 0 && pAgentRange[0] > pAgentRange[1]) throw Exception("FLOCK ERROR: illegal agent range, min value " + std::to_string(pAgentRange[0]) + " exceeds max value " + std::to_string(pAgentRange[1]), __FILE__, __FUNCTION__, __LINE__); + if (pMinParValue.rows() != pMaxParValue.rows()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of max value " + std::to_string(pMaxParValue.rows()), __FILE__, __FUNCTION__, __LINE__); + + mSendInterval = pSendInterval; + mCurrentSendInterval = mSendInterval; + mAgentRange = pAgentRange; + mAgentGroupSize = 1; + mNormalise = true; + mMinParValue = pMinParValue; + mMaxParValue = pMaxParValue; + mParValueScale = pMaxParValue - pMinParValue; + mParValueOffset = pMinParValue; + mMaskValues = false; + + unsigned int dim = mParValueScale.rows(); + for (unsigned int d = 0; d& pAgentRange, unsigned int pAgentGroupSize) throw (Exception) +{ + if (pAgentRange[1] >= 0 && pAgentRange[0] > pAgentRange[1]) throw Exception("FLOCK ERROR: illegal agent range, min value " + std::to_string(pAgentRange[0]) + " exceeds max value " + std::to_string(pAgentRange[1]), __FILE__, __FUNCTION__, __LINE__); + + mSendInterval = pSendInterval; + mCurrentSendInterval = mSendInterval; + mAgentRange = pAgentRange; + mAgentGroupSize = pAgentGroupSize; + mNormalise = false; + mMaskValues = false; +} + +void +ParameterRegistration::set(unsigned int pSendInterval, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception) +{ + if (pMinParValue.rows() != pMaxParValue.rows()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of max value " + std::to_string(pMaxParValue.rows()), __FILE__, __FUNCTION__, __LINE__); + + mSendInterval = pSendInterval; + mCurrentSendInterval = mSendInterval; + mAgentRange = { -1, -1 }; + mAgentGroupSize = pAgentGroupSize; + mNormalise = true; + mMinParValue = pMinParValue; + mMaxParValue = pMaxParValue; + mParValueScale = pMaxParValue - pMinParValue; + mParValueOffset = pMinParValue; + mMaskValues = false; + + unsigned int dim = mParValueScale.rows(); + for (unsigned int d = 0; d& pAgentRange, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception) +{ + if (pAgentRange[1] >= 0 && pAgentRange[0] > pAgentRange[1]) throw Exception("FLOCK ERROR: illegal agent range, min value " + std::to_string(pAgentRange[0]) + " exceeds max value " + std::to_string(pAgentRange[1]), __FILE__, __FUNCTION__, __LINE__); + if (pMinParValue.rows() != pMaxParValue.rows()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of max value " + std::to_string(pMaxParValue.rows()), __FILE__, __FUNCTION__, __LINE__); + + mSendInterval = pSendInterval; + mCurrentSendInterval = mSendInterval; + mAgentRange = pAgentRange; + mAgentGroupSize = pAgentGroupSize; + mNormalise = true; + mMinParValue = pMinParValue; + mMaxParValue = pMaxParValue; + mParValueScale = pMaxParValue - pMinParValue; + mParValueOffset = pMinParValue; + mMaskValues = false; + + unsigned int dim = mParValueScale.rows(); + for (unsigned int d = 0; d& pParValueMask) +{ + mSendInterval = pSendInterval; + mCurrentSendInterval = mSendInterval; + mAgentRange = { -1, -1 }; + mAgentGroupSize = 1; + mNormalise = false; + mParValueMask = pParValueMask; + mMaskValues = true; +} + +void +ParameterRegistration::set(unsigned int pSendInterval, const std::array& pAgentRange, const std::vector& pParValueMask) throw (Exception) +{ + if (pAgentRange[1] >= 0 && pAgentRange[0] > pAgentRange[1]) throw Exception("FLOCK ERROR: illegal agent range, min value " + std::to_string(pAgentRange[0]) + " exceeds max value " + std::to_string(pAgentRange[1]), __FILE__, __FUNCTION__, __LINE__); + + mSendInterval = pSendInterval; + mCurrentSendInterval = mSendInterval; + mAgentRange = pAgentRange; + mAgentGroupSize = 1; + mNormalise = false; + mParValueMask = pParValueMask; + mMaskValues = true; +} + +void +ParameterRegistration::set(unsigned int pSendInterval, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception) +{ + if (pMinParValue.rows() != pMaxParValue.rows()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of max value " + std::to_string(pMaxParValue.rows()), __FILE__, __FUNCTION__, __LINE__); + if (pMinParValue.rows() != mParValueMask.size()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of mask value " + std::to_string(pParValueMask.size()), __FILE__, __FUNCTION__, __LINE__); + + mSendInterval = pSendInterval; + mCurrentSendInterval = mSendInterval; + mAgentRange = { -1, -1 }; + mAgentGroupSize = 1; + mNormalise = true; + mMinParValue = pMinParValue; + mMaxParValue = pMaxParValue; + mParValueScale = pMaxParValue - pMinParValue; + mParValueOffset = pMinParValue; + mParValueMask = pParValueMask; + mMaskValues = true; + + unsigned int dim = mParValueScale.rows(); + for (unsigned int d = 0; d& pAgentRange, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception) +{ + if (pAgentRange[1] >= 0 && pAgentRange[0] > pAgentRange[1]) throw Exception("FLOCK ERROR: illegal agent range, min value " + std::to_string(pAgentRange[0]) + " exceeds max value " + std::to_string(pAgentRange[1]), __FILE__, __FUNCTION__, __LINE__); + if (pMinParValue.rows() != pMaxParValue.rows()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of max value " + std::to_string(pMaxParValue.rows()), __FILE__, __FUNCTION__, __LINE__); + if (pMinParValue.rows() != mParValueMask.size()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of mask value " + std::to_string(pParValueMask.size()), __FILE__, __FUNCTION__, __LINE__); + + mSendInterval = pSendInterval; + mCurrentSendInterval = mSendInterval; + mAgentRange = pAgentRange; + mAgentGroupSize = 1; + mNormalise = true; + mMinParValue = pMinParValue; + mMaxParValue = pMaxParValue; + mParValueScale = pMaxParValue - pMinParValue; + mParValueOffset = pMinParValue; + mParValueMask = pParValueMask; + mMaskValues = true; + + unsigned int dim = mParValueScale.rows(); + for (unsigned int d = 0; d& pParValueMask) +{ + mSendInterval = pSendInterval; + mCurrentSendInterval = mSendInterval; + mAgentRange = { -1, -1 }; + mAgentGroupSize = pAgentGroupSize; + mNormalise = false; + mParValueMask = pParValueMask; + mMaskValues = true; +} + +void +ParameterRegistration::set(unsigned int pSendInterval, const std::array& pAgentRange, unsigned int pAgentGroupSize, const std::vector& pParValueMask) throw (Exception) +{ + if (pAgentRange[1] >= 0 && pAgentRange[0] > pAgentRange[1]) throw Exception("FLOCK ERROR: illegal agent range, min value " + std::to_string(pAgentRange[0]) + " exceeds max value " + std::to_string(pAgentRange[1]), __FILE__, __FUNCTION__, __LINE__); + + mSendInterval = pSendInterval; + mCurrentSendInterval = mSendInterval; + mAgentRange = pAgentRange; + mAgentGroupSize = pAgentGroupSize; + mNormalise = false; + mParValueMask = pParValueMask; + mMaskValues = true; +} + +void +ParameterRegistration::set(unsigned int pSendInterval, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception) +{ + if (pMinParValue.rows() != pMaxParValue.rows()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of max value " + std::to_string(pMaxParValue.rows()), __FILE__, __FUNCTION__, __LINE__); + if (pMinParValue.rows() != mParValueMask.size()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of mask value " + std::to_string(pParValueMask.size()), __FILE__, __FUNCTION__, __LINE__); + + mSendInterval = pSendInterval; + mCurrentSendInterval = mSendInterval; + mAgentRange = { -1, -1 }; + mAgentGroupSize = pAgentGroupSize; + mNormalise = true; + mMinParValue = pMinParValue; + mMaxParValue = pMaxParValue; + mParValueScale = pMaxParValue - pMinParValue; + mParValueOffset = pMinParValue; + mParValueMask = pParValueMask; + mMaskValues = true; + + unsigned int dim = mParValueScale.rows(); + for (unsigned int d = 0; d& pAgentRange, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception) +{ + if (pAgentRange[1] >= 0 && pAgentRange[0] > pAgentRange[1]) throw Exception("FLOCK ERROR: illegal agent range, min value " + std::to_string(pAgentRange[0]) + " exceeds max value " + std::to_string(pAgentRange[1]), __FILE__, __FUNCTION__, __LINE__); + if (pMinParValue.rows() != pMaxParValue.rows()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of max value " + std::to_string(pMaxParValue.rows()), __FILE__, __FUNCTION__, __LINE__); + if (pMinParValue.rows() != mParValueMask.size()) throw Exception("FLOCK ERROR: dim of min value " + std::to_string(pMinParValue.rows()) + " doesn't match dim of mask value " + std::to_string(pParValueMask.size()), __FILE__, __FUNCTION__, __LINE__); + + mSendInterval = pSendInterval; + mCurrentSendInterval = mSendInterval; + mAgentRange = pAgentRange; + mAgentGroupSize = pAgentGroupSize; + mNormalise = true; + mMinParValue = pMinParValue; + mMaxParValue = pMaxParValue; + mParValueScale = pMaxParValue - pMinParValue; + mParValueOffset = pMinParValue; + mParValueMask = pParValueMask; + mMaskValues = true; + + unsigned int dim = mParValueScale.rows(); + for (unsigned int d = 0; d& +ParameterRegistration::agentRange() const +{ + return mAgentRange; +} + +unsigned int +ParameterRegistration::agentGroupSize() const +{ + return mAgentGroupSize; +} + +bool +ParameterRegistration::normalise() const +{ + return mNormalise; +} + +const Eigen::VectorXf& +ParameterRegistration::minParValue()const +{ + return mMinParValue; +} + +const Eigen::VectorXf& +ParameterRegistration::maxParValue()const +{ + return mMaxParValue; +} + +const Eigen::VectorXf& +ParameterRegistration::parValueScale() const +{ + return mParValueScale; +} + +const Eigen::VectorXf& +ParameterRegistration::parValueOffset() const +{ + return mParValueOffset; +} + +bool +ParameterRegistration::maskValues() const +{ + return mMaskValues; +} + +const std::vector& +ParameterRegistration::parValueMask() const +{ + return mParValueMask; +} + +bool +ParameterRegistration::operator==(const ParameterRegistration& pRegistration) const +{ + return match(pRegistration.mSwarmName, pRegistration.mParameterName); +} + +bool +ParameterRegistration::match(const std::string& pSwarmName, const std::string& pParameterName) const +{ + return (mSwarmName == pSwarmName && mParameterName == pParameterName); +} + +#pragma mark flock messenger + +FlockCom::FlockCom() + : OscMessenger() +{} + +FlockCom::~FlockCom() +{ + // delete all parameter registrations + std::map< std::shared_ptr, std::vector >& parameterMap = mParameterRegistry.map(); + + for (auto iter = parameterMap.begin(); iter != parameterMap.end(); ++iter) + { + std::vector& parameterRegistration = iter->second; + + int regCount = parameterRegistration.size(); + + for (int rI = 0; rI(new OscSender("ErrorSender", pSenderIP, pSenderPort)); + mControlReceiver = std::shared_ptr(new OscReceiver("ControlReceiver", pReceiverPort)); + mOscControl = std::shared_ptr(new OscControl(mErrorSender)); + mOscControl->setErrorSender(mErrorSender); + mControlReceiver->registerOscListener(mOscControl); + mControlReceiver->start(); + + } + catch (Exception& e) + { + throw; + } +} + +void +FlockCom::createOscControl(std::shared_ptr pOscControl, unsigned int pReceiverPort, const std::string& pSenderIP, unsigned int pSenderPort) throw (Exception) +{ + try + { + mErrorSender = std::shared_ptr(new OscSender("ErrorSender", pSenderIP, pSenderPort)); + mControlReceiver = std::shared_ptr(new OscReceiver("ControlReceiver", pReceiverPort)); + mOscControl = pOscControl; + mOscControl->setErrorSender(mErrorSender); + mControlReceiver->registerOscListener(pOscControl); + mControlReceiver->start(); + } + catch (Exception& e) + { + throw; + } +} + +bool +FlockCom::checkParameterRegistration(std::shared_ptr pSender, const std::string& pSwarmName, const std::string& pParameterName) +{ + //std::cout << "FlockCom::checkParameterRegistration()\n"; + if (mParameterRegistry.contains(pSender) == false) return false; + std::vector< ParameterRegistration* >& regs = mParameterRegistry[pSender]; + + unsigned int regCount = regs.size(); + for (unsigned int rI = 0; rImatch(pSwarmName, pParameterName) == true) return true; + return false; +} + +ParameterRegistration* +FlockCom::parameterRegistration(std::shared_ptr pSender, const std::string& pSwarmName, const std::string& pParameterName) throw (Exception) +{ + //std::cout << "FlockCom::parameterRegistration\n"; + + if (mParameterRegistry.contains(pSender) == false) throw Exception("FLOCK ERROR: sender " + pSender->name() + " does not exist", __FILE__, __FUNCTION__, __LINE__); + std::vector< ParameterRegistration* >& regs = mParameterRegistry[pSender]; + + unsigned int regCount = regs.size(); + for (unsigned int rI = 0; rImatch(pSwarmName, pParameterName) == true) + { + return regs[rI]; + } + + throw Exception("FLOCK ERROR: parameter " + pParameterName + " of swarm " + pSwarmName + " not registered for sender " + pSender->name(), __FILE__, __FUNCTION__, __LINE__); +} + +std::vector< ParameterRegistration* > +FlockCom::parameterRegistrations(const std::string& pSwarmName, const std::string& pParameterName) const +{ + std::vector< ParameterRegistration* > result; + + const std::map< std::shared_ptr, std::vector >& parameterMap = mParameterRegistry.map(); + + for (auto iter = parameterMap.begin(); iter != parameterMap.end(); ++iter) + { + const std::vector& parRegs = iter->second; + + int regCount = parRegs.size(); + + for (int rI = 0; rIswarmName() == pSwarmName && parRegs[rI]->parameterName() == pParameterName) result.push_back(parRegs[rI]); + } + } + + return result; +} + +bool +FlockCom::checkParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName) +{ + if (checkSender(pSenderName) == false) return false; + + std::shared_ptr pSender = sender(pSenderName); + std::vector< ParameterRegistration* > regs = mParameterRegistry[pSender]; + + unsigned int regCount = regs.size(); + for (unsigned int rI = 0; rImatch(pSwarmName, pParameterName) == true) return true; + return false; +} + +void +FlockCom::createSender(const std::string& pSenderName, const std::string& pReceiverIP, unsigned int pReceiverPort, bool pExtendedOscMode) throw (Exception) +{ + try + { + std::shared_ptr _sender = OscMessenger::createSender(pSenderName, pReceiverIP, pReceiverPort); + + mExtendedOscMode.add(_sender, pExtendedOscMode); + mParameterRegistry.add(_sender, std::vector()); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::removeSender(const std::string& pSenderName) throw (dab::Exception) +{ + try + { + //std::cout << "removeSender name " << pSenderName.toStdString() << " begin\n"; + + std::shared_ptr _sender = sender(pSenderName); + + mParameterRegistry.remove(_sender); + mExtendedOscMode.remove(_sender); + + OscMessenger::removeSender(pSenderName); + + //std::cout << "removeSender name " << pSenderName.toStdString() << " end\n"; + } + catch (dab::Exception& e) + { + throw; + } +} + +void +FlockCom::removeSenders() +{ + std::map >& senderMap = mSenders.map(); + for (auto iter = senderMap.begin(); iter != senderMap.end(); ++iter) + { + std::shared_ptr _sender = iter->second; + + mParameterRegistry.remove(_sender); + mExtendedOscMode.remove(_sender); + } + + OscMessenger::removeSenders(); +} + +bool +FlockCom::extendedOscMode(const std::string& pSenderName) throw (Exception) +{ + try + { + std::shared_ptr _sender = sender(pSenderName); + return mExtendedOscMode[_sender]; + } + catch (Exception& e) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName) throw (dab::Exception) +{ + try + { + registerParameter(pSenderName, 0, pSwarmName, pParameterName, 1); + } + catch (dab::Exception&) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (dab::Exception) +{ + try + { + registerParameter(pSenderName, 0, pSwarmName, pParameterName, 1, pMinParValue, pMaxParValue); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange) throw (dab::Exception) +{ + try + { + registerParameter(pSenderName, 0, pSwarmName, pParameterName, pAgentRange, 1); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (dab::Exception) +{ + try + { + registerParameter(pSenderName, 0, pSwarmName, pParameterName, pAgentRange, 1, pMinParValue, pMaxParValue); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName) throw (dab::Exception) +{ + try + { + registerParameter(pSenderName, pSendInterval, pSwarmName, pParameterName, 1); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (dab::Exception) +{ + try + { + registerParameter(pSenderName, pSendInterval, pSwarmName, pParameterName, 1, pMinParValue, pMaxParValue); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange) throw (dab::Exception) +{ + try + { + registerParameter(pSenderName, pSendInterval, pSwarmName, pParameterName, pAgentRange, 1); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (dab::Exception) +{ + try + { + registerParameter(pSenderName, pSendInterval, pSwarmName, pParameterName, pAgentRange, 1, pMinParValue, pMaxParValue); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, unsigned int pAgentGroupSize) throw (dab::Exception) +{ + try + { + registerParameter(pSenderName, 0, pSwarmName, pParameterName, pAgentGroupSize); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (dab::Exception) +{ + try + { + registerParameter(pSenderName, 0, pSwarmName, pParameterName, pAgentGroupSize, pMinParValue, pMaxParValue); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, unsigned int pAgentGroupSize) throw (dab::Exception) +{ + try + { + registerParameter(pSenderName, 0, pSwarmName, pParameterName, pAgentRange, pAgentGroupSize); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (dab::Exception) +{ + try + { + registerParameter(pSenderName, 0, pSwarmName, pParameterName, pAgentRange, pAgentGroupSize, pMinParValue, pMaxParValue); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, unsigned int pAgentGroupSize) throw (dab::Exception) +{ + //std::cout << "FlockCom::registerParameter( " << pSenderName << ", " << pSwarmName << ", " << pParameterName << " )\n"; + + try + { + std::shared_ptr _sender = sender(pSenderName); + + if (checkParameterRegistration(_sender, pSwarmName, pParameterName) == true) + { + ParameterRegistration* parReg = parameterRegistration(_sender, pSwarmName, pParameterName); + parReg->set(pSendInterval, pAgentGroupSize); + } + else + { + mParameterRegistry[_sender].push_back(new ParameterRegistration(pSwarmName, pParameterName, pSenderName, pSendInterval, pAgentGroupSize)); + } + } + catch (dab::Exception& e) + { + e += dab::Exception("COM ERROR: failed to register parameter for sender " + pSenderName + " swarm " + pSwarmName + " parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__); + + throw e; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (dab::Exception) +{ + //std::cout << "FlockCom::registerParameter( " << pSenderName << ", " << pSwarmName << ", " << pParameterName << ", " << pMinParValue << ", " << pMaxParValue << " )\n"; + + //std::cout << "FlockCom::registerParameter( " << pSenderName << ", " << pSwarmName << ", " << pParameterName << " )\n"; + + try + { + std::shared_ptr _sender = sender(pSenderName); + + if (checkParameterRegistration(_sender, pSwarmName, pParameterName) == true) + { + ParameterRegistration* parReg = parameterRegistration(_sender, pSwarmName, pParameterName); + parReg->set(pSendInterval, pAgentGroupSize); + } + else + { + mParameterRegistry[_sender].push_back(new ParameterRegistration(pSwarmName, pParameterName, pSenderName, pSendInterval, pAgentGroupSize)); + } + } + catch (dab::Exception& e) + { + e += dab::Exception("COM ERROR: failed to register parameter for sender " + pSenderName + " swarm " + pSwarmName + " parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__); + + throw e; + } + + + + + try + { + std::shared_ptr _sender = sender(pSenderName); + + // // dirty fix + // if( checkParameterRegistration( snd , pSwarmName, pParameterName) == true ) return; + // // dirty fix end + + if (checkParameterRegistration(_sender, pSwarmName, pParameterName) == true) + { + ParameterRegistration* parReg = parameterRegistration(_sender, pSwarmName, pParameterName); + parReg->set(pSendInterval, pAgentGroupSize, pMinParValue, pMaxParValue); + } + else + { + mParameterRegistry[_sender].push_back(new ParameterRegistration(pSwarmName, pParameterName, pSenderName, pSendInterval, pAgentGroupSize, pMinParValue, pMaxParValue)); + } + } + catch (dab::Exception& e) + { + e += dab::Exception("COM ERROR: failed to register parameter for sender " + pSenderName + " swarm " + pSwarmName + " parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__); + + throw e; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, unsigned int pAgentGroupSize) throw (Exception) +{ + try + { + //std::cout << "FlockCom::registerParameter( pSenderName " << pSenderName.toStdString() << " , pSendInterval " << pSendInterval << " , pSwarmName " << pSwarmName.toStdString() << " , pParameterName " << pParameterName.toStdString() << " , pAgentRange " << pAgentRange << " )\n"; + + std::shared_ptr _sender = sender(pSenderName); + + // // dirty fix + // if( checkParameterRegistration( snd , pSwarmName, pParameterName) == true ) return; + // // dirty fix end + + if (checkParameterRegistration(_sender, pSwarmName, pParameterName) == true) + { + ParameterRegistration* parReg = parameterRegistration(_sender, pSwarmName, pParameterName); + parReg->set(pSendInterval, pAgentRange, pAgentGroupSize); + } + else + { + mParameterRegistry[_sender].push_back(new ParameterRegistration(pSwarmName, pParameterName, pSenderName, pSendInterval, pAgentRange, pAgentGroupSize)); + } + } + catch (dab::Exception& e) + { + e += dab::Exception("COM ERROR: failed to register parameter for sender " + pSenderName + " swarm " + pSwarmName + " parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__); + + throw e; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (dab::Exception) +{ + try + { + std::shared_ptr _sender = sender(pSenderName); + + // // dirty fix + // if( checkParameterRegistration( snd , pSwarmName, pParameterName) == true ) return; + // // dirty fix end + + if (checkParameterRegistration(_sender, pSwarmName, pParameterName) == true) + { + ParameterRegistration* parReg = parameterRegistration(_sender, pSwarmName, pParameterName); + parReg->set(pSendInterval, pAgentRange, pAgentGroupSize, pMinParValue, pMaxParValue); + } + else + { + mParameterRegistry[_sender].push_back(new ParameterRegistration(pSwarmName, pParameterName, pSenderName, pSendInterval, pAgentRange, pAgentGroupSize, pMinParValue, pMaxParValue)); + } + } + catch (dab::Exception& e) + { + e += dab::Exception("COM ERROR: failed to register parameter for sender " + pSenderName + " swarm " + pSwarmName + " parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__); + + throw e; + } +} + +// <<<<< + +void +FlockCom::registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::vector& pParValueMask) throw (dab::Exception) +{ + try + { + registerParameter(pSenderName, 0, pSwarmName, pParameterName, 1, pParValueMask); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception) +{ + try + { + registerParameter(pSenderName, 0, pSwarmName, pParameterName, 1, pMinParValue, pMaxParValue, pParValueMask); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const std::vector& pParValueMask) throw (Exception) +{ + try + { + registerParameter(pSenderName, 0, pSwarmName, pParameterName, pAgentRange, 1, pParValueMask); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception) +{ + try + { + registerParameter(pSenderName, 0, pSwarmName, pParameterName, pAgentRange, 1, pMinParValue, pMaxParValue, pParValueMask); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::vector& pParValueMask) throw (Exception) +{ + try + { + registerParameter(pSenderName, pSendInterval, pSwarmName, pParameterName, 1, pParValueMask); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception) +{ + try + { + registerParameter(pSenderName, pSendInterval, pSwarmName, pParameterName, 1, pMinParValue, pMaxParValue, pParValueMask); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const std::vector& pParValueMask) throw (Exception) +{ + try + { + registerParameter(pSenderName, pSendInterval, pSwarmName, pParameterName, pAgentRange, 1, pParValueMask); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception) +{ + try + { + registerParameter(pSenderName, pSendInterval, pSwarmName, pParameterName, pAgentRange, 1, pMinParValue, pMaxParValue, pParValueMask); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, unsigned int pAgentGroupSize, const std::vector& pParValueMask) throw (Exception) +{ + try + { + registerParameter(pSenderName, 0, pSwarmName, pParameterName, pAgentGroupSize, pParValueMask); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception) +{ + try + { + registerParameter(pSenderName, 0, pSwarmName, pParameterName, pAgentGroupSize, pMinParValue, pMaxParValue, pParValueMask); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, unsigned int pAgentGroupSize, const std::vector& pParValueMask) throw (Exception) +{ + try + { + registerParameter(pSenderName, 0, pSwarmName, pParameterName, pAgentRange, pAgentGroupSize, pParValueMask); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception) +{ + try + { + registerParameter(pSenderName, 0, pSwarmName, pParameterName, pAgentRange, pAgentGroupSize, pMinParValue, pMaxParValue, pParValueMask); + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, unsigned int pAgentGroupSize, const std::vector& pParValueMask) throw (Exception) +{ + //std::cout << "FlockCom::registerParameter( " << pSenderName.toStdString() << ", " << pSwarmName.toStdString() << ", " << pParameterName.toStdString() << " )\n"; + + try + { + std::shared_ptr _sender = sender(pSenderName); + + // // dirty fix + // if( checkParameterRegistration( snd , pSwarmName, pParameterName) == true ) return; + // // dirty fix end + + if (checkParameterRegistration(_sender, pSwarmName, pParameterName) == true) + { + ParameterRegistration* parReg = parameterRegistration(_sender, pSwarmName, pParameterName); + parReg->set(pSendInterval, pAgentGroupSize, pParValueMask); + } + else + { + mParameterRegistry[_sender].push_back(new ParameterRegistration(pSwarmName, pParameterName, pSenderName, pSendInterval, pAgentGroupSize, pParValueMask)); + } + } + catch (dab::Exception& e) + { + e += dab::Exception("COM ERROR: failed to register parameter for sender " + pSenderName + " swarm " + pSwarmName + " parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__); + + throw e; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception) +{ + // std::cout << "FlockCom::registerParameter( " << pSenderName.toStdString() << ", " << pSwarmName.toStdString() << ", " << pParameterName.toStdString() << ", " << pMinParValue << ", " << pMaxParValue << " )\n"; + + try + { + std::shared_ptr _sender = sender(pSenderName); + + // // dirty fix + // if( checkParameterRegistration( snd , pSwarmName, pParameterName) == true ) return; + // // dirty fix end + + if (checkParameterRegistration(_sender, pSwarmName, pParameterName) == true) + { + ParameterRegistration* parReg = parameterRegistration(_sender, pSwarmName, pParameterName); + parReg->set(pSendInterval, pAgentGroupSize, pMinParValue, pMaxParValue, pParValueMask); + } + else + { + mParameterRegistry[_sender].push_back(new ParameterRegistration(pSwarmName, pParameterName, pSenderName, pSendInterval, pAgentGroupSize, pMinParValue, pMaxParValue, pParValueMask)); + } + } + catch (dab::Exception& e) + { + e += dab::Exception("COM ERROR: failed to register parameter for sender " + pSenderName + " swarm " + pSwarmName + " parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__); + + throw e; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, unsigned int pAgentGroupSize, const std::vector& pParValueMask) throw (Exception) +{ + try + { + //std::cout << "FlockCom::registerParameter( pSenderName " << pSenderName.toStdString() << " , pSendInterval " << pSendInterval << " , pSwarmName " << pSwarmName.toStdString() << " , pParameterName " << pParameterName.toStdString() << " , pAgentRange " << pAgentRange << " )\n"; + + std::shared_ptr _sender = sender(pSenderName); + + // // dirty fix + // if( checkParameterRegistration( snd , pSwarmName, pParameterName) == true ) return; + // // dirty fix end + + if (checkParameterRegistration(_sender, pSwarmName, pParameterName) == true) + { + ParameterRegistration* parReg = parameterRegistration(_sender, pSwarmName, pParameterName); + parReg->set(pSendInterval, pAgentRange, pAgentGroupSize, pParValueMask); + } + else + { + mParameterRegistry[_sender].push_back(new ParameterRegistration(pSwarmName, pParameterName, pSenderName, pSendInterval, pAgentRange, pAgentGroupSize, pParValueMask)); + } + } + catch (dab::Exception& e) + { + e += dab::Exception("COM ERROR: failed to register parameter for sender " + pSenderName + " swarm " + pSwarmName + " parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__); + + throw e; + } +} + +void +FlockCom::registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception) +{ + try + { + std::shared_ptr _sender = sender(pSenderName); + + // // dirty fix + // if( checkParameterRegistration( snd , pSwarmName, pParameterName) == true ) return; + // // dirty fix end + + if (checkParameterRegistration(_sender, pSwarmName, pParameterName) == true) + { + ParameterRegistration* parReg = parameterRegistration(_sender, pSwarmName, pParameterName); + parReg->set(pSendInterval, pAgentRange, pAgentGroupSize, pMinParValue, pMaxParValue, pParValueMask); + } + else + { + mParameterRegistry[_sender].push_back(new ParameterRegistration(pSwarmName, pParameterName, pSenderName, pSendInterval, pAgentRange, pAgentGroupSize, pMinParValue, pMaxParValue, pParValueMask)); + } + } + catch (dab::Exception& e) + { + e += dab::Exception("COM ERROR: failed to register parameter for sender " + pSenderName + " swarm " + pSwarmName + " parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__); + + throw e; + } +} + +// <<<<< + +void +FlockCom::deregisterParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName) throw (dab::Exception) +{ + try + { + std::shared_ptr _sender = sender(pSenderName); + + if (checkParameterRegistration(_sender, pSwarmName, pParameterName) == false) + { + throw Exception("COM ERROR: parameter " + pParameterName + " of swarm " + pSwarmName + " not registered for sender " + pSenderName, __FILE__, __FUNCTION__, __LINE__); + } + else + { + std::vector& regs = mParameterRegistry[_sender]; + + int regCount = regs.size(); + for (int rI = regCount - 1; rI >= 0; --rI) + { + ParameterRegistration* reg = regs[rI]; + if (reg->match(pSwarmName, pParameterName) == true) + { + regs.erase(regs.begin() + rI); + delete reg; + return; + } + } + } + } + catch (dab::Exception& e) + { + e += Exception("COM ERROR: failed to deregister swarm " + pSwarmName + " parameter " + pParameterName + " for sender " + pSenderName, __FILE__, __FUNCTION__, __LINE__); + + throw e; + } +} + +void +FlockCom::update() throw (dab::Exception) +{ + try + { + send(); + } + catch (dab::Exception& e) + { + std::cout << e << "\n"; + } +} + +void +FlockCom::send() throw (dab::Exception) +{ + try + { + std::vector< std::shared_ptr > _senders = mSenders.values(); + + unsigned int sndCount = _senders.size(); + std::shared_ptr _sender; + + for (unsigned int sI = 0; sI 0) + { + sendMessage(_sender); + } + } + } + catch (dab::Exception) + { + throw; + } +} + +void +FlockCom::sendMessage(std::shared_ptr pSender) throw (dab::Exception) +{ + //std::cout << "FlockCom::sendMessage( com::Sender* pSender ) begin\n"; + + try + { + std::vector& regs = mParameterRegistry[pSender]; + bool extOscMode = mExtendedOscMode[pSender]; + + unsigned int regCount = regs.size(); + + for (unsigned int rI = 0; rIsendInterval() > 0 && reg->currentSendInterval() < reg->sendInterval()) reg->currentSendInterval() += 1; + else + { + sendMessage(pSender, reg, extOscMode); + reg->currentSendInterval() = 0; + } + } + + //pSender->send(); + } + catch (dab::Exception& e) + { + e += Exception("COM ERROR: failed to send message with sender " + pSender->name(), __FILE__, __FUNCTION__, __LINE__); + throw e; + } + + //std::cout << "FlockCom::sendMessage( com::Sender* pSender ) end\n"; +} + +//void +//FlockCom::sendMessage( std::shared_ptr pSender, ParameterRegistration* pRegistration, bool pExtendedOscMode ) throw (dab::Exception) +//{ +// //std::cout << "FlockCom::sendOSCMessage( com::Sender* pSender, ParameterRegistration* pRegistration ) throw (FlockException)\n"; +// +// try +// { +// const std::string& swarmName = pRegistration->swarmName(); +// const std::string& parameterName = pRegistration->parameterName(); +// +// Swarm* swarm = Simulation::get().swarm(swarmName); +// +// if( swarm->checkSwarmParameter( parameterName ) == true ) +// { +// sendMessage( pSender, pRegistration, std::string( "/" + swarmName + "/" + parameterName ), swarm->swarmParameter( parameterName ), pExtendedOscMode ); +// } +// else if( swarm->checkParameter( parameterName ) == true ) +// { +// unsigned int parameterIndex = swarm->parameterIndex(parameterName); +// std::array agentRange = pRegistration->agentRange(); +// +// std::vector& agents = swarm->agents(); +// int agentCount = agents.size(); +// +// if( agentRange[0] < 0) agentRange[0] = 0; +// else if( agentRange[0] >= agentCount ) return; +// if( agentRange[1] < 0 || agentRange[1] >= agentCount ) agentRange[1] = agentCount; +// +// int agentGroupSize = pRegistration->agentGroupSize(); +// +// //std::cout << "agentGroupSize " << agentGroupSize << "\n"; +// //std::cout << "ar0 " << agentRange[0] << " ar1 " << agentRange[1] << "\n"; +// +// for( unsigned int aI = agentRange[0]; aI < agentRange[1]; ++aI ) +// { +// sendMessage( pSender, pRegistration, std::string( "/" + swarmName + "/" + std::to_string(aI) + "/" + parameterName ), agents[aI]->parameter( parameterIndex ), pExtendedOscMode ); +// } +// } +// else +// { +// throw dab::Exception( "COM ERROR: parameter " + parameterName + " not found for swarm " + swarmName, __FILE__, __FUNCTION__, __LINE__ ); +// } +// } +// catch( dab::Exception& e ) +// { +// e += dab::Exception("COM ERROR: failed to send message", __FILE__, __FUNCTION__, __LINE__); +// throw e; +// } +//} + +void +FlockCom::sendMessage(std::shared_ptr pSender, ParameterRegistration* pRegistration, bool pExtendedOscMode) throw (dab::Exception) +{ + //std::cout << "FlockCom::sendOSCMessage( com::Sender* pSender, ParameterRegistration* pRegistration ) throw (FlockException)\n"; + + try + { + const std::string& swarmName = pRegistration->swarmName(); + const std::string& parameterName = pRegistration->parameterName(); + + Swarm* swarm = Simulation::get().swarm(swarmName); + + if (swarm->checkSwarmParameter(parameterName) == true) + { + sendMessage(pSender, pRegistration, std::string("/" + swarmName + "/" + parameterName), swarm->swarmParameter(parameterName), pExtendedOscMode); + } + else if (swarm->checkParameter(parameterName) == true) + { + unsigned int parameterIndex = swarm->parameterIndex(parameterName); + std::array agentRange = pRegistration->agentRange(); + + std::vector& agents = swarm->agents(); + int agentCount = agents.size(); + + if (agentRange[0] < 0) agentRange[0] = 0; + else if (agentRange[0] >= agentCount) return; + if (agentRange[1] < 0 || agentRange[1] >= agentCount) agentRange[1] = agentCount; + + int agentGroupSize = pRegistration->agentGroupSize(); + + // std::cout << "agentGroupSize " << agentGroupSize << "\n"; + // std::cout << "ar0 " << agentRange[0] << " ar1 " << agentRange[1] << "\n"; + + for (int aI = agentRange[0]; aI < agentRange[1]; ) + { + int startAI = aI; + int parameterCount = std::min(agentGroupSize, agentRange[1] - aI); + std::vector _parameters(parameterCount); + + for (int i = 0; iparameter( parameterIndex ) << "\n"; + + _parameters[i] = agents[aI]->parameter(parameterIndex); + } + + if (agentGroupSize > 1) + { + int endAI = aI - 1; + sendMessage(pSender, pRegistration, std::string("/" + swarmName + "/" + std::to_string(startAI) + "/" + std::to_string(endAI) + "/" + parameterName), _parameters, pExtendedOscMode); + } + else + { + sendMessage(pSender, pRegistration, std::string("/" + swarmName + "/" + std::to_string(startAI) + "/" + parameterName), _parameters, pExtendedOscMode); + } + } + } + else + { + throw dab::Exception("COM ERROR: parameter " + parameterName + " not found for swarm " + swarmName, __FILE__, __FUNCTION__, __LINE__); + } + } + catch (dab::Exception& e) + { + e += dab::Exception("COM ERROR: failed to send message", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +FlockCom::sendMessage(std::shared_ptr pSender, ParameterRegistration* pRegistration, const std::string& pAddress, std::vector pParameters, bool pExtendedOscMode) throw (Exception) +{ + //std::cout << "sendMessage sender " << pSender->name() << " address " << pAddress << "\n"; + + try + { + std::shared_ptr message(new OscMessage()); + message->setAddress(pAddress); + addMessageParameter(message, pRegistration, pParameters, pExtendedOscMode); + + //pSender->queue( message ); // TODO: check why queing doesn't work + + pSender->send(message); + } + catch (dab::Exception& e) + { + e += dab::Exception("COM ERROR: failed to send message", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +FlockCom::sendMessage(std::shared_ptr pSender, ParameterRegistration* pRegistration, const std::string& pAddress, Parameter* pParameter, bool pExtendedOscMode) throw (Exception) +{ + // deprecated + + try + { + std::shared_ptr message(new OscMessage()); + message->setAddress(pAddress); + + addMessageParameter(message, pRegistration, pParameter, pExtendedOscMode); + + //pSender->queue( message ); // TODO: check why queing doesn't work + pSender->send(message); + } + catch (dab::Exception& e) + { + e += dab::Exception("COM ERROR: failed to send message", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +FlockCom::addMessageParameter(std::shared_ptr pMessage, ParameterRegistration* pRegistration, std::vector pParameters, bool pExtendedOscMode) throw (Exception) +{ + try + { + int parameterCount = pParameters.size(); + if (parameterCount == 0) return; + + unsigned int parDim = pParameters[0]->values().rows(); + bool normalise = pRegistration->normalise(); + bool maskValues = pRegistration->maskValues(); + const std::vector& parValueMask = pRegistration->parValueMask(); + + if (pExtendedOscMode == false) + { + if (normalise == false) + { + if (maskValues == false) + { + for (int pI = 0, i = 0; pIvalues(); + + for (int d = 0; dadd(parValues[d]); + } + } + } + else + { + for (int pI = 0, i = 0; pIvalues(); + + for (int d = 0; dadd(parValues[d]); + } + } + } + } + } + else + { + const Eigen::VectorXf& parValueScale = pRegistration->parValueScale(); + const Eigen::VectorXf& parValueOffset = pRegistration->parValueOffset(); + float parSendNormValue; + + if (maskValues == false) + { + for (int pI = 0, i = 0; pIvalues(); + + for (int d = 0; dadd(parSendNormValue); + } + } + } + else + { + for (int pI = 0, i = 0; pIvalues(); + + for (int d = 0; dadd(parSendNormValue); + } + } + } + } + } + } + else + { + int parameterValueCount = 0; + + if (maskValues == true) + { + int maskValueCount = 0; + for (int d = 0; d parameterValues(parameterValueCount); + + if (normalise == false) + { + if (maskValues == false) + { + for (int pI = 0, i = 0; pIvalues(); + + for (int d = 0; dvalues(); + + for (int d = 0; dparValueScale(); + const Eigen::VectorXf& parValueOffset = pRegistration->parValueOffset(); + float parSendNormValue; + + if (maskValues == false) + { + for (int pI = 0, i = 0; pIvalues(); + + for (int d = 0; dvalues(); + + for (int d = 0; dadd(parameterValues.data(), parameterValues.size()); + } + } + catch (dab::Exception& e) + { + e += dab::Exception("COM ERROR: failed to add message parameter", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +FlockCom::addMessageParameter(std::shared_ptr pMessage, ParameterRegistration* pRegistration, Parameter* pParameter, bool pExtendedOscMode) throw (dab::Exception) +{ + //deprecated + + try + { + const Eigen::VectorXf& parValues = pParameter->values(); + unsigned int parDim = parValues.rows(); + + bool maskValues = pRegistration->maskValues(); + const std::vector& parValueMask = pRegistration->parValueMask(); + + bool normalise = pRegistration->normalise(); + + if (normalise == false) + { + if (maskValues == true) + { + if (pExtendedOscMode == true) + { + std::vector< float > parSendValues; + for (int d = 0; dadd(parSendValues.data(), parSendValues.size()); + } + else + { + for (int d = 0; dadd(parValues[d]); + } + } + } + } + else + { + if (pExtendedOscMode == true) + { + pMessage->add(parValues.data(), parDim); + } + else + { + for (int d = 0; dadd(parValues[d]); + } + } + } + } + else + { + const Eigen::VectorXf& parValueScale = pRegistration->parValueScale(); + const Eigen::VectorXf& parValueOffset = pRegistration->parValueOffset(); + + if (parDim != parValueScale.rows()) throw dab::Exception("COM ERROR: value scale dimension (" + std::to_string(parDim) + ") does not match parameter dimension (" + std::to_string(parValues.rows()) + ")", __FILE__, __FUNCTION__, __LINE__); + else + { + if (maskValues == true) + { + std::vector< float > parSendValues; + float parSendValue; + + if (pExtendedOscMode == true) + { + for (unsigned int d = 0; d 1.0) parSendValue = 1.0; + parSendValues.push_back(parSendValue); + } + } + + pMessage->add(parSendValues.data(), parSendValues.size()); + } + else + { + for (unsigned int d = 0; d 1.0) parSendValue = 1.0; + + pMessage->add(parSendValue); + } + } + } + } + else + { + if (pExtendedOscMode == true) + { + std::vector scaledValues(parDim); + + for (unsigned int d = 0; d 1.0) scaledValues[d] = 1.0; + } + + pMessage->add(scaledValues.data(), scaledValues.size()); + } + else + { + float scaledValue; + + for (unsigned int d = 0; d 1.0) scaledValue = 1.0; + pMessage->add(scaledValue); + } + } + } + } + } + } + catch (dab::Exception& e) + { + e += dab::Exception("COM ERROR: failed to add message parameter", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} \ No newline at end of file diff --git a/src/dab_flock_com.h b/src/dab_flock_com.h new file mode 100644 index 0000000..e0108e1 --- /dev/null +++ b/src/dab_flock_com.h @@ -0,0 +1,484 @@ +/** \file dab_flock_com.h +* +* Created by Daniel Bisig on 5/26/07. +* Ported to OpenFrameworks by Daniel Bisig on 09/08/17. +*/ + +#ifndef _dab_flock_com_h_ +#define _dab_flock_com_h_ + +#include +#include +#include +#include +#include "ofUtils.h" +#include "dab_exception.h" +#include "dab_singleton.h" +#include "dab_index_map.h" +#include "dab_osc_messenger.h" + +namespace dab +{ + + namespace flock + { + + class Parameter; + class OscControl; + +#pragma mark communication type + +#pragma mark parameter communication registration + + class ParameterRegistration + { + public: + ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval); + ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception); + ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const std::array& pAgentRange) throw (Exception); + ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const std::array& pAgentRange, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception); + ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, unsigned int pAgentGroupSize); + ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception); + ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const std::array& pAgentRange, unsigned int pAgentGroupSize) throw (Exception); + ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const std::array& pAgentRange, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception); + + ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const std::vector& pParValueMask); + ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception); + ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const std::array& pAgentRange, const std::vector& pParValueMask) throw (Exception); + ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const std::array& pAgentRange, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception); + ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, unsigned int pAgentGroupSize, const std::vector& pParValueMask); + ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception); + ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const std::array& pAgentRange, unsigned int pAgentGroupSize, const std::vector& pParValueMask) throw (Exception); + ParameterRegistration(const std::string& pSwarmName, const std::string& pParameterName, const std::string& pSenderName, unsigned int pSendInterval, const std::array& pAgentRange, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception); + + ParameterRegistration(const ParameterRegistration& pRegistration); + ~ParameterRegistration(); + + void set(unsigned int pSendInterval); + void set(unsigned int pSendInterval, const std::array& pAgentRange) throw (Exception); + void set(unsigned int pSendInterval, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception); + void set(unsigned int pSendInterval, const std::array& pAgentRange, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception); + void set(unsigned int pSendInterval, unsigned int pAgentGroupSize); + void set(unsigned int pSendInterval, const std::array& pAgentRange, unsigned int pAgentGroupSize) throw (Exception); + void set(unsigned int pSendInterval, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception); + void set(unsigned int pSendInterval, const std::array& pAgentRange, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception); + + void set(unsigned int pSendInterval, const std::vector& pParValueMask); + void set(unsigned int pSendInterval, const std::array& pAgentRange, const std::vector& pParValueMask) throw (Exception); + void set(unsigned int pSendInterval, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception); + void set(unsigned int pSendInterval, const std::array& pAgentRange, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception); + void set(unsigned int pSendInterval, unsigned int pAgentGroupSize, const std::vector& pParValueMask); + void set(unsigned int pSendInterval, const std::array& pAgentRange, unsigned int pAgentGroupSize, const std::vector& pParValueMask) throw (Exception); + void set(unsigned int pSendInterval, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception); + void set(unsigned int pSendInterval, const std::array& pAgentRange, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception); + + const std::string& swarmName() const; + const std::string& parameterName() const; + const std::string& senderName() const; + unsigned int sendInterval() const; + unsigned int& currentSendInterval(); + const std::array& agentRange() const; + unsigned int agentGroupSize() const; + bool normalise() const; + const Eigen::VectorXf& minParValue()const; + const Eigen::VectorXf& maxParValue()const; + const Eigen::VectorXf& parValueScale() const; + const Eigen::VectorXf& parValueOffset() const; + const std::vector& parValueMask() const; + bool maskValues() const; + + bool operator==(const ParameterRegistration& pRegistration) const; + bool match(const std::string& pSwarmName, const std::string& pParameterName) const; + + protected: + std::string mSwarmName; + std::string mParameterName; + std::string mSenderName; + std::array mAgentRange; + unsigned int mAgentGroupSize; + bool mNormalise; + Eigen::VectorXf mMinParValue; + Eigen::VectorXf mMaxParValue; + Eigen::VectorXf mParValueScale; + Eigen::VectorXf mParValueOffset; + bool mMaskValues; + std::vector mParValueMask; + unsigned int mSendInterval; + unsigned int mCurrentSendInterval; + }; + +#pragma mark flock messenger + + class FlockCom : public OscMessenger, public Singleton + { + friend class Singleton; + + public: + /** + \brief create osc control + \param pReceiverPort receiver port number + \param pSenderIP sender ip address + \param pSenderPort sender port number + \throw Exception failed to create osc control + */ + void createOscControl(unsigned int pReceiverPort, const std::string& pSenderIP, unsigned int pSenderPort) throw (Exception); + + /** + \brief create osc control + \param pOscControl OSCControl + \param pReceiverPort receiver port number + \param pSenderIP sender ip address + \param pSenderPort sender port number + \throw Exception failed to create osc control + */ + void createOscControl(std::shared_ptr pOscControl, unsigned int pReceiverPort, const std::string& pSenderIP, unsigned int pSenderPort) throw (Exception); + + /** + \brief create network sender + \param pSenderName name of network sender + \param pReceiverIP IP address of receiver + \param pReceiverPort port of receiver + \param pExtendedOscMode use extended OSC protocol + \exception Exception failed to create network sender + */ + void createSender(const std::string& pSenderName, const std::string& pReceiverIP, unsigned int pReceiverPort, bool pExtendedOscMode) throw (Exception); + + /** + \brief remove all senders with the exception of those involved in osc control + */ + void removeSenders(); + + /** + \brief remove sender + \param pSenderName name of sender + \exception failed to remove sender + */ + void removeSender(const std::string& pSenderName) throw (Exception); + + /** + \brief query extended osc mode + \param pSenderName name of sender + \exception Exception sender not found + */ + bool extendedOscMode(const std::string& pSenderName) throw (Exception); + + /** + \brief retrieve parameter registration information + \param pSenderName name of sender + \param pSwarmName name of swarm + \param pParameterName name of parameter + \exception ComException failed to retrieve paramater registration + */ + ParameterRegistration* parameterRegistration(std::shared_ptr pSender, const std::string& pSwarmName, const std::string& pParameterName) throw (Exception); + + /** + \brief return parameter registration information + \param pSwarmName name of swarm / env + \param pParameterName name of parameter + \return parameter registration information + */ + std::vector< ParameterRegistration* > parameterRegistrations(const std::string& pSwarmName, const std::string& pParameterName) const; + + /** + \brief check if parameter is registered for sending + \param pSenderName name of sender + \param pSwarmName name of swarm + \param pParameterName name of parameter + */ + bool checkParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName); + + /** + \brief register parameter for sending + \param pSenderName name of sender + \param pSwarmName name of swarm + \param pParameterName name of parameter + \exception Exception failed to register parameter + */ + void registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName) throw (Exception); + + /** + \brief register parameter for sending + \param pSenderName name of sender + \param pSwarmName name of swarm + \param pParameterName name of parameter + \param pMinParValue minimum parameter value + \param pMaxParValue maximum parameter value + \exception Exception failed to register parameter + */ + void registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception); + + /** + \brief register parameter for sending + \param pSenderName name of sender + \param pSwarmName name of swarm + \param pParameterName name of parameter + \param pAgentRange range of agents + \exception Exception failed to register parameter + */ + void registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange) throw (Exception); + + /** + \brief register parameter for sending + \param pSenderName name of sender + \param pSwarmName name of swarm + \param pParameterName name of parameter + \param pAgentRange range of agents + \param pMinParValue minimum parameter value + \param pMaxParValue maximum parameter value + \exception Exception failed to register parameter + */ + void registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception); + + /** + \brief register parameter for sending + \param pSenderName name of sender + \param pSendInterval send interval + \param pSwarmName name of swarm + \param pParameterName name of parameter + \exception Exception failed to register parameter + */ + void registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName) throw (Exception); + + /** + \brief register parameter for sending + \param pSenderName name of sender + \param pSendInterval send interval + \param pSwarmName name of swarm + \param pParameterName name of parameter + \param pMinParValue minimum parameter value + \param pMaxParValue maximum parameter value + \exception Exception failed to register parameter + */ + void registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception); + + /** + \brief register parameter for sending + \param pSenderName name of sender + \param pSendInterval send interval + \param pSwarmName name of swarm + \param pParameterName name of parameter + \param pAgentRange range of agents + \exception Exception failed to register parameter + */ + void registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange) throw (Exception); + + /** + \brief register parameter for sending + \param pSenderName name of sender + \param pSendInterval send interval + \param pSwarmName name of swarm + \param pParameterName name of parameter + \param pAgentRange range of agents + \param pMinParValue minimum parameter value + \param pMaxParValue maximum parameter value + \exception Exception failed to register parameter + */ + void registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception); + + /** + \brief register parameter for sending + \param pSenderName name of sender + \param pSwarmName name of swarm + \param pParameterName name of parameter + \param pAgentGroupSize number of parameters sent at once ( for OSC senders only ) + \exception Exception failed to register parameter + */ + void registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, unsigned int pAgentGroupSize) throw (Exception); + + /** + \brief register parameter for sending + \param pSenderName name of sender + \param pSwarmName name of swarm + \param pParameterName name of parameter + \param pAgentGroupSize number of parameters sent at once ( for OSC senders only ) + \param pMinParValue minimum parameter value + \param pMaxParValue maximum parameter value + \exception Exception failed to register parameter + */ + void registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception); + + /** + \brief register parameter for sending + \param pSenderName name of sender + \param pSwarmName name of swarm + \param pParameterName name of parameter + \param pAgentRange range of agents + \param pAgentGroupSize number of parameters sent at once ( for OSC senders only ) + \exception Exception failed to register parameter + */ + void registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, unsigned int pAgentGroupSize) throw (Exception); + + /** + \brief register parameter for sending + \param pSenderName name of sender + \param pSwarmName name of swarm + \param pParameterName name of parameter + \param pAgentRange range of agents + \param pAgentGroupSize number of parameters sent at once ( for OSC senders only ) + \param pMinParValue minimum parameter value + \param pMaxParValue maximum parameter value + \exception Exception failed to register parameter + */ + void registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception); + + /** + \brief register parameter for sending + \param pSenderName name of sender + \param pSendInterval send interval + \param pSwarmName name of swarm + \param pParameterName name of parameter + \param pAgentGroupSize number of parameters sent at once ( for OSC senders only ) + \exception Exception failed to register parameter + */ + void registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, unsigned int pAgentGroupSize) throw (Exception); + + /** + \brief register parameter for sending + \param pSenderName name of sender + \param pSendInterval send interval + \param pSwarmName name of swarm + \param pParameterName name of parameter + \param pAgentGroupSize number of parameters sent at once ( for OSC senders only ) + \param pMinParValue minimum parameter value + \param pMaxParValue maximum parameter value + \exception Exception failed to register parameter + */ + void registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception); + + /** + \brief register parameter for sending + \param pSenderName name of sender + \param pSendInterval send interval + \param pSwarmName name of swarm + \param pParameterName name of parameter + \param pAgentRange range of agents + \param pAgentGroupSize number of parameters sent at once ( for OSC senders only ) + \exception Exception failed to register parameter + */ + void registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, unsigned int pAgentGroupSize) throw (Exception); + + /** + \brief register parameter for sending + \param pSenderName name of sender + \param pSendInterval send interval + \param pSwarmName name of swarm + \param pParameterName name of parameter + \param pAgentRange range of agents + \param pAgentGroupSize number of parameters sent at once ( for OSC senders only ) + \param pMinParValue minimum parameter value + \param pMaxParValue maximum parameter value + \exception Exception failed to register parameter + */ + void registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue) throw (Exception); + + + void registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::vector& pParValueMask) throw (Exception); + void registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception); + void registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const std::vector& pParValueMask) throw (Exception); + void registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception); + void registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::vector& pParValueMask) throw (Exception); + void registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception); + void registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const std::vector& pParValueMask) throw (Exception); + void registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception); + void registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, unsigned int pAgentGroupSize, const std::vector& pParValueMask) throw (Exception); + void registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception); + void registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, unsigned int pAgentGroupSize, const std::vector& pParValueMask) throw (Exception); + void registerParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception); + void registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, unsigned int pAgentGroupSize, const std::vector& pParValueMask) throw (Exception); + void registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception); + void registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, unsigned int pAgentGroupSize, const std::vector& pParValueMask) throw (Exception); + void registerParameter(const std::string& pSenderName, unsigned int pSendInterval, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, unsigned int pAgentGroupSize, const Eigen::VectorXf& pMinParValue, const Eigen::VectorXf& pMaxParValue, const std::vector& pParValueMask) throw (Exception); + + + /** + \brief deregister parameter from sending + \param pSenderName name of sender + \param pSwarmName name of swarm + \param pParameterName name of parameter + */ + void deregisterParameter(const std::string& pSenderName, const std::string& pSwarmName, const std::string& pParameterName) throw (Exception); + + + /** + \brief update messenger + \Exception Exception failed to update messenger + */ + virtual void update() throw (Exception); + + protected: + std::shared_ptr mControlReceiver; + std::shared_ptr mErrorSender; + std::shared_ptr mOscControl; + + IndexMap< std::shared_ptr, std::vector > mParameterRegistry; ///\brief parameter communication registry + IndexMap< std::shared_ptr, bool > mExtendedOscMode; + + double mTime; + + + /** + \brief default constructor + */ + FlockCom(); + + /** + \brief destructor + */ + ~FlockCom(); + + /** + \brief check if parameter registration for sender already exists + \param pSenderName name of sender + \param pSwarmName name of swarm + \param pParameterName name of parameter + \return true if parameter registration found, false otherwise + */ + bool checkParameterRegistration(std::shared_ptr pSender, const std::string& pSwarmName, const std::string& pParameterName); + + /** + \brief update senders + \exception ComException failed to update senders + \remarks creates message based on registered parameters for all senders and sends them + */ + void send() throw (Exception); + + /** + \brief send osc message + \param pSender sender + \exception ComException failed to update sender + */ + void sendMessage(std::shared_ptr pSender) throw (Exception); + + /** + \brief update osc sender + \param pSender sender + \param pRegistration parameter registration + \param pExtendedOscMode use extended osc protocol + \exception ComException failed to update sender + */ + void sendMessage(std::shared_ptr pSender, ParameterRegistration* pRegistration, bool pExtendedOscMode) throw (Exception); + + /** + \brief update osc sender + \param pSender sender + \param pRegistration parameter registration + \param pAddress osc address pattern + \param pParameter parameter + \param pExtendedOscMode use extended osc protocol + \exception ComException failed to update sender + */ + void sendMessage(std::shared_ptr pSender, ParameterRegistration* pRegistration, const std::string& pAddress, Parameter* pParameter, bool pExtendedOscMode) throw (Exception); + + void sendMessage(std::shared_ptr pSender, ParameterRegistration* pRegistration, const std::string& pAddress, std::vector pParameters, bool pExtendedOscMode) throw (Exception); + + void addMessageParameter(std::shared_ptr pMessage, ParameterRegistration* pRegistration, Parameter* pParameter, bool pExtendedOscMode) throw (Exception); + + void addMessageParameter(std::shared_ptr pMessage, ParameterRegistration* pRegistration, std::vector pParameters, bool pExtendedOscMode) throw (Exception); + + }; + + }; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_cone_vision_behavior.cpp b/src/dab_flock_cone_vision_behavior.cpp new file mode 100644 index 0000000..e94ac23 --- /dev/null +++ b/src/dab_flock_cone_vision_behavior.cpp @@ -0,0 +1,128 @@ +/** \file dab_flock_cone_vision_behavior.cpp + */ + +#include "dab_flock_cone_vision_behavior.h" +#include "dab_flock_parameter.h" +#include "dab_flock_agent.h" +#include "dab_space_neighbor_relation.h" + +using namespace dab; +using namespace dab::flock; + +ConeVisionBehavior::ConeVisionBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "ConeVisionBehavior"; +} + +ConeVisionBehavior::ConeVisionBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "ConeVisionBehavior"; + + if( mInputParameters.size() < 2 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(2) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mInputParameters[1]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match input parameter " + mInputParameters[1]->name() + " dim " + std::to_string(mInputParameters[1]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mInputNeighborGroups.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputNeighborGroups.size()) + " neighbor groups supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputNeighborGroups.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputNeighborGroups.size()) + " neighbor groups supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ) ; + + + // input parameter + mPositionInPar = mInputParameters[0]; + mVelocityPar = mInputParameters[1]; + + // output parameter + mPositionOutPar = mOutputParameters[0]; + + // create internal parameters + mVisionAnglePar = createInternalParameter("visionAngle", { 0.0 } ); + + // input neighbor groups + mPositionInNeighbors = mInputNeighborGroups[0]; + + // input neighbor groups + mPositionOutNeighbors = mOutputNeighborGroups[0]; + + // remaining stuff + unsigned int dim = mVelocityPar->dim(); + mNormVelocity.resize(dim,1); + mNormNeighborDirection.resize(dim,1); +} + +ConeVisionBehavior::~ConeVisionBehavior() +{} + +Behavior* +ConeVisionBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new ConeVisionBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new ConeVisionBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +ConeVisionBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new ConeVisionBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +ConeVisionBehavior::act() +{ + //std::cout << "ConeVisionBehavior::act() begin\n"; + + //std::cout << "AlignmentBehavior begin: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + if(mActivePar->value() <= 0.0) return; + + space::NeighborGroup& positionInNeighbors = *mPositionInNeighbors; + Eigen::VectorXf& velocity = mVelocityPar->values(); + const std::string& velocityName = mVelocityPar->name(); + space::NeighborGroup& positionOutNeighbors = *mPositionOutNeighbors; + space::SpaceNeighborRelation* neighbor; + space::SpaceObject* spaceObject; + + positionOutNeighbors.removeNeighbors(); + + float& visionAngle = mVisionAnglePar->value(); + + mNormVelocity = velocity; + mNormVelocity.normalize(); + + + unsigned int totalNeighborCount = positionInNeighbors.neighborCount(); + + for(unsigned int i=0; ineighbor(); + const Eigen::VectorXf& neighborDirection = neighbor->direction(); + + mNormNeighborDirection = neighborDirection; + mNormNeighborDirection.normalize(); + + //std::cout << "vel " << velocity << " nVel " << neighborVelocity << " dot " << mNormVelocity.dot( mNormNeighVelocity ) << "\n"; + + if( mNormVelocity.dot( mNormNeighborDirection ) < visionAngle ) continue; + + positionOutNeighbors.addNeighbor( spaceObject, neighbor->distance(), neighbor->direction() ); + } + + //std::cout << "in neighbors " << positionInNeighbors << "\n"; + //std::cout << "out neighbors " << positionOutNeighbors << "\n"; + + //std::cout << "ConeVisionBehavior::act() end\n"; +} \ No newline at end of file diff --git a/src/dab_flock_cone_vision_behavior.h b/src/dab_flock_cone_vision_behavior.h new file mode 100644 index 0000000..fd89adc --- /dev/null +++ b/src/dab_flock_cone_vision_behavior.h @@ -0,0 +1,101 @@ +/** \file dab_flock_cone_vision_behavior.h + * \class dab::flock::ConeVisionBehavior velocity alignment behavior + * \brief cone vision behavior + * + * The behavior implements cone vision for agents.\n + * It does so by copying those neighbors from an input neighbor group into an output neighbor group that fall within the interior of an agent's vision cone.\n. + * The tip of vision cone is placed at the agent's position and oriented in the direction of the agent's velocity.\n + * \n + * Input Parameter:\n + * type: position dim: nD neighbors: required\n + * type: velocity dim: nD neighbors: ignore\n + * \n + * Output Parameter:\n + * type: position dim: nD neighbors: required\n + * \n + * Internal Parameter:\n + * name: xxx_visionAngle dim: 1D defaultValue: 0.0\n + * \n + * Created by Daniel Bisig on 4/15/09. + */ + +// TODO: Untested + +#ifndef _dab_flock_cone_vision_behavior_h_ +#define _dab_flock_cone_vision_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class Agent; + +class ConeVisionBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + ConeVisionBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + ConeVisionBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~ConeVisionBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mPositionInPar; /// \brief position parameter (input) + Parameter* mVelocityPar; /// \brief velocity parameter (input) + Parameter* mPositionOutPar; /// \brief position parameter (output) + Parameter* mVisionAnglePar; /// \brief force parameter (internal) + space::NeighborGroup* mPositionInNeighbors; /// \brief position neighbor group + space::NeighborGroup* mPositionOutNeighbors; /// \brief position neighbor group + + Eigen::VectorXf mNormVelocity; + Eigen::VectorXf mNormNeighborDirection; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_copy_behavior.cpp b/src/dab_flock_copy_behavior.cpp new file mode 100644 index 0000000..c033e44 --- /dev/null +++ b/src/dab_flock_copy_behavior.cpp @@ -0,0 +1,75 @@ +/** \file dab_flock_copy_behavior.cpp + */ + +#include "dab_flock_copy_behavior.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +CopyBehavior::CopyBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "CopyBehavior"; +} + +CopyBehavior::CopyBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "CopyBehavior"; + + if( mInputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mParIn = mInputParameters[0]; + + // output parameter + mParOut = mOutputParameters[0]; +} + +CopyBehavior::~CopyBehavior() +{} + +Behavior* +CopyBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new CopyBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new CopyBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +CopyBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new CopyBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +CopyBehavior::act() +{ + //std::cout << "CopyBehavior begin: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& valueIn = mParIn->values(); + Eigen::VectorXf& valueOut = mParOut->backupValues(); + + valueOut = valueIn; + + //std::cout << "CopyBehavior end: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + //assert(std::isnan(valueOut[0]) == false && "isNan"); +} \ No newline at end of file diff --git a/src/dab_flock_copy_behavior.h b/src/dab_flock_copy_behavior.h new file mode 100644 index 0000000..c0501ae --- /dev/null +++ b/src/dab_flock_copy_behavior.h @@ -0,0 +1,86 @@ +/** \file dab_flock_copy_behavior.h + * \class dab::flock::CohesionBehavior copy parameter values into other parameter + * \brief copy parameter values into other parameter + * + * The Behavior copies parameter values into other parameter\n + * Input Parameter:\n + * type: input dim: nD neighbors: ignored\n + * \n + * Output Parameter:\n + * type: output dim: nD write: replace\n + * \n + * Internal Parameter:\n + * name: xxx_active dim: 1D defaultValue: 1.0\n + * \n + * Created by Daniel Bisig on 4/25/07. + * Ported to OpenFrameworks by Daniel Bisig on 13/10/2017. + */ + +#ifndef _dab_flock_copy_behavior_h_ +#define _dab_flock_copy_behavior_h_ + +#include "dab_flock_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class CopyBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + CopyBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + CopyBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~CopyBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mParIn; /// \brief input parameter (input) + Parameter* mParOut; /// \brief output parameter (output) +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_damping_behavior.cpp b/src/dab_flock_damping_behavior.cpp new file mode 100644 index 0000000..d03ba74 --- /dev/null +++ b/src/dab_flock_damping_behavior.cpp @@ -0,0 +1,98 @@ +/** \file dab_flock_damping_behavior.cpp + */ + +#include "dab_flock_damping_behavior.h" +#include "dab_flock_parameter.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +DampingBehavior::DampingBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "DampingBehavior"; +} + +DampingBehavior::DampingBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "DampingBehavior"; + + if(mInputParameters.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if(mOutputParameters.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mVelocityPar = mInputParameters[0]; + + // output parameter + mForcePar = mOutputParameters[0]; + + // create internal parameters + mPrefVelocityPar = createInternalParameter("prefVelocity", { 0.0f } ); + mAmountPar = createInternalParameter("amount", { 0.1f } ); + + // remaining stuff + unsigned int dim = mForcePar->dim(); + mTmpForce.resize(dim, 1); +} + +DampingBehavior::~DampingBehavior() +{} + +Behavior* +DampingBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new DampingBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new DampingBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +DampingBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new DampingBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +DampingBehavior::act() +{ + //std::cout << "DampingBehavior begin: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& velocity = mVelocityPar->values(); + float& prefVelocity = mPrefVelocityPar->value(); + float& amount = mAmountPar->value(); + Eigen::VectorXf& force = mForcePar->backupValues(); + Eigen::VectorXf& tmpForce = mTmpForce; + + float velMag = velocity.norm(); + + if(velMag == 0) return; + + float velDiff = prefVelocity - velMag; + + tmpForce = velocity; + tmpForce.normalize(); + tmpForce *= velDiff; + tmpForce *= amount; + + force += tmpForce; + + //std::cout << "DampingBehavior end: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + //assert(std::isnan(force[0]) == false && "isNan"); +} \ No newline at end of file diff --git a/src/dab_flock_damping_behavior.h b/src/dab_flock_damping_behavior.h new file mode 100644 index 0000000..d92de91 --- /dev/null +++ b/src/dab_flock_damping_behavior.h @@ -0,0 +1,95 @@ +/** \file dab_flock_damping_behavior.h + * \class dab::flock::DampingBehavior adapt Agent velocity towards target speed + * \brief adapt Agent velocity towards target speed + * + * The Behavior adapts Agent velocity towards target speed\n + * Input Parameter:\n + * type: velocity dim: nD neighbors: ignored\n + * \n + * Output Parameter:\n + * type: force dim: nD write: add\n + * \n + * Internal Parameter:\n + * name: xxx_prefVelocity dim: 1D defaultValue: 1.0\n + * name: xxx_amount dim: 1D defaultValue: 0.1\n + * name: xxx_active dim: 1D defaultValue: 1.0\n + * \n + * Created by Daniel Bisig on 4/21/07. + * Ported to OpenFrameworks by Daniel Bisig on 10/10/2017. + */ + +#ifndef _dab_flock_damping_behavior_h_ +#define _dab_flock_damping_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class Agent; + +class DampingBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + DampingBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception FlockException wrong number of type of parameters + */ + DampingBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~DampingBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception FlockException wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mVelocityPar; /// \brief velocity parameter (input) + Parameter* mForcePar; /// \brief force parameter (output) + Parameter* mPrefVelocityPar; /// \brief preferred velocity parameter (internal) + Parameter* mAmountPar; /// \brief behavior amount parameter (internal) + + Eigen::VectorXf mTmpForce; /// \brief temporary force +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_distance_field_follow_behavior.cpp b/src/dab_flock_distance_field_follow_behavior.cpp new file mode 100644 index 0000000..cc6207b --- /dev/null +++ b/src/dab_flock_distance_field_follow_behavior.cpp @@ -0,0 +1,148 @@ +/** \file dab_flock_distance_field_follow_behavior.cpp + */ + +#include "dab_flock_distance_field_follow_behavior.h" +#include + +using namespace dab; +using namespace dab::flock; + +DistanceFieldFollowBehavior::DistanceFieldFollowBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "DistanceFieldFollowBehavior"; +} + +DistanceFieldFollowBehavior::DistanceFieldFollowBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "DistanceFieldFollowBehavior"; + + if(mInputParameters.size() < 2) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(2) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if(mOutputParameters.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if(mInputParameters[0]->dim() != mInputParameters[1]->dim() || mInputParameters[0]->dim() != mOutputParameters[0]->dim()) throw Exception( "FLOCK ERROR: dimension of input and output parameter not equal", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputNeighborGroups.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputNeighborGroups.size()) + " neighbor groups supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameters + mPositionPar = mInputParameters[0]; + mVelocityPar = mInputParameters[1]; + + // output parameters + mForcePar = mOutputParameters[0]; + + // internal parameters + mMinDistPar = createInternalParameter("minDist", { 0.0f } ); + mMaxDistPar = createInternalParameter("maxDist", { 1.0f } ); + mOrtAmountPar = createInternalParameter("ortAmount", { 1.0f } ); + mTanAmountPar = createInternalParameter("tanAmount", { 1.0f } ); + mAmountPar = createInternalParameter("amount", { 0.1f } ); + + // input neighbor groups + mGridValues = mInputNeighborGroups[0]; + + // other stuff + unsigned int dim = mPositionPar->dim(); + mOrtDirection.resize(dim,1); + mTangDirection.resize(dim,1); + mDistanceVector.resize(dim,1); + mNormVelocity.resize(dim,1); +} + +DistanceFieldFollowBehavior::~DistanceFieldFollowBehavior() +{} + +Behavior* +DistanceFieldFollowBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new DistanceFieldFollowBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new DistanceFieldFollowBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +DistanceFieldFollowBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new DistanceFieldFollowBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +DistanceFieldFollowBehavior::act() +{ + //std::cout << "DistanceFieldFollowBehavior::act() begin\n"; + + if(mActivePar->value() <= 0.0) return; + + // input parameters + Eigen::VectorXf& position = mPositionPar->values(); + space::NeighborGroup& positionNeighbors = *mGridValues; + Eigen::VectorXf& velocity = mVelocityPar->values(); + + // output parameter + Eigen::VectorXf& force = mForcePar->backupValues(); + + // internal parameters + float& minDist = mMinDistPar->value(); + float& maxDist = mMaxDistPar->value(); + float& ortAmount = mOrtAmountPar->value(); + float& tanAmount = mTanAmountPar->value(); + float& amount = mAmountPar->value(); + + float distanceVectorLength; + float minDistanceVectorLength = FLT_MAX; + + unsigned int totalNeighborCount = positionNeighbors.neighborCount(); + unsigned int neighborCount = 0; + + if(totalNeighborCount == 0) return; + + for(unsigned int i=0; iposition(); + mDistanceVector = positionNeighbors.value(i); + distanceVectorLength = mDistanceVector.norm(); + + //std::cout << "dist vec " << mDistanceVector << " length " << distanceVectorLength << "\n"; + + if(minDist > 0.0 && distanceVectorLength < minDist) continue; + if(maxDist > 0.0 && distanceVectorLength > maxDist) continue; + + if(minDistanceVectorLength > distanceVectorLength) + { + minDistanceVectorLength = distanceVectorLength; + mOrtDirection = mDistanceVector; + } + + neighborCount++; + } + + if(neighborCount == 0) return; + + float ort2tanRatio = (minDistanceVectorLength - minDist) / (maxDist - minDist); + + mOrtDirection.normalize(); + mNormVelocity = velocity; + mNormVelocity.normalize(); + + mTangDirection = mNormVelocity - mOrtDirection * mOrtDirection.dot(mNormVelocity); + + ort2tanRatio = sqrt(ort2tanRatio); + + force += ( mOrtDirection * ortAmount * ort2tanRatio + mTangDirection * tanAmount * (1.0 - ort2tanRatio) ) * amount; + + //std::cout << "force " << force << "\n"; + + //std::cout << "DistanceFieldFollowBehavior::act() end\n"; +} \ No newline at end of file diff --git a/src/dab_flock_distance_field_follow_behavior.h b/src/dab_flock_distance_field_follow_behavior.h new file mode 100644 index 0000000..9f6e8fe --- /dev/null +++ b/src/dab_flock_distance_field_follow_behavior.h @@ -0,0 +1,109 @@ +/** \file dab_flock_distance_field_follow_behavior.h + * \class dab::flock::DistanceFieldFollowBehavior cause Agent to along a surface represented by a distance field + * \brief cause Agent to along a surface represented by a distance field + * + * The Behavior causes an Agent to move along the surface represented by a distance field\n + * The force created by the behavior acts both along the vectors of the distance field as well as tangential to them.\n + * The balance between the colinear and tangential force components depends on the length of the distance vector.\n + * The closer the distance vector length is to the value represented by the maximum distance parameter, the more the colinear component dominates.\n + * The closer the distance vector length is to the value represented by the minimum distance parameter, the more the tangention component dominates.\n + * \n + * Input Parameter:\n + * type: position dim: nD neighbors: required\n + * type: velocity dim: nD neighbors: ignore\n + * \n + * Output Parameter:\n + * type: force dim: nD write: add\n + * \n + * Internal Parameter:\n + * name: xxx_minDist dim: 1D defaultValue: 0.0\n + * name: xxx_maxDist dim: 1D defaultValue: 1.0\n + * name: xxx_amount dim: 1D defaultValue: 1.0\n + * name: xxx_active dim: 1D defaultValue: 0.1\n + * \n + * Created by Daniel Bisig on 9/23/07. + * Ported to OpenFrameworks by Daniel Bisig on 14/10/2017. + */ + +// TODO: Untested!! + +#ifndef _dab_flock_distance_field_follow_behavior_h_ +#define _dab_flock_distance_field_follow_behavior_h_ + +#include "dab_flock_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class DistanceFieldFollowBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + DistanceFieldFollowBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + DistanceFieldFollowBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~DistanceFieldFollowBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mPositionPar; /// \brief position parameter (input) + Parameter* mVelocityPar; /// \brief velocity parameter (input) + Parameter* mForcePar; /// \brief force parameter (output) + Parameter* mMinDistPar; /// \brief minimum distance parameter (internal) + Parameter* mMaxDistPar; /// \brief maximum distance parameter (internal) + Parameter* mOrtAmountPar; /// \brief behavior amount parameter (internal) + Parameter* mTanAmountPar; /// \brief behavior amount parameter (internal) + Parameter* mAmountPar; /// \brief behavior amount parameter (internal) + space::NeighborGroup* mGridValues; /// \brief grid values + + Eigen::VectorXf mOrtDirection; /// \brief force along distance vector + Eigen::VectorXf mTangDirection; /// \brief force perpendicular to distance vector + Eigen::VectorXf mDistanceVector; /// \brief distance to surface vector + Eigen::VectorXf mNormVelocity; /// \brief normalized velocity vector +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_env.cpp b/src/dab_flock_env.cpp new file mode 100644 index 0000000..f254eb0 --- /dev/null +++ b/src/dab_flock_env.cpp @@ -0,0 +1,227 @@ +/** \file dab_flock_env.cpp + */ + +#include "dab_flock_env.h" +#include "dab_flock_simulation.h" +#include "dab_space_neighbor_group_alg.h" +#include "dab_exception.h" + +using namespace dab; +using namespace dab::flock; + +Env::Env() +: Agent() +, mDim(0) +{} + +Env::Env(const std::string& pName, unsigned int pDim) +: Agent(pName) +, mDim(pDim) +{ + Simulation::get().addAgent(this); + Simulation::get().addEnv(this); +} + +Env::~Env() +{ + Simulation::get().removeAgent(this); + Simulation::get().removeEnv(this); +} + +unsigned int +Env::dim() const +{ + return mDim; +} + +void +Env::addParameter(const std::string& pParameterName, unsigned int pValueDim, const dab::Array& pSubdivisionCount, const Eigen::VectorXf& pMinPos, const Eigen::VectorXf& pMaxPos) throw (Exception) +{ + if( pSubdivisionCount.size() != mDim ) throw Exception("FLOCK ERROR: subdivision dimension " + std::to_string(pSubdivisionCount.size()) + " doesn't match environment dimension " + std::to_string(mDim), __FILE__, __FUNCTION__, __LINE__ ); + if( pMinPos.rows() != mDim ) throw Exception( "FLOCK ERROR: minPos dimension " + std::to_string(pMinPos.rows()) + " doesn't match environment dimension " + std::to_string(mDim), __FILE__, __FUNCTION__, __LINE__ ); + if( pMaxPos.rows() != mDim ) throw Exception( "FLOCK ERROR: maxPos dimension " + std::to_string(pMaxPos.rows()) + " doesn't match environment dimension " + std::to_string(mDim), __FILE__, __FUNCTION__, __LINE__ ); + + try + { + EnvParameter* parameter = new EnvParameter( this, pParameterName, pValueDim, pSubdivisionCount, pMinPos, pMaxPos ); + addParameter(parameter); + } + catch(Exception& e) + { + throw; + } +} + +void +Env::addParameter(const std::string& pParameterName, const Eigen::VectorXf& pValues, const dab::Array& pSubdivisionCount, const Eigen::VectorXf& pMinPos, const Eigen::VectorXf& pMaxPos) throw (Exception) +{ + if( pSubdivisionCount.size() != mDim ) throw Exception( "FLOCK ERROR: subdivision dimension " + std::to_string(pSubdivisionCount.size()) + " doesn't match environment dimension " + std::to_string(mDim), __FILE__, __FUNCTION__, __LINE__ ); + if( pMinPos.rows() != mDim ) throw Exception( "FLOCK ERROR: minPos dimension " + std::to_string(pMinPos.rows()) + " doesn't match environment dimension " + std::to_string(mDim), __FILE__, __FUNCTION__, __LINE__ ); + if( pMaxPos.rows() != mDim ) throw Exception( "FLOCK ERROR: maxPos dimension " + std::to_string(pMaxPos.rows()) + " doesn't match environment dimension " + std::to_string(mDim), __FILE__, __FUNCTION__, __LINE__ ); + + try + { + EnvParameter* parameter = new EnvParameter( this, pParameterName, pValues, pSubdivisionCount, pMinPos, pMaxPos ); + addParameter(parameter); + } + catch(Exception& e) + { + throw; + } +} + +void +Env::addParameter( std::shared_ptr pGridSpace, unsigned int pValueDim ) throw (Exception) +{ + try + { + EnvParameter* parameter = new EnvParameter( this, pGridSpace, pValueDim ); + addParameter(parameter); + } + catch(Exception& e) + { + throw; + } +} + +void +Env::setParameterValues(const std::string& pParameterName, const Eigen::VectorXf& pValues, const Eigen::VectorXf& pPosition, space::GridValueSetMode pSetMode) throw (Exception) +{ + try + { + Parameter* par = parameter(pParameterName); + EnvParameter* envPar = dynamic_cast( par ); + if(envPar != nullptr) envPar->set(pValues, pPosition, pSetMode); + else par->set(pValues); + } + catch(Exception& e) + { + throw; + } +} + +void +Env::changeParameterValues(const std::string& pParameterName, const Eigen::VectorXf& pValues, const Eigen::VectorXf& pPosition, space::GridValueSetMode pSetMode) throw (Exception) +{ + try + { + Parameter* par = parameter(pParameterName); + EnvParameter* envPar = dynamic_cast( par ); + if(envPar != nullptr) envPar->change(pValues, pPosition, pSetMode); + else par->change(pValues); + } + catch(Exception& e) + { + throw; + } +} + +void +Env::set(const std::string& pParameterName, float pParameterValue) throw (Exception) +{ + try + { + Agent::set( pParameterName, pParameterValue ); + } + catch( Exception& e ) + { + throw; + } +} + +void +Env::set(const std::string& pParameterName, const Eigen::VectorXf& pParameterValues) throw (Exception) +{ + try + { + Agent::set( pParameterName, pParameterValues ); + } + catch( Exception& e ) + { + throw; + } +} + +void +Env::set(const std::string& pParameterName, const math::VectorField& pValues) throw (Exception) +{ + try + { + Parameter* par = parameter(pParameterName); + EnvParameter* envPar = dynamic_cast( par ); + if(envPar != nullptr) + { + envPar->set( pValues ); + } + else throw Exception( "FLOCK ERROR: Environment paramter name " + pParameterName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +Env::randomize(const std::string& pParameterName, float pMinParameterValue, float pMaxParameterValue) throw (Exception) +{ + try + { + Agent::randomize( pParameterName, pMinParameterValue, pMaxParameterValue ); + } + catch(Exception& e) + { + throw; + } +} + +void +Env::randomize(const std::string& pParameterName, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues) throw (Exception) +{ + try + { + Agent::randomize( pParameterName, pMinParameterValues, pMaxParameterValues ); + } + catch(Exception& e) + { + throw; + } +} + +void +Env::randomize(const std::string& pParameterName, float pMinParameterValue, float pMaxParameterValue, float pThresholdValue ) throw (Exception) +{ + try + { + Parameter* par = parameter(pParameterName); + EnvParameter* envPar = dynamic_cast( par ); + if(envPar != nullptr) + { + envPar->randomize( pMinParameterValue, pMaxParameterValue, pThresholdValue ); + } + else throw Exception( "FLOCK ERROR: Environment paramter name " + pParameterName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +Env::randomize(const std::string& pParameterName, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues, const Eigen::VectorXf& pThresholdValues) throw (Exception) +{ + try + { + Parameter* par = parameter(pParameterName); + EnvParameter* envPar = dynamic_cast( par ); + if(envPar != nullptr) + { + envPar->randomize( pMinParameterValues, pMaxParameterValues, pThresholdValues ); + } + else throw Exception( "FLOCK ERROR: Environment paramter name " + pParameterName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + diff --git a/src/dab_flock_env.h b/src/dab_flock_env.h new file mode 100644 index 0000000..9d4543e --- /dev/null +++ b/src/dab_flock_env.h @@ -0,0 +1,178 @@ +/** \file dab_flock_env.h + * + * Created by Daniel Bisig on 2/21/09. + * Ported to OpenFrameworks by Daniel Bisig on 10/08/17. + */ + +#ifndef _dab_flock_env_h_ +#define _dab_flock_env_h_ + +#include "dab_exception.h" +#include "dab_array.h" +#include "dab_index_map.h" +#include "dab_space_grid.h" +#include "dab_flock_agent.h" +#include "dab_flock_env_parameter.h" +#include + +namespace dab +{ + +namespace flock +{ + +class Env : public Agent +{ +public: + /** + \brief create environment + */ + Env(const std::string& pName, unsigned int pDim); + + /** + \brief destructor + */ + ~Env(); + + /** + \brief clear environment + \remark triggers destructor + */ + void clear(); + + unsigned int dim() const; + + using Agent::addParameter; + + /** + \brief create parameter + \param pParameterName parameter name + \param pValueDim parameter value dimension + \param pSubdivisionCount parameter grid value subdivision count + \param pMinPos paramter grid minimum position + \param pMaxPos parameter grid maximum position + \exception Exception failed to add parameter + */ + void addParameter(const std::string& pParameterName, unsigned int pValueDim, const dab::Array& pSubdivisionCount, const Eigen::VectorXf& pMinPos, const Eigen::VectorXf& pMaxPos) throw (Exception); + + /** + \brief create parameter + \param pParameterName parameter name + \param pValues parameter values + \param pSubdivisionCount parameter grid value subdivision count + \param pMinPos paramter grid minimum position + \param pMaxPos parameter grid maximum position + \exception Exception failed to add parameter + */ + void addParameter(const std::string& pParameterName, const Eigen::VectorXf& pValues, const dab::Array& pSubdivisionCount, const Eigen::VectorXf& pMinPos, const Eigen::VectorXf& pMaxPos) throw (Exception); + + /** + \brief create parameter + \param pGridSpace grid space + \param pValueDim parameter value dimension + \exception Exception failed to add parameter + */ + void addParameter( std::shared_ptr pGridSpace, unsigned int pValueDim ) throw (Exception); + + /** + \brief set parameter values + \param pParameterName parameter name + \param pValues parameter values + \param pPosition position of parameter values + \param pSetMode set mode + \exception Exception failed to set parameter + */ + void setParameterValues(const std::string& pParameterName, const Eigen::VectorXf& pValues, const Eigen::VectorXf& pPosition, space::GridValueSetMode pSetMode) throw (Exception); + + /** + \brief change parameter values + \param pParameterName parameter name + \param pValues parameter values + \param pPosition position of parameter values + \param pSetMode set mode + \exception Exception FlockException failed to set parameter + */ + void changeParameterValues(const std::string& pParameterName, const Eigen::VectorXf& pValues, const Eigen::VectorXf& pPosition, space::GridValueSetMode pSetMode) throw (Exception); + + /** + \brief set parameter values + \param pParameterName parameter name + \param pParameterValue parameter value + \exception Exception parameter name is not found + */ + void set(const std::string& pParameterName, float pParameterValue) throw (Exception); + + /** + \brief set parameter values + \param pParameterName parameter name + \param pParameterValues parameter values + \exception Exception parameter name is not found or parameter values has wrong dimension + */ + void set(const std::string& pParameterName, const Eigen::VectorXf& pParameterValues) throw (Exception); + + /** + \brief set parameter values + \param pParameterName parameter name + \param pValues parameter values + \param pPosition position of parameter values + \param pSetMode set mode + \exception Exception failed to set parameter + */ + void set(const std::string& pParameterName, const math::VectorField& pValues) throw (Exception); + + /** + \brief randomize parameter value + \param pParameterName parameter name + \param pMinParameterValue minimum parameter value + \param pMaxParameterValue maximum parameter value + \exception Exception parameter name not found + */ + void randomize(const std::string& pParameterName, float pMinParameterValue, float pMaxParameterValue) throw (Exception); + + /** + \brief randomize parameter values + \param pParameterName parameter name + \param pMinParameterValues minimum parameter values + \param pMaxParameterValues maximum parameter values + \exception Exception parameter name not found or parameter values has wrong dimension + */ + void randomize(const std::string& pParameterName, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues) throw (Exception); + + /** + \brief randomize parameter value + \param pParameterName parameter name + \param pMinParameterValue minimum parameter value + \param pMaxParameterValue maximum parameter value + \param pThresholdValue threshold value + \exception Exception parameter name not found + + salt and pepper randomization. If random number between 0.0 and 1.0 is below threshold, the parameter will be set to min value, otherwise it will be set to max value + */ + void randomize(const std::string& pParameterName, float pMinParameterValue, float pMaxParameterValue, float pThresholdValue) throw (Exception); + + /** + \brief randomize parameter values + \param pParameterName parameter name + \param pMinParameterValues minimum parameter values + \param pMaxParameterValues maximum parameter values + \param pThresholdValues threshold values + \exception Exception parameter name not found or parameter values has wrong dimension + + salt and pepper randomization. If random number between 0.0 and 1.0 is below threshold, the parameter will be set to min value, otherwise it will be set to max value + */ + void randomize(const std::string& pParameterName, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues, const Eigen::VectorXf& pThresholdValues) throw (Exception); + +protected: + /** + \brief default constructor + */ + Env(); + + unsigned int mDim; ///\brief dimension of environments +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_env_agent_interact_behavior.cpp b/src/dab_flock_env_agent_interact_behavior.cpp new file mode 100644 index 0000000..60caddd --- /dev/null +++ b/src/dab_flock_env_agent_interact_behavior.cpp @@ -0,0 +1,97 @@ +/** \file dab_flock_env_agent_interact_behavior.cpp + */ + +#include "dab_flock_env_agent_interact_behavior.h" +#include "dab_flock_env.h" +#include "dab_flock_swarm.h" + +using namespace dab; +using namespace dab::flock; + +EnvAgentInteractBehavior::EnvAgentInteractBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: EnvBehavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "EnvAgentInteractBehavior"; +} + +EnvAgentInteractBehavior::EnvAgentInteractBehavior(Env* pEnv, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) +: EnvBehavior(pEnv, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "EnvAgentInteractBehavior"; + + // input parameter + mEnvPar = dynamic_cast( mInputParameters[0] ); + + if( mEnvPar == nullptr ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " is not an environment parameter", __FILE__, __FUNCTION__, __LINE__ ); + + mAgentParName = mInputAgentParameterNames[mInputParameters[0]->name()][0]; + + // create internal parameters + unsigned int envValueDim = mEnvPar->valueDim(); + mAmountPar = createInternalParameter("amount", envValueDim, 1.0 ); +} + +EnvAgentInteractBehavior::~EnvAgentInteractBehavior() +{} + +Behavior* +EnvAgentInteractBehavior::create(const std::string& pBehaviorName, Agent* pEnv) const +{ + try + { + Env* env = dynamic_cast(pEnv); + + if(env != nullptr) + { + return new EnvAgentInteractBehavior(env, pBehaviorName, mInputParameterString, mOutputParameterString); + } + else return new EnvAgentInteractBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +EnvAgentInteractBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + return new EnvAgentInteractBehavior(pInputParameterString, pOutputParameterString); +} + +void +EnvAgentInteractBehavior::act() +{ + //std::cout << "TerrainDepressionBehavior::act() begin\n"; + + //space::SpaceGrid& envGrid = mEnvPar->backupGrid(); + const Eigen::VectorXf& amount = mAmountPar->values(); + + std::shared_ptr envSpace = mEnvPar->space(); + std::vector spaceObjects; + mEnvPar->spaceObjects( spaceObjects ); + + unsigned oC = spaceObjects.size(); + + for(unsigned int oI=0; oI( spaceObjects[oI] ); + if(agentPositionPar == nullptr) continue; + Agent* agent = agentPositionPar->agent(); + if( dynamic_cast(agent) != nullptr ) continue; + + // get agent parameter values + const Eigen::VectorXf& agentPosition = agentPositionPar->values(); + const Eigen::VectorXf& agentParValue = agent->parameter( mAgentParName )->values(); + + //std::cout << "agent " << oI << " name " << agent->name().toStdString() << " par " << agentPositionPar->name().toStdString() << " value "<< agentPosition << " weight " << agentWeight << "\n"; + + // change grid + mEnvPar->change( agentPosition, agentParValue * amount, space::Interpol ); + } + + //mEnvPar->flush(); + + //std::cout << "TerrainDepressionBehavior::act() end\n"; +} \ No newline at end of file diff --git a/src/dab_flock_env_agent_interact_behavior.h b/src/dab_flock_env_agent_interact_behavior.h new file mode 100644 index 0000000..097e347 --- /dev/null +++ b/src/dab_flock_env_agent_interact_behavior.h @@ -0,0 +1,53 @@ +/** \file dab_flock_env_agent_interact_behavior.h + */ + +#ifndef _dab_flock_env_agent_interact_behavior_h_ +#define _dab_flock_env_agent_interact_behavior_h_ + +#include "dab_flock_env_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class EnvAgentInteractBehavior : public EnvBehavior +{ +public: + EnvAgentInteractBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + EnvAgentInteractBehavior(Env* pEnv, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString); + ~EnvAgentInteractBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception FlockException wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const; + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + void act(); + +protected: + EnvParameter* mEnvPar; // input par + Parameter* mAmountPar; // interal par + std::string mAgentParName; // agent input par + + +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_env_behavior.cpp b/src/dab_flock_env_behavior.cpp new file mode 100644 index 0000000..f4be497 --- /dev/null +++ b/src/dab_flock_env_behavior.cpp @@ -0,0 +1,158 @@ +/** \file iso_flock_env_behavior.cpp + * + * Created by Daniel Bisig on 2/22/09. + */ + +#include "dab_flock_env_behavior.h" +#include "dab_flock_env.h" +#include "dab_tokenizer.h" + +using namespace dab; +using namespace dab::flock; + +EnvBehavior::EnvBehavior() + : Behavior() + , mEnv(nullptr) +{ + mClassName = "EnvBehavior"; +} + +EnvBehavior::EnvBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) + : Behavior(pInputParameterString, pOutputParameterString) + , mEnv(NULL) +{ + mClassName = "EnvBehavior"; +} + +EnvBehavior::EnvBehavior(Env* pEnv, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) + : Behavior(pInputParameterString, pOutputParameterString) + , mEnv(pEnv) +{ + mName = pBehaviorName; + mClassName = "EnvBehavior"; + mAgent = pEnv; + + mActivePar = createInternalParameter("active", { 1.0 }); + + createInputParameters(); + createOutputParameters(); +} + +EnvBehavior::~EnvBehavior() +{ + mInputAgentParameterNames.clear(); + mOutputAgentParameterNames.clear(); +} + +void +EnvBehavior::createInputParameters() throw (Exception) +{ + //std::cout << "EnvBehavior createInputParameters begin\n"; + + try + { + Tokenizer& tokenizer = Tokenizer::get(); + std::vector inputParameterNames; + tokenizer.split(mInputParameterString, inputParameterNames, ' '); + unsigned int inputParameterCount = inputParameterNames.size(); + + for(unsigned int i=0; i envParSplit; + tokenizer.split(inputParameterNames[i], envParSplit, ':'); + unsigned int envParSplitCount = envParSplit.size(); + + Parameter* envParameter = mEnv->parameter( envParSplit[0]); + + mInputParameters.push_back( envParameter ); + + // agent parameters associated with env parameter + if( dynamic_cast(envParameter) != nullptr && envParSplitCount >= 2) + { + std::vector agentParSplit; + tokenizer.split(envParSplit[1], agentParSplit, ','); + unsigned int agentParameterCount = agentParSplit.size(); + const std::string& envParameterName = envParameter->name(); + + mInputAgentParameterNames[envParameterName] = std::vector(); + + for(unsigned int j=0; j outputParameterNames; + tokenizer.split(mOutputParameterString, outputParameterNames, ' '); + unsigned int outputParameterCount = outputParameterNames.size(); + + for(unsigned int i=0; i envParSplit; + tokenizer.split(outputParameterNames[i], envParSplit, ':'); + unsigned int envParSplitCount = envParSplit.size(); + Parameter* envParameter = mEnv->parameter( envParSplit[0]); + + mOutputParameters.push_back( envParameter ); + + // agent parameters associated with env parameter + if( dynamic_cast(envParameter) != NULL && envParSplitCount >= 2) + { + std::vector agentParSplit; + tokenizer.split(envParSplit[1], agentParSplit, ','); + unsigned int agentParameterCount = agentParSplit.size(); + + const std::string& envParameterName = envParameter->name(); + + mOutputAgentParameterNames[envParameterName] = std::vector(); + + for(unsigned int j=0; j0: limited proceeding) + */ + virtual std::string info(int pPropagationLevel = 0) const; + + /** + \brief retrieve textual behavior info + \param pOstream output text stream + \param pBehavior behavior + */ + friend std::ostream& operator << ( std::ostream& pOstream, const EnvBehavior& pBehavior ) + { + pOstream << pBehavior.info(); + + return pOstream; + }; + +protected: + /** + \brief default constructor + */ + EnvBehavior(); + + /** + \brief create input behavior parameters + \exception Exception failed to create input parameters + */ + virtual void createInputParameters() throw (Exception); + + /** + \brief create output behavior parameters + \exception Exception failed to create output parameters + */ + virtual void createOutputParameters() throw (Exception); + + /** + \brief create internal behavior parameter + \param pParameterName name of parameter + \param pValues values of parameter + \return parameter + + creates an internal behavior parameter which is visible at the level of the agent (i.e. other behaviors can access it).\n + the name of the parameter is constructed as follows: behaviorName_parameterName.\n + */ + // Parameter* createInternalParameter(const base::String& pParameterName, const math::Vector& pValues); + + Env* mEnv; /// \brief environment this behavior belongs to + + std::map< std::string, std::vector > mInputAgentParameterNames; + std::map< std::string, std::vector > mOutputAgentParameterNames; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_env_clamp_behavior.cpp b/src/dab_flock_env_clamp_behavior.cpp new file mode 100644 index 0000000..8e66d33 --- /dev/null +++ b/src/dab_flock_env_clamp_behavior.cpp @@ -0,0 +1,107 @@ +/** \file dab_flock_env_clamp_behavior.cpp + */ + +#include "dab_flock_env_clamp_behavior.h" +#include "dab_flock_env.h" +#include "dab_flock_swarm.h" + +using namespace dab; +using namespace dab::flock; + +EnvClampBehavior::EnvClampBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: EnvBehavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "EnvClampBehavior"; +} + +EnvClampBehavior::EnvClampBehavior(Env* pEnv, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) +: EnvBehavior(pEnv, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "EnvClampBehavior"; + + if( mInputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mInputEnvPar = dynamic_cast( mInputParameters[0] ); + + // output parameter + mOutputEnvPar = dynamic_cast( mOutputParameters[0] ); + + if( mInputEnvPar == nullptr ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " is not an environment parameter", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputEnvPar == nullptr ) throw Exception( "FLOCK ERROR: output parameter " + mOutputParameters[0]->name() + " is not an environment parameter", __FILE__, __FUNCTION__, __LINE__ ); + + unsigned int inputGridDim = mInputEnvPar->gridDim(); + unsigned int inputValueDim = mInputEnvPar->valueDim(); + const dab::Array& inputGridSize = mInputEnvPar->gridSize(); + + unsigned int outputGridDim = mOutputEnvPar->gridDim(); + unsigned int outputValueDim = mOutputEnvPar->valueDim(); + const dab::Array& outputGridSize = mOutputEnvPar->gridSize(); + + if( inputGridDim != outputGridDim ) throw Exception( "FLOCK ERROR: input environment parameter " + mInputEnvPar->name() + " grid dimension " + std::to_string(inputGridDim) + " does not match output environment parameter " + mOutputEnvPar->name() + " grid dimension " + std::to_string(outputGridDim), __FILE__, __FUNCTION__, __LINE__ ); + if( inputValueDim != outputValueDim ) throw Exception( "FLOCK ERROR: input environment parameter " + mInputEnvPar->name() + " value dimension " + std::to_string(inputValueDim) + " does not match output environment parameter " + mOutputEnvPar->name() + " value dimension " + std::to_string(outputValueDim), __FILE__, __FUNCTION__, __LINE__ ); + + if( inputGridSize != outputGridSize ) throw Exception( "FLOCK ERROR: input environment parameter " + mInputEnvPar->name() + " grid size " + inputGridSize.info() + " does not match output environment parameter " + mOutputEnvPar->name() + " grid size " + outputGridSize.info(), __FILE__, __FUNCTION__, __LINE__ ); + + // create internal parameters + mClampMinPar = createInternalParameter("clampMin", inputValueDim, 0.0 ); + mClampMaxPar = createInternalParameter("clampMax", inputValueDim, 1.0 ); +} + +EnvClampBehavior::~EnvClampBehavior() +{} + +Behavior* +EnvClampBehavior::create(const std::string& pBehaviorName, Agent* pEnv) const +{ + try + { + Env* env = dynamic_cast(pEnv); + + if(env != nullptr) + { + return new EnvClampBehavior(env, pBehaviorName, mInputParameterString, mOutputParameterString); + } + else return new EnvClampBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +EnvClampBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + return new EnvClampBehavior(pInputParameterString, pOutputParameterString); +} + +void +EnvClampBehavior::act() +{ + space::SpaceGrid* inputGrid = mInputEnvPar->grid(); + space::SpaceGrid* outputGrid = mOutputEnvPar->backupGrid(); + Eigen::VectorXf& clampMin = mClampMinPar->values(); + Eigen::VectorXf& clampMax = mClampMaxPar->values(); + + math::VectorField& inputField = inputGrid->vectorField(); + math::VectorField& outputField = outputGrid->vectorField(); + std::vector< Eigen::VectorXf >& inputVectors = inputField.vectors(); + std::vector< Eigen::VectorXf >& outputVectors = outputField.vectors(); + unsigned int vectorCount = inputField.vectorCount(); + unsigned int vectorDim = inputField.vectorDim(); + + for( int vI=0; vI clampMax[d] ) outputVectors[vI][d] = clampMax[d]; + } + } + + mOutputEnvPar->flush(); +} \ No newline at end of file diff --git a/src/dab_flock_env_clamp_behavior.h b/src/dab_flock_env_clamp_behavior.h new file mode 100644 index 0000000..429ae99 --- /dev/null +++ b/src/dab_flock_env_clamp_behavior.h @@ -0,0 +1,53 @@ +/** \file dab_flock_env_clamp_behavior.h + */ + +#ifndef _dab_flock_env_clamp_behavior_h_ +#define _dab_flock_env_clamp_behavior_h_ + +#include "dab_flock_env_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class EnvClampBehavior : public EnvBehavior +{ +public: + EnvClampBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + EnvClampBehavior(Env* pEnv, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString); + ~EnvClampBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception FlockException wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const; + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + void act(); + +protected: + EnvParameter* mInputEnvPar; // input environment parameter + Parameter* mClampMinPar; // internal parameter + Parameter* mClampMaxPar; // internal parameter + EnvParameter* mOutputEnvPar; // output environment parameter + +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_env_decay_behavior.cpp b/src/dab_flock_env_decay_behavior.cpp new file mode 100644 index 0000000..166828c --- /dev/null +++ b/src/dab_flock_env_decay_behavior.cpp @@ -0,0 +1,101 @@ +/** \file dab_flock_env_decay_behavior.cpp + */ + +#include "dab_flock_env_decay_behavior.h" +#include "dab_flock_env.h" +#include "dab_flock_swarm.h" + +using namespace dab; +using namespace dab::flock; + +EnvDecayBehavior::EnvDecayBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: EnvBehavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "EnvDecayBehavior"; +} + +EnvDecayBehavior::EnvDecayBehavior(Env* pEnv, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) +: EnvBehavior(pEnv, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "EnvDecayBehavior"; + + if( mInputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mInputEnvPar = dynamic_cast( mInputParameters[0] ); + + // output parameter + mOutputEnvPar = dynamic_cast( mOutputParameters[0] ); + + if( mInputEnvPar == nullptr ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " is not an environment parameter", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputEnvPar == nullptr ) throw Exception( "FLOCK ERROR: output parameter " + mOutputParameters[0]->name() + " is not an environment parameter", __FILE__, __FUNCTION__, __LINE__ ); + + unsigned int inputGridDim = mInputEnvPar->gridDim(); + unsigned int inputValueDim = mInputEnvPar->valueDim(); + const dab::Array& inputGridSize = mInputEnvPar->gridSize(); + + unsigned int outputGridDim = mOutputEnvPar->gridDim(); + unsigned int outputValueDim = mOutputEnvPar->valueDim(); + const dab::Array& outputGridSize = mOutputEnvPar->gridSize(); + + if( inputGridDim != outputGridDim ) throw Exception( "FLOCK ERROR: input environment parameter " + mInputEnvPar->name() + " grid dimension " + std::to_string(inputGridDim) + " does not match output environment parameter " + mOutputEnvPar->name() + " grid dimension " + std::to_string(outputGridDim), __FILE__, __FUNCTION__, __LINE__ ); + if( inputValueDim != outputValueDim ) throw Exception( "FLOCK ERROR: input environment parameter " + mInputEnvPar->name() + " value dimension " + std::to_string(inputValueDim) + " does not match output environment parameter " + mOutputEnvPar->name() + " value dimension " + std::to_string(outputValueDim), __FILE__, __FUNCTION__, __LINE__ ); + if( inputGridSize != outputGridSize ) throw Exception( "FLOCK ERROR: input environment parameter " + mInputEnvPar->name() + " grid size " + inputGridSize.info() + " does not match output environment parameter " + mOutputEnvPar->name() + " grid size " + outputGridSize.info(), __FILE__, __FUNCTION__, __LINE__ ); + + // create internal parameters + mDecayPar = createInternalParameter("decay", { 0.01f } ); +} + +EnvDecayBehavior::~EnvDecayBehavior() +{} + +Behavior* +EnvDecayBehavior::create(const std::string& pBehaviorName, Agent* pEnv) const +{ + try + { + Env* env = dynamic_cast(pEnv); + + if(env != nullptr) + { + return new EnvDecayBehavior(env, pBehaviorName, mInputParameterString, mOutputParameterString); + } + else return new EnvDecayBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +EnvDecayBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + return new EnvDecayBehavior(pInputParameterString, pOutputParameterString); +} + +void +EnvDecayBehavior::act() +{ + space::SpaceGrid* inputGrid = mInputEnvPar->grid(); + space::SpaceGrid* outputGrid = mOutputEnvPar->backupGrid(); + Eigen::VectorXf decay = mDecayPar->values(); + + math::VectorField& inputField = inputGrid->vectorField(); + math::VectorField& outputField = outputGrid->vectorField(); + std::vector& inputVectors = inputField.vectors(); + std::vector& outputVectors = outputField.vectors(); + unsigned int vectorCount = inputField.vectorCount(); + unsigned int vectorDim = inputField.vectorDim(); + + for( int vI=0; vI( mInputParameters[0] ); + + // output parameter + mOutputEnvPar = dynamic_cast( mOutputParameters[0] ); + + if( mInputEnvPar == NULL ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " is not an environment parameter", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputEnvPar == NULL ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[1]->name() + " is not an environment parameter", __FILE__, __FUNCTION__, __LINE__ ); + + unsigned int inputGridDim = mInputEnvPar->gridDim(); + unsigned int inputValueDim = mInputEnvPar->valueDim(); + const dab::Array& inputGridSize = mInputEnvPar->gridSize(); + + if( mOutputEnvPar->gridDim() != inputGridDim ) throw Exception( "FLOCK ERROR: grid dimensions of parameters don't match", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputEnvPar->valueDim() != inputValueDim ) throw Exception( "FLOCK ERROR: value dimensions of parameters don't match", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputEnvPar->gridSize() != inputGridSize ) throw Exception( "FLOCK ERROR: grid size of parameters don't match", __FILE__, __FUNCTION__, __LINE__ ); + + // create internal parameter + mDiffusionPar = createInternalParameter("diffusion", inputValueDim, 0.01 ); +} + +EnvDiffusionBehavior::~EnvDiffusionBehavior() +{} + +Behavior* +EnvDiffusionBehavior::create(const std::string& pBehaviorName, Agent* pEnv) const +{ + try + { + Env* env = dynamic_cast(pEnv); + + if(env != NULL) + { + return new EnvDiffusionBehavior(env, pBehaviorName, mInputParameterString, mOutputParameterString); + } + else return new EnvDiffusionBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +EnvDiffusionBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + return new EnvDiffusionBehavior(pInputParameterString, pOutputParameterString); +} + +void +EnvDiffusionBehavior::act() +{ + space::SpaceGrid* inputGrid = mInputEnvPar->grid(); + space::SpaceGrid* outputGrid = mOutputEnvPar->backupGrid(); + const Eigen::VectorXf& diffusion = mDiffusionPar->values(); + + math::VectorField& inputField = inputGrid->vectorField(); + math::VectorField& outputField = outputGrid->vectorField(); + std::vector& inputVectors = inputField.vectors(); + std::vector& outputVectors = outputField.vectors(); + unsigned int vectorCount = inputField.vectorCount(); + unsigned int vectorDim = inputField.vectorDim(); + + const dab::Array& gridSize = inputField.size(); + + // 2D grids only for the moment + if( gridSize.size() != 2 ) return; + + int vI; + int gridWidth = gridSize[0]; + int gridHeight = gridSize[1]; + int gridWidth_1 = gridWidth - 1; + int gridHeight_1 = gridHeight - 1; + Eigen::VectorXf gridValue( vectorDim ); + + // boundary conditions : corners + // top left + vI = 0; + //std::cout << "top left vI\n" << vI << "\n"; + for(int d=0; dflush(); +} \ No newline at end of file diff --git a/src/dab_flock_env_diffusion_behavior.h b/src/dab_flock_env_diffusion_behavior.h new file mode 100644 index 0000000..eda0ba0 --- /dev/null +++ b/src/dab_flock_env_diffusion_behavior.h @@ -0,0 +1,52 @@ +/** \file dab_flock_env_diffusion_behavior.h + */ + +#ifndef _dab_flock_env_diffusion_behavior_h_ +#define _dab_flock_env_diffusion_behavior_h_ + +#include "dab_flock_env_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class EnvDiffusionBehavior : public EnvBehavior +{ +public: + EnvDiffusionBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + EnvDiffusionBehavior(Env* pEnv, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString); + ~EnvDiffusionBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception FlockException wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const; + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + void act(); + +protected: + EnvParameter* mInputEnvPar; // input environment parameter + Parameter* mDiffusionPar; // internal parameter + EnvParameter* mOutputEnvPar; // output environment parameter + +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_env_gierer_meinhardt_behavior.cpp b/src/dab_flock_env_gierer_meinhardt_behavior.cpp new file mode 100644 index 0000000..9db89db --- /dev/null +++ b/src/dab_flock_env_gierer_meinhardt_behavior.cpp @@ -0,0 +1,122 @@ +/** \file dab_flock_env_gierer_meinhardt_behavior.cpp + */ + +#include "dab_flock_env_gierer_meinhardt_behavior.h" +#include "dab_flock_env.h" +#include "dab_flock_swarm.h" + +using namespace dab; +using namespace dab::flock; + +EnvGiererMeinhardtBehavior::EnvGiererMeinhardtBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: EnvBehavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "EnvGiererMeinhardtBehavior"; +} + +EnvGiererMeinhardtBehavior::EnvGiererMeinhardtBehavior(Env* pEnv, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) +: EnvBehavior(pEnv, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "EnvGiererMeinhardtBehavior"; + + if( mInputParameters.size() < 2 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(2) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 2 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(2) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mInputChem1Par = dynamic_cast( mInputParameters[0] ); + mInputChem2Par = dynamic_cast( mInputParameters[1] ); + + // output parameter + mOutputChem1Par = dynamic_cast( mOutputParameters[0] ); + mOutputChem2Par = dynamic_cast( mOutputParameters[1] ); + + if( mInputChem1Par == nullptr ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " is not an environment parameter", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputChem2Par == nullptr ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[1]->name() + " is not an environment parameter", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputChem1Par == nullptr ) throw Exception( "FLOCK ERROR: output parameter " + mOutputParameters[0]->name() + " is not an environment parameter", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputChem2Par == nullptr ) throw Exception( "FLOCK ERROR: output parameter " + mOutputParameters[1]->name() + " is not an environment parameter", __FILE__, __FUNCTION__, __LINE__ ); + + unsigned int chemGridDim = mInputChem1Par->gridDim(); + unsigned int chemValueDim = mInputChem1Par->valueDim(); + const dab::Array& chemGridSize = mInputChem1Par->gridSize(); + + if( mInputChem2Par->gridDim() != chemGridDim || mOutputChem1Par->gridDim() != chemGridDim || mOutputChem2Par->gridDim() != chemGridDim) throw Exception( "FLOCK ERROR: grid dimensions of parameters don't match", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputChem2Par->valueDim() != chemValueDim || mOutputChem1Par->valueDim() != chemValueDim || mOutputChem2Par->valueDim() != chemValueDim) throw Exception( "FLOCK ERROR: value dimensions of parameters don't match", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputChem2Par->gridSize() != chemGridSize || mOutputChem1Par->gridSize() != chemGridSize || mOutputChem2Par->gridSize() != chemGridSize) throw Exception( "FLOCK ERROR: grid size of parameters don't match", __FILE__, __FUNCTION__, __LINE__ ); + + // create internal parameters + mChem1ProdPar = createInternalParameter("chem1Production", chemValueDim, 0.01 ); + mChem2ProdPar = createInternalParameter("chem2Production", chemValueDim, 0.01 ); + mChem1DecayPar = createInternalParameter("chem1Decay", chemValueDim, 0.15 ); + mChem2DecayPar = createInternalParameter("chem2Decay", chemValueDim, 0.1 ); + mReactRatePar = createInternalParameter("reactionRate", chemValueDim, 0.1 ); +} + +EnvGiererMeinhardtBehavior::~EnvGiererMeinhardtBehavior() +{} + +Behavior* +EnvGiererMeinhardtBehavior::create(const std::string& pBehaviorName, Agent* pEnv) const +{ + try + { + Env* env = dynamic_cast(pEnv); + + if(env != NULL) + { + return new EnvGiererMeinhardtBehavior(env, pBehaviorName, mInputParameterString, mOutputParameterString); + } + else return new EnvGiererMeinhardtBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +EnvGiererMeinhardtBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + return new EnvGiererMeinhardtBehavior(pInputParameterString, pOutputParameterString); +} + +void +EnvGiererMeinhardtBehavior::act() +{ + space::SpaceGrid* inputChem1Grid = mInputChem1Par->grid(); + space::SpaceGrid* inputChem2Grid = mInputChem2Par->grid(); + space::SpaceGrid* outputChem1Grid = mOutputChem1Par->backupGrid(); + space::SpaceGrid* outputChem2Grid = mOutputChem2Par->backupGrid(); + const Eigen::VectorXf& chem1Prod = mChem1ProdPar->values(); + const Eigen::VectorXf& chem2Prod = mChem2ProdPar->values(); + const Eigen::VectorXf& chem1Decay = mChem1DecayPar->values(); + const Eigen::VectorXf& chem2Decay = mChem2DecayPar->values(); + const Eigen::VectorXf& reactRate = mReactRatePar->values(); + math::VectorField& inputChem1Field = inputChem1Grid->vectorField(); + math::VectorField& inputChem2Field = inputChem2Grid->vectorField(); + math::VectorField& outputChem1Field = outputChem1Grid->vectorField(); + math::VectorField& outputChem2Field = outputChem2Grid->vectorField(); + std::vector& inputChem1Vectors = inputChem1Field.vectors(); + std::vector& inputChem2Vectors = inputChem2Field.vectors(); + std::vector& outputChem1Vectors = outputChem1Field.vectors(); + std::vector& outputChem2Vectors = outputChem2Field.vectors(); + + unsigned int vectorCount = inputChem1Field.vectorCount(); + unsigned int vectorDim = inputChem1Field.vectorDim(); + float conc1, conc2, conc11; + + for( int vI=0; vI( mInputParameters[0] ); + mInputChem2Par = dynamic_cast( mInputParameters[1] ); + + // output parameter + mOutputChem1Par = dynamic_cast( mOutputParameters[0] ); + mOutputChem2Par = dynamic_cast( mOutputParameters[1] ); + + if( mInputChem1Par == nullptr ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " is not an environment parameter", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputChem2Par == nullptr ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[1]->name() + " is not an environment parameter", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputChem1Par == nullptr ) throw Exception( "FLOCK ERROR: output parameter " + mOutputParameters[0]->name() + " is not an environment parameter", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputChem2Par == nullptr ) throw Exception( "FLOCK ERROR: output parameter " + mOutputParameters[1]->name() + " is not an environment parameter", __FILE__, __FUNCTION__, __LINE__ ); + + unsigned int chemGridDim = mInputChem1Par->gridDim(); + unsigned int chemValueDim = mInputChem1Par->valueDim(); + const dab::Array& chemGridSize = mInputChem1Par->gridSize(); + + if( mInputChem2Par->gridDim() != chemGridDim || mOutputChem1Par->gridDim() != chemGridDim || mOutputChem2Par->gridDim() != chemGridDim) throw Exception( "FLOCK ERROR: grid dimensions of parameters don't match", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputChem2Par->valueDim() != chemValueDim || mOutputChem1Par->valueDim() != chemValueDim || mOutputChem2Par->valueDim() != chemValueDim) throw Exception( "FLOCK ERROR: value dimensions of parameters don't match", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputChem2Par->gridSize() != chemGridSize || mOutputChem1Par->gridSize() != chemGridSize || mOutputChem2Par->gridSize() != chemGridSize) throw Exception( "FLOCK ERROR: grid size of parameters don't match", __FILE__, __FUNCTION__, __LINE__ ); + + // create internal parameters + mFPar = createInternalParameter("F", chemValueDim, 0.1 ); + mKPar = createInternalParameter("k", chemValueDim, 0.1 ); +} + +EnvGrayScottBehavior::~EnvGrayScottBehavior() +{} + +Behavior* +EnvGrayScottBehavior::create(const std::string& pBehaviorName, Agent* pEnv) const +{ + try + { + Env* env = dynamic_cast(pEnv); + + if(env != nullptr) + { + return new EnvGrayScottBehavior(env, pBehaviorName, mInputParameterString, mOutputParameterString); + } + else return new EnvGrayScottBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +EnvGrayScottBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + return new EnvGrayScottBehavior(pInputParameterString, pOutputParameterString); +} + +void +EnvGrayScottBehavior::act() +{ + space::SpaceGrid* inputChem1Grid = mInputChem1Par->grid(); + space::SpaceGrid* inputChem2Grid = mInputChem2Par->grid(); + space::SpaceGrid* outputChem1Grid = mOutputChem1Par->backupGrid(); + space::SpaceGrid* outputChem2Grid = mOutputChem2Par->backupGrid(); + const Eigen::VectorXf& F = mFPar->values(); + const Eigen::VectorXf& k = mKPar->values(); + math::VectorField& inputChem1Field = inputChem1Grid->vectorField(); + math::VectorField& inputChem2Field = inputChem2Grid->vectorField(); + math::VectorField& outputChem1Field = outputChem1Grid->vectorField(); + math::VectorField& outputChem2Field = outputChem2Grid->vectorField(); + std::vector& inputChem1Vectors = inputChem1Field.vectors(); + std::vector& inputChem2Vectors = inputChem2Field.vectors(); + std::vector& outputChem1Vectors = outputChem1Field.vectors(); + std::vector& outputChem2Vectors = outputChem2Field.vectors(); + + unsigned int vectorCount = inputChem1Field.vectorCount(); + unsigned int vectorDim = inputChem1Field.vectorDim(); + + float conc1, conc2, conc122; + for( int vI=0; vI 1.0 ) conc1 = 1.0; + if( conc2 < 0.0 ) conc2 = 0.0; + else if( conc2 > 1.0 ) conc2 = 1.0; + + conc122 = conc1 * conc2 * conc2; + outputChem1Vectors[vI][d] += F[d] * ( 1.0 - conc1 ) - ( conc122 ); + outputChem2Vectors[vI][d] += conc122 - ( F[d] + k[d] ) * conc2; + } + } +} \ No newline at end of file diff --git a/src/dab_flock_env_gray_scott_behavior.h b/src/dab_flock_env_gray_scott_behavior.h new file mode 100644 index 0000000..6c7c39c --- /dev/null +++ b/src/dab_flock_env_gray_scott_behavior.h @@ -0,0 +1,54 @@ +/** \file dab_flock_env_gray_scott_behavior.h + */ + +#ifndef _dab_flock_env_gray_scott_behavior_h_ +#define _dab_flock_env_gray_scott_behavior_h_ + +#include "dab_flock_env_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class EnvGrayScottBehavior : public EnvBehavior +{ +public: + EnvGrayScottBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + EnvGrayScottBehavior(Env* pEnv, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString); + ~EnvGrayScottBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception FlockException wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const; + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + void act(); + +protected: + EnvParameter* mInputChem1Par; // input environment parameter + EnvParameter* mInputChem2Par; // input environment parameter + Parameter* mFPar; // internal parameter + Parameter* mKPar; // internal parameter + EnvParameter* mOutputChem1Par; // output environment parameter + EnvParameter* mOutputChem2Par; // output environment parameter +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_env_parameter.cpp b/src/dab_flock_env_parameter.cpp new file mode 100644 index 0000000..1957df4 --- /dev/null +++ b/src/dab_flock_env_parameter.cpp @@ -0,0 +1,361 @@ +/** \file dab_flock_env_parameter.cpp + */ + +#include "dab_flock_env_parameter.h" +#include "dab_flock_env.h" +#include "dab_flock_simulation.h" +#include "dab_math.h" + +using namespace dab; +using namespace dab::flock; + +EnvParameter::EnvParameter() +: mValueGrid(nullptr) +, mBackupValueGrid(nullptr) +{} + +EnvParameter::EnvParameter(Env* pEnv, const std::string& pName, unsigned int pValueDim, const dab::Array& pSubdivisionCount, const Eigen::VectorXf& pMinPos, const Eigen::VectorXf& pMaxPos) throw (Exception) +: Parameter(pEnv, pName, pValueDim) +{ + try + { + mValueGrid = new space::SpaceGrid(pValueDim, pSubdivisionCount, pMinPos, pMaxPos); + mBackupValueGrid = new space::SpaceGrid(pValueDim, pSubdivisionCount, pMinPos, pMaxPos); + + std::string spaceName(pEnv->name() + "_" + mName); + mGridAlg = new space::GridAlg( mValueGrid, space::GridAlg::AvgLocationMode, space::GridAlg::NoUpdateMode ); + mGridSpace = std::shared_ptr(new space::Space( spaceName, mGridAlg )); + + Simulation::get().space().addSpace(mGridSpace); + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: failed to create EnvParameter " + pName, __FILE__, __FUNCTION__, __LINE__); + throw; + } +} + +EnvParameter::EnvParameter(Env* pEnv, const std::string& pName, const Eigen::VectorXf& pValues, const dab::Array& pSubdivisionCount, const Eigen::VectorXf& pMinPos, const Eigen::VectorXf& pMaxPos) throw (Exception) +: Parameter(pEnv, pName, pValues) +{ + try + { + mValueGrid = new space::SpaceGrid(pValues.rows(), pSubdivisionCount, pMinPos, pMaxPos); + mBackupValueGrid = new space::SpaceGrid(pValues.rows(), pSubdivisionCount, pMinPos, pMaxPos); + + mValueGrid->setValues(pValues); + mBackupValueGrid->setValues(pValues); + + std::string spaceName(pEnv->name() + "_" + mName); + mGridAlg = new space::GridAlg( mValueGrid, space::GridAlg::AvgLocationMode, space::GridAlg::NoUpdateMode ); + mGridSpace = std::shared_ptr(new space::Space( spaceName, mGridAlg )); + + Simulation::get().space().addSpace(mGridSpace); + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: failed to create EnvParameter " + pName, __FILE__, __FUNCTION__, __LINE__); + throw; + } +} + +EnvParameter::EnvParameter( Env* pEnv, std::shared_ptr pGridSpace, unsigned int pValueDim ) throw (Exception) +: Parameter( pEnv, pGridSpace->name(), pValueDim ) +{ + mGridSpace = pGridSpace; + + space::GridAlg* gridAlg = dynamic_cast< space::GridAlg* >( pGridSpace->spaceAlg() ); + if(gridAlg == nullptr) throw Exception( "FLOCK ERROR: environment parameter space " + pGridSpace->name() + "does not contain a grid", __FILE__, __FUNCTION__, __LINE__ ); + + mBackupValueGrid = &( gridAlg->grid() ); + + if( mBackupValueGrid->valueDim() != pValueDim ) throw Exception( "FLOCK ERROR: environment parameter space " + pGridSpace->name() + " doesn't match specified dimension", __FILE__, __FUNCTION__, __LINE__ ); + + mValueGrid = new space::SpaceGrid( mBackupValueGrid->valueDim(), mBackupValueGrid->subdivisionCount(), mBackupValueGrid->minPos(), mBackupValueGrid->maxPos() ); +} + +EnvParameter::EnvParameter(Env* pEnv, EnvParameter& pParameter) +: Parameter(pEnv, pParameter) +{ + mValueGrid = new space::SpaceGrid( *(pParameter.mValueGrid) ); + mBackupValueGrid = new space::SpaceGrid( *(pParameter.mBackupValueGrid) ); + + std::string spaceName(pEnv->name() + "_" + mName); + mGridAlg = new space::GridAlg( mValueGrid, space::GridAlg::AvgLocationMode, space::GridAlg::NoUpdateMode ); + mGridSpace = std::shared_ptr(new space::Space( spaceName, mGridAlg )); + + Simulation::get().space().addSpace(mGridSpace); +} + +EnvParameter::~EnvParameter() +{ + Simulation::get().space().removeSpace(mGridSpace->name()); + delete mValueGrid; + delete mBackupValueGrid; +} + +unsigned int +EnvParameter::gridDim() const +{ + return mValueGrid->gridDim(); +} + +const dab::Array& +EnvParameter::gridSize() const +{ + return mValueGrid->subdivisionCount(); +} + +unsigned int +EnvParameter::valueDim() const +{ + return mValueGrid->valueDim(); +} + +const Eigen::VectorXf& +EnvParameter::minPos() const +{ + return mValueGrid->minPos(); +} + +const Eigen::VectorXf& +EnvParameter::maxPos() const +{ + return mValueGrid->maxPos(); +} + +space::SpaceGrid* +EnvParameter::grid() +{ + return mValueGrid; +} + +space::SpaceGrid* +EnvParameter::backupGrid() +{ + return mBackupValueGrid; +} + +std::shared_ptr +EnvParameter::space() +{ + return mGridSpace; +} + +void +EnvParameter::set( float pValue ) +{ + Eigen::VectorXf _value(mDim); + _value.setConstant(pValue); + + mBackupValueGrid->setValues( _value ); + + flush(); +} + +void +EnvParameter::set( const Eigen::VectorXf& pValues ) throw (Exception) +{ + mBackupValueGrid->setValues(pValues); + + flush(); +} + +void +EnvParameter::set( const math::VectorField& pValues ) throw (Exception) +{ + math::VectorField& backupField = mBackupValueGrid->vectorField(); + + try + { + backupField = pValues; + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: parameter " + mName + " vectorfield mismatch", __FILE__, __FUNCTION__, __LINE__); + throw e; + } + + flush(); +} + +void +EnvParameter::set( const Eigen::VectorXf& pPosition, const Eigen::VectorXf& pValues, space::GridValueSetMode pSetMode ) throw (Exception) +{ + mBackupValueGrid->setValue(pPosition, pValues, pSetMode ); + + //flush(); +} + +void +EnvParameter::change( const Eigen::VectorXf& pValues ) throw (Exception) +{ + mBackupValueGrid->changeValues(pValues); + + flush(); +} + +void +EnvParameter::change( const Eigen::VectorXf& pPosition, const Eigen::VectorXf& pValues, space::GridValueSetMode pSetMode ) throw (Exception) +{ + mBackupValueGrid->changeValue(pPosition, pValues, pSetMode ); + + //flush(); +} + +void +EnvParameter::randomize(float pMinParameterValue, float pMaxParameterValue) +{ + if( isnan( pMinParameterValue ) == false && isnan( pMaxParameterValue ) == true ) return; + + math::Math<>& math = math::Math<>::get(); + + math::VectorField& vectorField = mBackupValueGrid->vectorField(); + unsigned int vC = vectorField.vectorCount(); + std::vector< Eigen::VectorXf >& vectors = vectorField.vectors(); + + for(unsigned int vI=0; vI& math = math::Math<>::get(); + + math::VectorField& vectorField = mBackupValueGrid->vectorField(); + unsigned int vC = vectorField.vectorCount(); + std::vector< Eigen::VectorXf >& vectors = vectorField.vectors(); + + for(unsigned int vI=0; vI& math = math::Math<>::get(); + + math::VectorField& vectorField = mBackupValueGrid->vectorField(); + unsigned int vC = vectorField.vectorCount(); + std::vector< Eigen::VectorXf >& vectors = vectorField.vectors(); + + for(unsigned int vI=0; vI= pThresholdValue ) vector[c] = pMaxParameterValue; + else vector[c] = pMinParameterValue; + } + } + + flush(); +} + +void +EnvParameter::randomize(const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues, const Eigen::VectorXf& pThresholdValues ) throw (Exception) +{ + if(pMinParameterValues.rows() != mDim) throw Exception( "FLOCK ERROR: valueCount mismatch: " + std::to_string(mDim) + " != " + std::to_string(pMinParameterValues.rows()) + " for parameter " + mName, __FILE__, __FUNCTION__, __LINE__ ); + if(pMaxParameterValues.rows() != mDim) throw Exception( "FLOCK ERROR: valueCount mismatch: " + std::to_string(mDim) + " != " + std::to_string(pMaxParameterValues.rows()) + " for parameter " + mName, __FILE__, __FUNCTION__, __LINE__ ); + if(pThresholdValues.rows() != mDim) throw Exception( "FLOCK ERROR: valueCount mismatch: " + std::to_string(mDim) + " != " + std::to_string(pThresholdValues.rows()) + " for parameter " + mName, __FILE__, __FUNCTION__, __LINE__ ); + + math::Math<>& math = math::Math<>::get(); + + math::VectorField& vectorField = mBackupValueGrid->vectorField(); + unsigned int vC = vectorField.vectorCount(); + std::vector< Eigen::VectorXf >& vectors = vectorField.vectors(); + + for(unsigned int vI=0; vI= pThresholdValues[c] ) vector[c] = pMaxParameterValues[c]; + else vector[c] = pMinParameterValues[c]; + } + } + + flush(); +} + +void +EnvParameter::flush() +{ + (*mValueGrid) = *mBackupValueGrid; +} + +void +EnvParameter::spaceObjects( std::vector< SpaceObject* >& pEnvObjects ) +{ + pEnvObjects.clear(); + + const Eigen::VectorXf& gridMinPos = mGridAlg->grid().minPos(); + const Eigen::VectorXf& gridMaxPos = mGridAlg->grid().maxPos(); + std::vector& gridProxyObjects = mGridSpace->objects(); + unsigned int oC = gridProxyObjects.size(); + SpaceObject* spaceObject; + + bool withinEnvBoundary; + + for(unsigned int oI=0; oIspaceObject(); + Eigen::VectorXf& objectPos = spaceObject->position(); + + withinEnvBoundary = true; + + for(int d=0; d gridMaxPos[d]) + { + withinEnvBoundary = false; + break; + } + } + + if(withinEnvBoundary == true) pEnvObjects.push_back( gridProxyObjects[oI]->spaceObject() ); + } +} + +EnvParameter::operator std::string() const +{ + return info(0); +} + +std::string +EnvParameter::info(int pPropagationLevel) const +{ + std::stringstream ss; + + ss << mName << " "; + ss << "values:\n"; + ss << (*mValueGrid); + ss << "backup values:\n"; + ss << (*mBackupValueGrid); + + return ss.str(); +} diff --git a/src/dab_flock_env_parameter.h b/src/dab_flock_env_parameter.h new file mode 100644 index 0000000..08bf160 --- /dev/null +++ b/src/dab_flock_env_parameter.h @@ -0,0 +1,257 @@ +/** \file dab_flock_env_parameter.h + * + * Created by Daniel Bisig on 2/21/09. + * Ported to OpenFrameworks by Daniel Bisig on 10/08/17. + */ + +#ifndef _dab_flock_env_parameter_h_ +#define _dab_flock_env_parameter_h_ + +#include "dab_exception.h" +#include "dab_flock_parameter.h" +#include "dab_space.h" +#include "dab_space_alg_grid.h" +#include "dab_space_grid.h" + +namespace dab +{ + +namespace flock +{ + +class Env; + +class EnvParameter : public Parameter +{ +public: + /** + \brief create environment parameter + \param pEnv environment this parameter belongs to + \param pName name of environment parameter + \param pValueDim dimension of parameter value + \param pSubdivisionCount grid subdivision of parameter value + \param pMinPos minimum position of parameter value grid + \param pMaxPos maximum position of parameter value grid + \exception Exception failed to create env parameter + */ + EnvParameter(Env* pEnv, const std::string& pName, unsigned int pValueDim, const dab::Array& pSubdivisionCount, const Eigen::VectorXf& pMinPos, const Eigen::VectorXf& pMaxPos) throw (Exception); + + /** + \brief create environment parameter + \param pEnv environment this parameter belongs to + \param pName name of environment parameter + \param pValues environment parameter value values + \param pSubdivisionCount grid subdivision of parameter value + \param pMinPos minimum position of parameter value grid + \param pMaxPos maximum position of parameter value grid + \exception Exception failed to create env parameter + */ + EnvParameter(Env* pEnv, const std::string& pName, const Eigen::VectorXf& pValues, const dab::Array& pSubdivisionCount, const Eigen::VectorXf& pMinPos, const Eigen::VectorXf& pMaxPos) throw (Exception); + + /** + \brief create environment parameter + \param pEnv environment this parameter belongs to + \param pGridSpace grid space + \param pValueDim dimension of parameter value + \exception Exception space does not contain a grid or valuedim of grid does not match specified value + */ + EnvParameter( Env* pEnv, std::shared_ptr pGridSpace, unsigned int pValueDim ) throw (Exception); + + /** + \brief copy constructor + \param pEnv env this parameter belongs to + \param pParameter parameter to copy + */ + EnvParameter(Env* pEnv, EnvParameter& pParameter); + + /** + \brief destructor + */ + ~EnvParameter(); + + /** + \brief return parameter grid dimension + \return parameter grid dimension + */ + unsigned int gridDim() const; + + /** + \brief return parameter grid size + \return parameter grid size + */ + const dab::Array& gridSize() const; + + /** + \brief return parameter value dimension + \returns parameter value dimension + */ + unsigned int valueDim() const; + + /** + \brief return minimum position + \return minimum position + */ + const Eigen::VectorXf& minPos() const; + + /** + \brief return maximum position + \return maximum position + */ + const Eigen::VectorXf& maxPos() const; + + /** + \brief return environment parameter grid + \return environment parameter grid + */ + space::SpaceGrid* grid(); + + /** + \brief return environment parameter grid + \return environment parameter grid + */ + space::SpaceGrid* backupGrid(); + + /** + \brief return environment space + \return environment space + */ + std::shared_ptr space(); + + /** + \brief set values + \param pValue single value + */ + void set(float pValue); + + /** + \brief set parameter values + \param pValues parameter values + + set entire parameter value grid to same value + */ + void set( const Eigen::VectorXf& pValues ) throw (Exception); + + /** + \brief set parameter values + \param pValues parameter values + \exception failed to set values + */ + void set( const math::VectorField& pValues ) throw (Exception); + + /** + \brief set parameter values + \param pPosition position + \param pValues parameter values + \param pSetMode set mode + + set parameter value grid at specified position + */ + void set( const Eigen::VectorXf& pPosition, const Eigen::VectorXf& pValues, space::GridValueSetMode pSetMode ) throw (Exception); + + /** + \brief change parameter values + \param pValues parameter values + + change entire parameter value grid by same value + */ + void change( const Eigen::VectorXf& pValues ) throw (Exception); + + /** + \brief change parameter values + \param pPosition position + \param pValues parameter values + \param pSetMode set mode + + change parameter value grid at specified position + */ + void change( const Eigen::VectorXf& pPosition, const Eigen::VectorXf& pValues, space::GridValueSetMode pSetMode ) throw (Exception); + + /** + \brief randomize parameter value + \param pMinParameterValue minimum parameter value + \param pMaxParameterValue minimum parameter value + */ + virtual void randomize(float pMinParameterValue, float pMaxParameterValue); + + /** + \brief randomize parameter value + \param pMinParameterValues minimum parameter values + \param pMaxParameterValues minimum parameter values + */ + virtual void randomize(const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues) throw (Exception); + + /** + \brief randomize parameter value + \param pMinParameterValue minimum parameter value + \param pMaxParameterValue minimum parameter value + \param pThresholdValue threshold value + + salt and pepper randomization + parameter value will be set to min value for random values below threshold and to max value for random values above threshold + */ + virtual void randomize(float pMinParameterValue, float pMaxParameterValue, float pThresholdValue); + + /** + \brief randomize parameter value + \param pMinParameterValues minimum parameter values + \param pMaxParameterValues minimum parameter values + \param pThresholdValues threshold values + + salt and pepper randomization + parameter value will be set to min value for random values below threshold and to max value for random values above threshold + */ + virtual void randomize(const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues, const Eigen::VectorXf& pThresholdValues ) throw (Exception); + + /** + \brief copy backup value into current value + */ + void flush(); + + /** + \brief return vector of space objects + \param pEnvObjects vector of space objects + + returns space objects that exist within the boundaries of the environment grid + */ + void spaceObjects( std::vector< SpaceObject* >& pEnvObjects ); + + /** + \brief print parameter information + */ + virtual operator std::string() const; + + /** + \brief print parameter information + \param pPropagationLevel how far the propagation method proceeds through composite classes (-1: unlimited, 0: no proceeding, >0: limited proceeding) + */ + virtual std::string info(int pPropagationLevel = 0) const; + + /** + \brief retrieve textual parameter info + \param pOstream output text stream + \param pParameter parameter + */ + friend std::ostream& operator << ( std::ostream& pOstream, const EnvParameter& pParameter ) + { + pOstream << pParameter.info(); + + return pOstream; + }; + +protected: + /** + \brief default constructor + */ + EnvParameter(); + + space::SpaceGrid* mValueGrid; ///\brief value grid + space::SpaceGrid* mBackupValueGrid; ///\brief backup value grid; + space::GridAlg* mGridAlg; ///\brief + std::shared_ptr mGridSpace; ///\brief space associated with value grid +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_euler_integration.cpp b/src/dab_flock_euler_integration.cpp new file mode 100644 index 0000000..27c8f85 --- /dev/null +++ b/src/dab_flock_euler_integration.cpp @@ -0,0 +1,84 @@ +/** \file dab_flock_euler_integration.cpp + */ + +#include "dab_flock_euler_integration.h" +#include "dab_flock_parameter.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +EulerIntegration::EulerIntegration(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "EulerIntegration"; +} + +EulerIntegration::EulerIntegration(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "EulerIntegration"; + + if(mInputParameters.size() < 3) throw Exception( "FLOCK ERROR: Behavior " + pBehaviorName + " : " + std::to_string(mOutputParameters.size()) + " Input Parameters Supplied, 3 Needed", __FILE__, __FUNCTION__, __LINE__ ); + if(mOutputParameters.size() < 2) throw Exception("FLOCK ERROR: Behavior " + pBehaviorName + " : " + std::to_string(mOutputParameters.size()) + " Output Parameters Supplied, 2 Needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: Behavior " + pBehaviorName + " : input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[1]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: Behavior " + pBehaviorName + " : input parameter " + mInputParameters[1]->name() + " dim " + std::to_string(mInputParameters[1]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[2]->dim() != mOutputParameters[1]->dim() ) throw Exception( "FLOCK ERROR: Behavior " + pBehaviorName + " : input parameter " + mInputParameters[2]->name() + " dim " + std::to_string(mInputParameters[2]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters[0]->dim() != mOutputParameters[1]->dim() ) throw Exception( "FLOCK ERROR: Behavior " + pBehaviorName + " : output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[1]->name() + " dim " + std::to_string( mOutputParameters[1]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + + + // input parameter + mDerivative0ParIn = mInputParameters[0]; + mDerivative1ParIn = mInputParameters[1]; + mDerivative2Par = mInputParameters[2]; + + // output parameter + mDerivative0ParOut = mOutputParameters[0]; + mDerivative1ParOut = mOutputParameters[1]; + + // internal parameter + mTimeStepPar = createInternalParameter("timestep", { 0.1f } ); +} + +EulerIntegration::~EulerIntegration() +{} + +Behavior* +EulerIntegration::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + return new EulerIntegration(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +EulerIntegration::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new EulerIntegration(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +EulerIntegration::act() +{ + Eigen::VectorXf& derivative0In = mDerivative0ParIn->values(); + Eigen::VectorXf& derivative1In = mDerivative1ParIn->values(); + Eigen::VectorXf& derivative2 = mDerivative2Par->values(); + Eigen::VectorXf& derivative0Out = mDerivative0ParOut->backupValues(); + Eigen::VectorXf& derivative1Out = mDerivative1ParOut->backupValues(); + float& timeStep = mTimeStepPar->value(); + + derivative0Out += derivative1In * timeStep; + derivative1Out += derivative2 * timeStep; +} \ No newline at end of file diff --git a/src/dab_flock_euler_integration.h b/src/dab_flock_euler_integration.h new file mode 100644 index 0000000..e7d0656 --- /dev/null +++ b/src/dab_flock_euler_integration.h @@ -0,0 +1,79 @@ +/** \file dab_flock_euler_integration.h + * + * Created by Daniel Bisig on 4/17/07. + * Ported to OpenFrameworks by Daniel Bisig on 12/08/17. + */ + +#ifndef _dab_flock_euler_integration_h_ +#define _dab_flock_euler_integration_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class EulerIntegration : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + EulerIntegration(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number or type of parameters + */ + EulerIntegration(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~EulerIntegration(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform integration + */ + virtual void act(); + +protected: + Parameter* mDerivative0ParIn; /// \brief zero order derivative (input) + Parameter* mDerivative1ParIn; /// \brief first order derivative (input) + Parameter* mDerivative2Par; /// \brief second order derivative (input) + Parameter* mDerivative0ParOut; /// \brief zero order derivative (output) + Parameter* mDerivative1ParOut; /// \brief first order derivative (output) + Parameter* mTimeStepPar; /// \brief integration time step (internal) +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_evasion_behavior.cpp b/src/dab_flock_evasion_behavior.cpp new file mode 100644 index 0000000..ec6ca2a --- /dev/null +++ b/src/dab_flock_evasion_behavior.cpp @@ -0,0 +1,126 @@ +/** \file dab_flock_evasion_behavior.cpp + */ + +#include "dab_flock_evasion_behavior.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +EvasionBehavior::EvasionBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "EvasionBehavior"; +} + +EvasionBehavior::EvasionBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "EvasionBehavior"; + + if( mInputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mInputNeighborGroups.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputNeighborGroups.size()) + " neighbor groups supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mPositionPar = mInputParameters[0]; + + // output parameter + mForcePar = mOutputParameters[0]; + + // create internal parameters + mMaxDistPar = createInternalParameter("maxDist", { 0.2f } ); + mAmountPar = createInternalParameter("amount", { 0.1f } ); + + // input neighbor groups + mPositionNeighbors = mInputNeighborGroups[0]; + + // remaining stuff + unsigned int dim = mForcePar->dim(); + mTmpForce.resize(dim, 1); +} + +EvasionBehavior::~EvasionBehavior() +{} + +Behavior* +EvasionBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new EvasionBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new EvasionBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +EvasionBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new EvasionBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +EvasionBehavior::act() +{ + //std::cout << "EvasionBehavior begin: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& position = mPositionPar->values(); + space::NeighborGroup& positionNeighbors = *mPositionNeighbors; + Eigen::VectorXf& force = mForcePar->backupValues(); + float& maxDist = mMaxDistPar->value(); + float& amount = mAmountPar->value(); + Eigen::VectorXf& tmpForce = mTmpForce; + + tmpForce.setConstant(0.0); + unsigned int totalNeighborCount = positionNeighbors.neighborCount(); + unsigned int neighborCount = 0; + + //std::cout << "evasion for agent " << mAgent->name().toStdString() << " pos " << position << " neighborCount " << totalNeighborCount << "\n"; + + if(totalNeighborCount == 0) return; + + float distance; + float scale; + + for(unsigned int i=0; i 0.0 && distance > maxDist) continue; + + scale = (maxDist - distance) / maxDist; + + tmpForce += direction * scale; + neighborCount++; + + //std::cout << " neighbor agent " << positionPar.neighbor(i)->agent()->name().toStdString() << " pos " << positionPar.neighbor(i)->values() << " dir " << direction << "\n"; + } + + if(neighborCount == 0) return; + + tmpForce /= static_cast(neighborCount); + tmpForce *= -1.0 * amount; + + //std::cout << "force " << tmpForce << "\n"; + + force += tmpForce; + + //std::cout << "EvasionBehavior end: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + + //assert(std::isnan(force[0]) == false && "isNan"); +} \ No newline at end of file diff --git a/src/dab_flock_evasion_behavior.h b/src/dab_flock_evasion_behavior.h new file mode 100644 index 0000000..3d6c147 --- /dev/null +++ b/src/dab_flock_evasion_behavior.h @@ -0,0 +1,93 @@ +/** \file dab_flock_evasion_behavior.h + * \class dab::flock::EvasionBehavior cause Agent to move away from their neighbors + * \brief cause Agent to move away from their neighbors + * + * The Behavior causes Agent to move away from their neighbors\n + * Input Parameter:\n + * type: position dim: nD neighbors: required\n + * \n + * Output Parameter:\n + * type: force dim: nD write: add\n + * \n + * Internal Parameter:\n + * name: xxx_maxDist dim: 1D defaultValue: 0.2\n + * name: xxx_amount dim: 1D defaultValue: 0.1\n + * name: xxx_active dim: 1D defaultValue: 1.0\n + * \n + * Created by Daniel Bisig on 4/21/07. + * Ported to OpenFrameworks by Daniel Bisig on 13/10/2017. + */ + +#ifndef _dab_flock_evasion_behavior_h_ +#define _dab_flock_evasion_behavior_h_ + +#include "dab_flock_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class EvasionBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + EvasionBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + EvasionBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~EvasionBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mPositionPar; /// \brief position parameter (input) + Parameter* mForcePar; /// \brief force parameter (output) + Parameter* mMaxDistPar; /// \brief minimum distance parameter (internal) + Parameter* mAmountPar; /// \brief behavior amount parameter (internal) + space::NeighborGroup* mPositionNeighbors; /// \brief position neighbor group + + Eigen::VectorXf mTmpForce; /// \brief temporary force +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_event_includes.h b/src/dab_flock_event_includes.h new file mode 100644 index 0000000..7afbb80 --- /dev/null +++ b/src/dab_flock_event_includes.h @@ -0,0 +1,35 @@ +/** \file dab_flock_event_includes.h + * + * Created by Daniel Bisig on 6/10/09. + * Ported to OpenFrameworks by Daniel Bisig on 11/10/2017. + */ + +#ifndef _dab_flock_event_includes_h_ +#define _dab_flock_event_includes_h_ + +#include "dab_flock_set_simulation_rate_event.h" +#include "dab_flock_clear_simulation_event.h" +#include "dab_flock_save_simulation_event.h" +#include "dab_flock_restore_simulation_event.h" +#include "dab_flock_add_space_event.h" +//#include "iso_flock_remove_space_event.h" +//#include "iso_flock_add_sender_event.h" +//#include "iso_flock_remove_sender_event.h" +//#include "iso_flock_add_receiver_event.h" +//#include "iso_flock_remove_receiver_event.h" +//#include "iso_flock_add_swarm_event.h" +//#include "iso_flock_remove_swarm_event.h" +#include "dab_flock_add_agents_event.h" +#include "dab_flock_remove_agents_event.h" +//#include "iso_flock_add_parameter_event.h" +#include "dab_flock_set_parameter_event.h" +//#include "iso_flock_remove_parameter_event.h" +//#include "iso_flock_assign_neighbors_event.h" +//#include "iso_flock_register_parameter_event.h" +//#include "iso_flock_deregister_parameter_event.h" +//#include "iso_flock_remove_neighbors_event.h" +//#include "iso_flock_add_behavior_event.h" +//#include "iso_flock_move_behavior_event.h" +//#include "iso_flock_remove_behavior_event.h" + +#endif \ No newline at end of file diff --git a/src/dab_flock_grid_avg_behavior.cpp b/src/dab_flock_grid_avg_behavior.cpp new file mode 100644 index 0000000..952d2fe --- /dev/null +++ b/src/dab_flock_grid_avg_behavior.cpp @@ -0,0 +1,132 @@ +/** \file dab_flock_grid_avg_behavior.cpp + */ + +#include "dab_flock_grid_avg_behavior.h" + +using namespace dab; +using namespace dab::flock; + +GridAvgBehavior::GridAvgBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "GridAvgBehavior"; +} + +GridAvgBehavior::GridAvgBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "GridAvgBehavior"; + + if( mInputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputNeighborGroups.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputNeighborGroups.size()) + " neighbor groups supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mParIn = mInputParameters[0]; + + // output parameter + mParOut = mOutputParameters[0]; + + // create internal parameters + mMinDistPar = createInternalParameter("minDist", { 0.0f } ); + mMaxDistPar = createInternalParameter("maxDist", { 1.0f } ); + mAmountPar = createInternalParameter("amount", { 0.1f }); + + // input neighbor groups + mGridValues = mInputNeighborGroups[0]; + + // other stuff + int dim = mParOut->dim(); + mTmpValueOut.resize(dim, 1); +} + +GridAvgBehavior::~GridAvgBehavior() +{} + +Behavior* +GridAvgBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new GridAvgBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new GridAvgBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +GridAvgBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new GridAvgBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +GridAvgBehavior::act() +{ + //std::cout << "GridAvgBehavior " << mName.toStdString() << " act() begin\n"; + + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& valueIn = mParIn->values(); + space::NeighborGroup& valueInNeighbors = *mGridValues; + Eigen::VectorXf& valueOut = mParOut->backupValues(); + float& minDist = mMinDistPar->value(); + float& maxDist = mMaxDistPar->value(); + float& amount = mAmountPar->value(); + + Eigen::VectorXf& tmpValueOut = mTmpValueOut; + unsigned int totalNeighborCount = valueInNeighbors.neighborCount(); + unsigned int neighborCount = 0; + + //std::cout << "totalNeighborCount " << totalNeighborCount << "\n"; + + if(totalNeighborCount == 0) return; + + tmpValueOut.setConstant(0.0); + float distance; + float scale; + + for(unsigned int i=0; i& gridValue = valueInNeighbors.neighbor(i)->position(); + const Eigen::VectorXf& gridValue = valueInNeighbors.value(i); + + assert(gridValue.rows() == valueOut.rows() && "wrong output value dimension"); + + distance = valueInNeighbors.distance(i); + + //std::cout << "valueIn " << valueIn << " gridValue " << gridValue << " dist " << distance << "\n"; + + if(minDist > 0.0 && distance < minDist) continue; + if(maxDist > 0.0 && distance > maxDist) continue; + + scale = (maxDist - minDist) / (1.0 + distance - minDist); + + tmpValueOut += gridValue * scale; + + //std::cout << "scale " << scale << " tmpValueOut " << tmpValueOut << "\n"; + + neighborCount++; + } + + if(neighborCount == 0) return; + + tmpValueOut /= static_cast(neighborCount); + tmpValueOut *= amount; + + valueOut += tmpValueOut; + + //std::cout << "tmpValueOut " << tmpValueOut << "\n"; + + //std::cout << "GridAvgBehavior " << mName.toStdString() << " act() end\n"; +} \ No newline at end of file diff --git a/src/dab_flock_grid_avg_behavior.h b/src/dab_flock_grid_avg_behavior.h new file mode 100644 index 0000000..9ab8452 --- /dev/null +++ b/src/dab_flock_grid_avg_behavior.h @@ -0,0 +1,97 @@ +/** \file dab_flock_grid_avg_behavior.h + * \class dab::flock::GridAvgBehavior add grid value at Agent position to output parameter + * \brief add grid value at Agent position to output parameter + * + * The Behavior adds grid value at Agent position to output parameter\n + * The grid value is linearly interpolated.\n + * \n + * Input Parameter:\n + * type: position dim: nD neighbors: required\n + * \n + * Output Parameter:\n + * type: output dim: nD write: add\n + * \n + * Internal Parameter:\n + * name: xxx_minDist dim: 1D defaultValue: 0.0\n + * name: xxx_maxDist dim: 1D defaultValue: 1.0\n + * name: xxx_amount dim: 1D defaultValue: 1.0\n + * name: xxx_active dim: 1D defaultValue: 0.1\n + * \n + * Created by Daniel Bisig on 5/24/07. + * Ported to OpenFrameworks by Daniel Bisig on 13/10/2017. + */ + +#ifndef _dab_flock_grid_avg_behavior_h_ +#define _dab_flock_grid_avg_behavior_h_ + +#include "dab_flock_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class GridAvgBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + GridAvgBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + GridAvgBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~GridAvgBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mParIn; /// \brief input parameter (input) + Parameter* mParOut; /// \brief output parameter (output) + Parameter* mMinDistPar; /// \brief mininum distance parameter (internal) + Parameter* mMaxDistPar; /// \brief maximum distance parameter (internal) + Parameter* mAmountPar; /// \brief behavior amount parameter (internal) + space::NeighborGroup* mGridValues; /// \brief grid values + + Eigen::VectorXf mTmpValueOut; /// \brief temporary output value +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_line_follow_behavior.cpp b/src/dab_flock_line_follow_behavior.cpp new file mode 100644 index 0000000..43b7704 --- /dev/null +++ b/src/dab_flock_line_follow_behavior.cpp @@ -0,0 +1,334 @@ +/** \file dab_flock_line_follow_behavior.cpp + */ + +#include "dab_flock_line_follow_behavior.h" +#include "dab_flock_agent.h" +#include "dab_geom_line.h" +#include "dab_geom_spline.h" +#include "dab_geom_spline_tools.h" + +using namespace dab; +using namespace dab::flock; + +LineFollowBehavior::LineFollowBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{} + +LineFollowBehavior::LineFollowBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +, mPreviousClosestGeomGroup( nullptr ) +, mPreviousClosestLineIndex( 0 ) +, mPreviousSpaceShape( nullptr ) +{ + if( mInputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mInputNeighborGroups.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputNeighborGroups.size()) + " neighbor groups supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mPositionPar = mInputParameters[0]; + + // output parameter + mForcePar = mOutputParameters[0]; + + // create internal parameters + mMinDistPar = createInternalParameter("minDist", { 0.0f }); + mMaxDistPar = createInternalParameter("maxDist", { 0.5f }); + mContourMaintainDistPar = createInternalParameter("contourMaintainDist",{ 10.0f }); + mOrtAmountPar = createInternalParameter("ortAmount", { 1.0f }); + mTanAmountPar = createInternalParameter("tanAmount", { 1.0f }); + mAmountPar = createInternalParameter("amount", { 0.1f }); + + // input neighbor groups + mPositionNeighbors = mInputNeighborGroups[0]; +} + +LineFollowBehavior::~LineFollowBehavior() +{} + +Behavior* +LineFollowBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new LineFollowBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new LineFollowBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +LineFollowBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new LineFollowBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +LineFollowBehavior::act() +{ + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& position = mPositionPar->values(); + space::NeighborGroup& positionNeighbors = *mPositionNeighbors; + Eigen::VectorXf& force = mForcePar->backupValues(); + float& minDist = mMinDistPar->value(); + float& maxDist = mMaxDistPar->value(); + float& contourMaintainDist = mContourMaintainDistPar->value(); + float& ortAmount = mOrtAmountPar->value(); + float& tanAmount = mTanAmountPar->value(); + float& amount = mAmountPar->value(); + + unsigned int totalNeighborCount = positionNeighbors.neighborCount(); + if(totalNeighborCount == 0) + { + mPreviousClosestGeomGroup = NULL; + return; + } + + // get neighbor space shape + space::SpaceShape* spaceShape = dynamic_cast( positionNeighbors.neighbor(0) ); + if(spaceShape == nullptr) + { + mPreviousClosestGeomGroup = NULL; + return; + } + + if( spaceShape != mPreviousSpaceShape ) + { + mPreviousClosestGeomGroup = NULL; + mPreviousSpaceShape = spaceShape; + } + + int swarmDim = position.rows(); + int swarmDimLim = std::min(swarmDim, 3); + + // determine agent position in object coordinate space of space shape + for(int d=0; dworld2object(mWC_AgentPosition); + + //std::cout << "wc_agentPos " << mWC_AgentPosition << " oc_agentPos " << mOC_AgentPosition << "\n"; + + geom::GeometryGroup* geomGroup; + + // check if previous geom group is part of current space shape and if it is sufficiently close + geomGroup = mPreviousClosestGeomGroup; + float closestGroupDist; + + //std::cout << "geomGroup " << geomGroup << "\n"; + + if( geomGroup != nullptr ) + { + //std::cout << "geomGroup min " << geomGroup->minPos() << " max " << geomGroup->maxPos() << "\n"; + + mBoundingBox.set( mPreviousClosestGeomGroup->minPos(), mPreviousClosestGeomGroup->maxPos() ); + mBoundingBox.closestPoint( mOC_AgentPosition, mOC_ClosestPosition ); + float geomDist = glm::length( mOC_ClosestPosition - mOC_AgentPosition ); + + //std::cout << "geomDist " << geomDist << "\n"; + + if( geomDist > contourMaintainDist ) + { + mPreviousClosestGeomGroup = nullptr; + geomGroup = mPreviousClosestGeomGroup; + } + } + + // look for new innermost closest geometry group + if( geomGroup == nullptr ) + { + geomGroup = dynamic_cast< geom::GeometryGroup* >( spaceShape->geometry().get() ); //top geom group + + if( geomGroup == nullptr ) return; + closestGroupDist = FLT_MAX; + + getClosestGeomGroup( &geomGroup, mOC_AgentPosition, closestGroupDist ); + + //std::cout << "new closest geom group " << geomGroup << " ap " << mOC_AgentPosition << " cgd " << closestGroupDist << "\n"; + } + + //std::cout << "closest geom group " << geomGroup << " : dist " << closestGroupDist << "\n"; + + std::vector< geom::Geometry* >& lines = geomGroup->geometries(); + int lineCount = lines.size(); + + //std::cout << "lineCount " << lineCount << "\n"; + + int searchLineStart1 = 0; + int searchLineEnd1 = 0; + int searchLineStart2 = 0; + int searchLineEnd2 = 0; + + if( mPreviousClosestGeomGroup != geomGroup ) // start a new full search + { + mPreviousClosestGeomGroup = geomGroup; + searchLineStart1 = 0; + searchLineEnd1 = lineCount; + searchLineStart2 = 0; + searchLineEnd2 = 0; + } + else + { + searchLineStart1 = mPreviousClosestLineIndex - 3; + searchLineEnd1 = mPreviousClosestLineIndex + 3; + + if( searchLineStart1 < 0 ) + { + searchLineStart2 = lineCount + searchLineStart1; + searchLineStart1 = 0; + searchLineEnd2 = lineCount; + } + else if( searchLineEnd1 > lineCount ) + { + searchLineEnd2 = searchLineEnd1 - lineCount; + searchLineStart2 = 0; + searchLineEnd1 = lineCount; + } + + if( searchLineStart2 >= lineCount ) searchLineStart2 = lineCount - 1; + else if( searchLineStart2 < 0 ) searchLineStart2 = 0; + } + + if(searchLineStart1 < 0) searchLineStart1 = 0; + if(searchLineStart1 > lineCount) searchLineStart1 = lineCount; + if(searchLineStart2 < 0) searchLineStart2 = 0; + if(searchLineStart2 > lineCount) searchLineStart2 = lineCount; + if(searchLineEnd1 < 0) searchLineEnd1 = 0; + if(searchLineEnd1 > lineCount) searchLineEnd1 = lineCount; + if(searchLineEnd2 < 0) searchLineEnd2 = 0; + if(searchLineEnd2 > lineCount) searchLineEnd2 = lineCount; + + //std::cout << "line search range start1 " << searchLineStart1 << " end1 " << searchLineEnd1 << " start2 " << searchLineStart2 << " end2 " << searchLineEnd2 << "\n"; + + geom::Line* line; + float lineDist; + + geom::Geometry* closestLine; + float closestLineDist = FLT_MAX; + + for( int lI = searchLineStart1; lI < searchLineEnd1; ++lI ) + { + line = static_cast( lines[ lI ] ); + + line->closestPoint(mOC_AgentPosition, mOC_ClosestPosition); + lineDist = glm::length( mOC_ClosestPosition - mOC_AgentPosition ); + + if( lineDist <= closestLineDist ) + { + closestLineDist = lineDist; + closestLine = line; + mPreviousClosestLineIndex = lI; + } + + //std::cout << lI << " v0 " << line->v0() << " v1 " << line->v1() << " dist " << lineDist << " closest " << closestLineDist << "\n"; + } + for( int lI = searchLineStart2; lI < searchLineEnd2; ++lI ) + { + line = static_cast( lines[ lI ] ); + + line->closestPoint(mOC_AgentPosition, mOC_ClosestPosition); + lineDist = glm::length( mOC_ClosestPosition - mOC_AgentPosition ); + + if( lineDist <= closestLineDist ) + { + closestLineDist = lineDist; + closestLine = line; + mPreviousClosestLineIndex = lI; + } + + //std::cout << lI << " v0 " << line->v0() << " v1 " << line->v1() << " dist " << lineDist << " closest " << closestLineDist << "\n"; + } + + closestLine->closestPoint(mOC_AgentPosition, mOC_ClosestPosition); + + // calculate orthogonal direction to closest point in world coordinates + + mWC_ClosestPosition = spaceShape->object2world(mOC_ClosestPosition); + mOrtDirection = mWC_ClosestPosition - mWC_AgentPosition; + + //std::cout << "closest line index " << mPreviousClosestLineIndex << " v0 " << line->v0() << " v1 " << line->v1() << "\n"; + + //std::cout << "agent wc " << mWC_AgentPosition << " oc " << mOC_AgentPosition << " line closest wc " << mWC_ClosestPosition << " oc " << mOC_ClosestPosition << "\n"; + + int tangIndex = mPreviousClosestLineIndex; + //mTangDirection = OC2WC_Matrix.multiply( lines[tangIndex]->maxPos() - lines[tangIndex]->minPos(), 1); + mTangDirection = static_cast< geom::Line* >( lines[tangIndex] )->v1() - static_cast< geom::Line* >( lines[tangIndex] )->v0(); + + // normalise orthogonal direction and tangent direction + mOrtDirection = glm::normalize(mOrtDirection); + mTangDirection = glm::normalize(mTangDirection); + + float scale = (closestLineDist - minDist) / (maxDist - minDist); + + //if( closestLineDist > maxDist) scale = 1.0; + + // new version + if( closestLineDist > maxDist) + { + mPreviousClosestLineIndex = 0; + mPreviousSpaceShape = nullptr; + return; + } + + for(int d=0; d& geometries = (*pGeomGroup)->geometries(); + int geometryCount = geometries.size(); + geom::GeometryGroup* geomGroup; + float groupDist; + bool closerGroupFound = false; + + //std::cout << "geometryCount " << geometryCount << "\n"; + + for( int i=0; i( geometries[i] ); + + //std::cout << "geometry " << i << " geomGroup " << geomGroup << "\n"; + + if( geomGroup != NULL ) + { + mBoundingBox.set( geomGroup->minPos(), geomGroup->maxPos() ); + mBoundingBox.closestPoint( mOC_AgentPosition, mOC_ClosestPosition ); + groupDist = glm::length( mOC_ClosestPosition - mOC_AgentPosition ); + + //std::cout << "groupDist " << groupDist << " former GroupDist " << pGroupDist << "\n"; + + if( groupDist <= pGroupDist ) + { + (*pGeomGroup) = geomGroup; + pGroupDist = groupDist; + closerGroupFound = true; + } + + //std::cout << "check group " << i << " : " << geomGroup << " bounding box min " << geomGroup->minPos() << " max " << geomGroup->maxPos() << " dist " << groupDist <<"\n"; + } + } + + //std::cout << "LineFollowBehavior::getClosestGeomGroup : geomGroup " << *pGeomGroup << " dist " << pGroupDist << " end\n"; + + if( closerGroupFound == true ) getClosestGeomGroup( pGeomGroup, pOC_AgentPosition, pGroupDist ); + else return; +} \ No newline at end of file diff --git a/src/dab_flock_line_follow_behavior.h b/src/dab_flock_line_follow_behavior.h new file mode 100644 index 0000000..e64b910 --- /dev/null +++ b/src/dab_flock_line_follow_behavior.h @@ -0,0 +1,98 @@ +/** \file dab_flock_line_follow_behavior.h + * needs at least three line segments, segments should form a closed shape + */ + +#ifndef _dab_flock_line_follow_behavior_h_ +#define _dab_flock_line_follow_behavior_h_ + +#include "ofVectorMath.h" +#include "dab_flock_behavior.h" +#include "dab_geom_cuboid.h" +#include "dab_geom_geometry_group.h" +#include "dab_space_shape.h" + +namespace dab +{ + +namespace flock +{ + +class LineFollowBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + LineFollowBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + LineFollowBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~LineFollowBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mPositionPar; /// \brief position parameter (input) + Parameter* mForcePar; /// \brief force parameter (output) + Parameter* mMinDistPar; /// \brief minimum distance parameter (internal) + Parameter* mMaxDistPar; /// \brief maximum distance parameter (internal) + Parameter* mContourMaintainDistPar; /// \brief contour maintain dist parameter (internal) + Parameter* mOrtAmountPar; /// \brief behavior ortogonal amount parameter (internal) + Parameter* mTanAmountPar; /// \brief behavior tangential amount parameter (internal) + Parameter* mAmountPar; /// \brief behavior amount parameter (internal) + space::NeighborGroup* mPositionNeighbors; /// \brief position neighbor group + + glm::mat4x4 mWC2OC_Matrix; + glm::vec3 mWC_AgentPosition; + glm::vec3 mOC_AgentPosition; + glm::vec3 mOC_ClosestPosition; + glm::vec3 mWC_ClosestPosition; + glm::vec3 mOrtDirection; + glm::vec3 mTangDirection; + + geom::Cuboid mBoundingBox; + space::SpaceShape* mPreviousSpaceShape; + geom::GeometryGroup* mPreviousClosestGeomGroup; + int mPreviousClosestLineIndex; + + void getClosestGeomGroup( geom::GeometryGroup** pGeomGroup, const glm::vec3& pOC_AgentPosition, float& pGroupDist ); +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_neighbor_direction_store_behavior.cpp b/src/dab_flock_neighbor_direction_store_behavior.cpp new file mode 100644 index 0000000..729caad --- /dev/null +++ b/src/dab_flock_neighbor_direction_store_behavior.cpp @@ -0,0 +1,106 @@ +/** \file dab_flock_neighbor_direction_store_behavior.cpp + */ + +#include "dab_flock_neighbor_direction_store_behavior.h" +#include "dab_flock_agent.h" +#include "dab_space_neighbors.h" +#include "dab_space_neighbor_relation.h" +#include + +using namespace dab; +using namespace dab::flock; + +NeighborDirectionStoreBehavior::NeighborDirectionStoreBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "NeighborDirectionStoreBehavior"; +} + +NeighborDirectionStoreBehavior::NeighborDirectionStoreBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "NeighborDirectionStoreBehavior"; + + if( mInputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputNeighborGroups.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputNeighborGroups.size()) + " neighbor groups supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mParameter = mInputParameters[0]; + + // neighbor parameter + mNeighborStorePar = mOutputParameters[0]; + + // input neighbor groups + mNeighbors = mInputNeighborGroups[0]; +} + +NeighborDirectionStoreBehavior::~NeighborDirectionStoreBehavior() +{} + +Behavior* +NeighborDirectionStoreBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new NeighborDirectionStoreBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new NeighborDirectionStoreBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +NeighborDirectionStoreBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new NeighborDirectionStoreBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +NeighborDirectionStoreBehavior::act() +{ + if(mActivePar->value() <= 0.0) return; + + space::NeighborGroup& neighbors = *mNeighbors; + Eigen::VectorXf& neighborStoreValues = mNeighborStorePar->backupValues(); + unsigned int neighborStoreParDim = mNeighborStorePar->dim(); + unsigned int parameterDim = mParameter->dim(); + + if(neighborStoreParDim < parameterDim) return; + + space::SpaceNeighborRelation* neighborRelation; + unsigned int neighborCount = neighbors.neighborCount(); + + int storeIndex = 0; + for(unsigned int d=0; ddirection(); + + for(unsigned int d=0; dname().toStdString() << " neighborStore " << *mNeighborStorePar << "\n"; +} \ No newline at end of file diff --git a/src/dab_flock_neighbor_direction_store_behavior.h b/src/dab_flock_neighbor_direction_store_behavior.h new file mode 100644 index 0000000..22cdefe --- /dev/null +++ b/src/dab_flock_neighbor_direction_store_behavior.h @@ -0,0 +1,94 @@ +/** \file dab_flock_neighbor_direction_store_behavior.h + * \class dab::flock::NeighborStoreBehavior store neighborhood information in agent parameter + * \brief store neighborhood information in agent parameter + * + * The Behavior stores the direction of neighbors in an output parameter\n + * The dimension of the output parameter is fixed and must be nD + nD * maxNeighborCount\n + * If there are fewer neighbors than the parameter can hold, the remaining parameter positions are filled with FLT_MIN\n + * If there are more neighbors than the parameter can hold, they will be ignored\n + * The content of the output Parameter is as follows:\n + * [0 - nD-1] : agent direction ( always 0.0 )\n + * [nD - 2nD-1] : neighbor1 direction\n + * [2nD - 3nD-1] : neighbor2 direction\n + * etc\n + * \n + * Input Parameter:\n + * type: position dim: nD neighbors: required\n + * \n + * Output Parameter:\n + * type: output dim: nD + nD * maxNeighborCount write: replace\n + * \n + * Created by Daniel Bisig on 30/12/08. + * Ported to OpenFrameworks by Daniel Bisig on 10/16/2017. + */ + + +#ifndef _dab_flock_neighbor_direction_store_behavior_h_ +#define _dab_flock_neighbor_direction_store_behavior_h_ + +#include "dab_flock_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class NeighborDirectionStoreBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + NeighborDirectionStoreBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + NeighborDirectionStoreBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~NeighborDirectionStoreBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mParameter; /// \brief input parameter (input) + Parameter* mNeighborStorePar; /// \brief neighbor store parameter (output) + space::NeighborGroup* mNeighbors; /// \brief neighbor group +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_neighbor_distance_store_behavior.cpp b/src/dab_flock_neighbor_distance_store_behavior.cpp new file mode 100644 index 0000000..9faf8e2 --- /dev/null +++ b/src/dab_flock_neighbor_distance_store_behavior.cpp @@ -0,0 +1,91 @@ +/** \file dab_flock_neighbor_distance_store_behavior.cpp + */ + +#include "dab_flock_neighbor_distance_store_behavior.h" +#include "dab_flock_agent.h" +#include "dab_space_neighbors.h" +#include "dab_space_neighbor_relation.h" +#include + +using namespace dab; +using namespace dab::flock; + +NeighborDistanceStoreBehavior::NeighborDistanceStoreBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "NeighborDistanceStoreBehavior"; +} + +NeighborDistanceStoreBehavior::NeighborDistanceStoreBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "NeighborDistanceStoreBehavior"; + + if( mInputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied," + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputNeighborGroups.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputNeighborGroups.size()) + " neighbor groups supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mParameter = mInputParameters[0]; + + // neighbor parameter + mNeighborStorePar = mOutputParameters[0]; + + // input neighbor groups + mNeighbors = mInputNeighborGroups[0]; +} + +NeighborDistanceStoreBehavior::~NeighborDistanceStoreBehavior() +{} + +Behavior* +NeighborDistanceStoreBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != nullptr) return new NeighborDistanceStoreBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new NeighborDistanceStoreBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +NeighborDistanceStoreBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new NeighborDistanceStoreBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +NeighborDistanceStoreBehavior::act() +{ + if(mActivePar->value() <= 0.0) return; + + space::NeighborGroup& neighbors = *mNeighbors; + unsigned int neighborCount = neighbors.neighborCount(); + Eigen::VectorXf& neighborStoreValues = mNeighborStorePar->backupValues(); + unsigned int neighborStoreParDim = mNeighborStorePar->dim(); + + int storeIndex = 0; + neighborStoreValues[storeIndex++] = 0.0; + + for(unsigned int neighborNr=0; neighborNrdistance(); + } + for(; storeIndexname().toStdString() << " neighborStore " << *mNeighborStorePar << "\n"; +} \ No newline at end of file diff --git a/src/dab_flock_neighbor_distance_store_behavior.h b/src/dab_flock_neighbor_distance_store_behavior.h new file mode 100644 index 0000000..d98721d --- /dev/null +++ b/src/dab_flock_neighbor_distance_store_behavior.h @@ -0,0 +1,94 @@ +/** \file dab_flock_neighbor_distance_store_behavior.h + * \class dab::flock::NeighborStoreBehavior store neighborhood information in agent parameter + * \brief store neighborhood information in agent parameter + * + * The Behavior stores the distance of neighbors in an output parameter\n + * The dimension of the output parameter is fixed and must be 1 + maxNeighborCount\n + * If there are fewer neighbors than the parameter can hold, the remaining parameter positions are filled with FLT_MIN\n + * If there are more neighbors than the parameter can hold, they will be ignored\n + * The content of the output Parameter is as follows:\n + * [0] : agent distance ( always 0.0 )\n + * [1] : neighbor1 distance\n + * [2] : neighbor2 distance\n + * etc\n + * \n + * Input Parameter:\n + * type: position dim: nD neighbors: required\n + * \n + * Output Parameter:\n + * type: output dim: 1 + maxNeighborCount write: replace\n + * \n + * Created by Daniel Bisig on 30/12/08. + * Ported to OpenFrameworks by Daniel Bisig on 16/10/2017. + */ + + +#ifndef _dab_flock_neighbor_distance_store_behavior_h_ +#define _dab_flock_neighbor_distance_store_behavior_h_ + +#include "dab_flock_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class NeighborDistanceStoreBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + NeighborDistanceStoreBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + NeighborDistanceStoreBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~NeighborDistanceStoreBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mParameter; /// \brief input parameter (input) + Parameter* mNeighborStorePar; /// \brief neighbor store parameter (output) + space::NeighborGroup* mNeighbors; /// \brief neighbor group +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_neighbor_index_store_behavior.cpp b/src/dab_flock_neighbor_index_store_behavior.cpp new file mode 100644 index 0000000..add9008 --- /dev/null +++ b/src/dab_flock_neighbor_index_store_behavior.cpp @@ -0,0 +1,91 @@ +/** \file dab_flock_neighbor_index_store_behavior.cpp + */ + +#include "dab_flock_neighbor_index_store_behavior.h" +#include "dab_flock_agent.h" +#include "dab_space_neighbors.h" +#include "dab_space_neighbor_relation.h" +#include + +using namespace dab; +using namespace dab::flock; + +NeighborIndexStoreBehavior::NeighborIndexStoreBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "NeighborIndexStoreBehavior"; +} + +NeighborIndexStoreBehavior::NeighborIndexStoreBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "NeighborIndexStoreBehavior"; + + if( mInputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputNeighborGroups.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputNeighborGroups.size()) + " neighbor groups supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mParameter = mInputParameters[0]; + + // neighbor parameter + mNeighborStorePar = mOutputParameters[0]; + + // input neighbor groups + mNeighbors = mInputNeighborGroups[0]; +} + +NeighborIndexStoreBehavior::~NeighborIndexStoreBehavior() +{} + +Behavior* +NeighborIndexStoreBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new NeighborIndexStoreBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new NeighborIndexStoreBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +NeighborIndexStoreBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new NeighborIndexStoreBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +NeighborIndexStoreBehavior::act() +{ + if(mActivePar->value() <= 0.0) return; + + space::NeighborGroup& neighbors = *mNeighbors; + unsigned int neighborCount = neighbors.neighborCount(); + Eigen::VectorXf& neighborStoreValues = mNeighborStorePar->backupValues(); + unsigned int neighborStoreParDim = mNeighborStorePar->dim(); + + int storeIndex = 0; + neighborStoreValues[storeIndex++] = static_cast( mAgent->index() ); + + for(unsigned int neighborNr=0; neighborNr( ( static_cast( neighbors[neighborNr]->neighbor() ) )->agent()->index() ); + } + for(; storeIndexname().toStdString() << " neighborStore " << *mNeighborStorePar << "\n"; +} \ No newline at end of file diff --git a/src/dab_flock_neighbor_index_store_behavior.h b/src/dab_flock_neighbor_index_store_behavior.h new file mode 100644 index 0000000..7436944 --- /dev/null +++ b/src/dab_flock_neighbor_index_store_behavior.h @@ -0,0 +1,93 @@ +/** \file dab_flock_neighbor_index_store_behavior.h + * \class dab::flock::NeighborStoreBehavior store neighborhood information in agent parameter + * \brief store neighborhood information in agent parameter + * + * The Behavior stores the index of neighbors in an output parameter\n + * The dimension of the output parameter is fixed and must be 1 + maxNeighborCount\n + * If there are fewer neighbors than the parameter can hold, the remaining parameter positions are filled with FLT_MIN\n + * If there are more neighbors than the parameter can hold, they will be ignored\n + * The content of the output Parameter is as follows:\n + * [0] : agent index\n + * [1] : neighbor1 index\n + * [2] : neighbor2 index\n + * etc\n + * \n + * Input Parameter:\n + * type: position dim: nD neighbors: required\n + * \n + * Output Parameter:\n + * type: output dim: 1 + maxNeighborCount write: replace\n + * \n + * Created by Daniel Bisig on 30/12/08. + * Ported to OpenFrameworks by Daniel Bisig on 16/10/2017. + */ + +#ifndef _dab_flock_neighbor_index_store_behavior_h_ +#define _dab_flock_neighbor_index_store_behavior_h_ + +#include "dab_flock_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class NeighborIndexStoreBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + NeighborIndexStoreBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + NeighborIndexStoreBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~NeighborIndexStoreBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mParameter; /// \brief input parameter (input) + Parameter* mNeighborStorePar; /// \brief neighbor store parameter (output) + space::NeighborGroup* mNeighbors; /// \brief neighbor group +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_neighbor_parameter_store_behavior.cpp b/src/dab_flock_neighbor_parameter_store_behavior.cpp new file mode 100644 index 0000000..fe66e51 --- /dev/null +++ b/src/dab_flock_neighbor_parameter_store_behavior.cpp @@ -0,0 +1,104 @@ +/** \file dab_flock_neighbor_parameter_store_behavior.cpp + */ + +#include "dab_flock_neighbor_parameter_store_behavior.h" +#include "dab_flock_agent.h" +#include "dab_space_neighbors.h" +#include "dab_space_neighbor_relation.h" +#include + +using namespace dab; +using namespace dab::flock; + +NeighborParameterStoreBehavior::NeighborParameterStoreBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "NeighborParameterStoreBehavior"; +} + +NeighborParameterStoreBehavior::NeighborParameterStoreBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "NeighborParameterStoreBehavior"; + + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputNeighborGroups.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputNeighborGroups.size()) + " neighbor groups supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mNeighborInputParameterNames.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters names supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mNeighborParameterName = mNeighborInputParameterNames[0]; + + // neighbor parameter + mNeighborStorePar = mOutputParameters[0]; + + // input neighbor groups + mNeighbors = mInputNeighborGroups[0]; +} + +NeighborParameterStoreBehavior::~NeighborParameterStoreBehavior() +{} + +Behavior* +NeighborParameterStoreBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new NeighborParameterStoreBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new NeighborParameterStoreBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +NeighborParameterStoreBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new NeighborParameterStoreBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +NeighborParameterStoreBehavior::act() +{ + if(mActivePar->value() <= 0.0) return; + + try + { + space::NeighborGroup& neighbors = *mNeighbors; + Eigen::VectorXf& neighborStoreValues = mNeighborStorePar->backupValues(); + unsigned int neighborStoreParDim = mNeighborStorePar->dim(); + unsigned int neighborParDim; + + space::SpaceNeighborRelation* neighborRelation; + unsigned int neighborCount = neighbors.neighborCount(); + + for(unsigned int d=0; d(neighbors.neighbor(neighborNr))->agent()->parameter( mNeighborParameterName )->values(); + + neighborParDim = neighborParValues.rows(); + + for(unsigned int d=0; dname().toStdString() << " neighborStore " << *mNeighborStorePar << "\n"; +} \ No newline at end of file diff --git a/src/dab_flock_neighbor_parameter_store_behavior.h b/src/dab_flock_neighbor_parameter_store_behavior.h new file mode 100644 index 0000000..127f84b --- /dev/null +++ b/src/dab_flock_neighbor_parameter_store_behavior.h @@ -0,0 +1,78 @@ +/** \file dab_flock_neighbor_parameter_store_behavior.h + * iso_flock + * + * Created by Daniel Bisig on 7/6/12. + * Ported to OpenFrameworks by Daniel Bisig on 17/10/2017. + * + */ + +#ifndef _dab_flock_neighbor_parameter_store_behavior_h_ +#define _dab_flock_neighbor_parameter_store_behavior_h_ + +#include "dab_flock_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class NeighborParameterStoreBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + NeighborParameterStoreBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + NeighborParameterStoreBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~NeighborParameterStoreBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + std::string mNeighborParameterName; /// \brief input parameter name (input) + Parameter* mNeighborStorePar; /// \brief neighbor store parameter (output) + space::NeighborGroup* mNeighbors; /// \brief neighbor group +}; + +}; + +}; + + +#endif \ No newline at end of file diff --git a/src/dab_flock_neighbor_store_behavior.cpp b/src/dab_flock_neighbor_store_behavior.cpp new file mode 100644 index 0000000..57f186a --- /dev/null +++ b/src/dab_flock_neighbor_store_behavior.cpp @@ -0,0 +1,93 @@ +/** \file dab_flock_neighbor_store_behavior.cpp + */ + +#include "dab_flock_neighbor_store_behavior.h" +#include "dab_flock_agent.h" +#include "dab_space_neighbor_relation.h" + +using namespace dab; +using namespace dab::flock; + +NeighborStoreBehavior::NeighborStoreBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "NeighborStoreBehavior"; +} + +NeighborStoreBehavior::NeighborStoreBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "NeighborStoreBehavior"; + + if( mInputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputNeighborGroups.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputNeighborGroups.size()) + " neighbor groups supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mParameter = mInputParameters[0]; + + // neighbor parameter + mNeighborStorePar = mOutputParameters[0]; + + // input neighbor groups + mNeighbors = mInputNeighborGroups[0]; +} + +NeighborStoreBehavior::~NeighborStoreBehavior() +{} + +Behavior* +NeighborStoreBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != nullptr) return new NeighborStoreBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new NeighborStoreBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +NeighborStoreBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new NeighborStoreBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +NeighborStoreBehavior::act() +{ + if(mActivePar->value() <= 0.0) return; + + space::NeighborGroup& neighbors = *mNeighbors; + Eigen::VectorXf& neighborStoreValues = mNeighborStorePar->backupValues(); + unsigned int neighborStoreParDim = mNeighborStorePar->dim(); + + space::SpaceNeighborRelation* neighborRelation; + unsigned int neighborCount = neighbors.neighborCount(); + + // reset neighbor store values + neighborStoreValues.setConstant(-1.0); + + unsigned int storeIndex = 0; + neighborStoreValues[storeIndex++] = mAgent->index(); + + for(unsigned int neighborNr=0; neighborNr( neighborRelation->neighbor() ) )->agent()->index(); + neighborStoreValues[storeIndex++] = neighborRelation->distance(); + } + + //std::cout << "agent " << mAgent->name().toStdString() << " neighborStore " << *mNeighborStorePar << "\n"; +} \ No newline at end of file diff --git a/src/dab_flock_neighbor_store_behavior.h b/src/dab_flock_neighbor_store_behavior.h new file mode 100644 index 0000000..1a0fd0c --- /dev/null +++ b/src/dab_flock_neighbor_store_behavior.h @@ -0,0 +1,96 @@ +/** \file dab_flock_neighbor_store_behavior.h + * \class dab::flock::NeighborStoreBehavior store neighborhood information in agent parameter + * \brief store neighborhood information in agent parameter + * + * The Behavior stores the index and distance of neighbors in an output parameter\n + * The dimension of the output parameter is fixed and must be 1 + 2 * maxNeighborCount\n + * If there are fewer neighbors than the parameter can hold, the remaining parameter positions are filled with FLT_MIN\n + * If there are more neighbors than the parameter can hold, they will be ignored\n + * The content of the output Parameter is as follows:\n + * [0] : agent index\n + * [1] : neighbor1 index\n + * [2] : neighbor1 distance\n + * [3] : neighbor2 index\n + * [4] : neighbor2 distance\n + * etc\n + * \n + * Input Parameter:\n + * type: position dim: nD neighbors: required\n + * \n + * Output Parameter:\n + * type: output dim: 1 + 2 * maxNeighborCount write: replace\n + * \n + * Created by Daniel Bisig on 6/12/08. + * Ported to OpenFrameworks by Daniel Bisig on 16/10/2017. + */ + + +#ifndef _dab_flock_neighbor_store_behavior_h_ +#define _dab_flock_neighbor_store_behavior_h_ + +#include "dab_flock_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class NeighborStoreBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + NeighborStoreBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + NeighborStoreBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~NeighborStoreBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mParameter; /// \brief input parameter (input) + Parameter* mNeighborStorePar; /// \brief neighbor store parameter (output) + space::NeighborGroup* mNeighbors; /// \brief neighbor group +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_orbit_behavior.cpp b/src/dab_flock_orbit_behavior.cpp new file mode 100644 index 0000000..6b37888 --- /dev/null +++ b/src/dab_flock_orbit_behavior.cpp @@ -0,0 +1,177 @@ +/** \file dab_flock_orbit_behavior.cpp + */ + +#include "dab_flock_orbit_behavior.h" +#include "dab_flock_parameter.h" +#include "dab_flock_agent.h" +#include "dab_space_neighbor_relation.h" +#include "ofVectorMath.h" +#include "ofMath.h" + +using namespace dab; +using namespace dab::flock; + +OrbitBehavior::OrbitBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "OrbitBehavior"; +} + +OrbitBehavior::OrbitBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "OrbitBehavior"; + + if( mInputParameters.size() < 2 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(2) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mInputParameters[1]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match input parameter " + mInputParameters[1]->name() + " dim " + std::to_string(mInputParameters[1]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != 3 ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + if( mInputNeighborGroups.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputNeighborGroups.size()) + " neighbor groups supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mPositionPar = mInputParameters[0]; + mVelocityPar = mInputParameters[1]; + + // output parameter + mForcePar = mOutputParameters[0]; + + // create internal parameters + mFrequencyPar = createInternalParameter("frequency", { 2.0f }); + mPhasePar = createInternalParameter("phase", { 0.0f }); + mMinDistPar = createInternalParameter("minDist", { 0.0f }); + mMaxDistPar = createInternalParameter("maxDist", { 0.5f }); + mRadAmountPar = createInternalParameter("radAmount", { 3.0f }); + mTanAmountPar = createInternalParameter("tanAmount", { 6.0f }); + mAmountPar = createInternalParameter("amount", { 0.1f }); + + // input neighbor groups + mPositionNeighbors = mInputNeighborGroups[0]; + + // remaining stuff + unsigned int dim = mForcePar->dim(); + mAvgDirection.resize(dim, 1); + mTmpForce.resize(dim, 1); +} + +OrbitBehavior::~OrbitBehavior() +{} + +Behavior* +OrbitBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new OrbitBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new OrbitBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +OrbitBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new OrbitBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +OrbitBehavior::act() +{ + //std::cout << "OrbitBehavior::act() begin\n"; + + //std::cout << "OrbitBehavior begin: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& position = mPositionPar->values(); + Eigen::VectorXf& velocity = mVelocityPar->values(); + + space::NeighborGroup& positionNeighbors = *mPositionNeighbors; + Eigen::VectorXf& force = mForcePar->backupValues(); + float& frequency = mFrequencyPar->value(); + float& phase = mPhasePar->value(); + float& minDist = mMinDistPar->value(); + float& maxDist = mMaxDistPar->value(); + float& radAmount = mRadAmountPar->value(); + float& tanAmount = mTanAmountPar->value(); + float& amount = mAmountPar->value(); + + Eigen::VectorXf& avgDirection = mAvgDirection; + Eigen::VectorXf& tmpForce = mTmpForce; + + unsigned int totalNeighborCount = positionNeighbors.neighborCount(); + + unsigned int neighborCount = 0; + + //std::cout << "cohesion agent " << mAgent->name().toStdString() << " pos " << position << " neighborCount " << totalNeighborCount << "\n"; + + if(totalNeighborCount == 0) return; + + float distance; + float avgDistance; + float scale; + + avgDirection.setConstant(0.0); + + for(unsigned int i=0; iname().toStdString() << " pos " << position << " neighbor pos " << positionNeighbors.neighbor(i)->position() << " distance " << positionNeighbors.distance(i) << " minDist " << minDist << " maxDist " << maxDist << "\n"; + + //std::cout << " neighbor direction " << direction << "\n"; + + if(minDist > 0.0 && distance < minDist) continue; + if(maxDist > 0.0 && distance > maxDist) continue; + + //std::cout << "dist " << distance << " sin " << 10.0 * sin( distance * 10.0 * math::Math::PI ) << "\n"; + + mNormDirection = direction; + mNormDirection.normalize(); + mNormVelocity = velocity; + mNormVelocity.normalize(); + + mCrossVec = mNormDirection.cross( mNormVelocity ); + mCrossVec.normalize(); + + if( mCrossVec[0] < 0 ) mCrossVec2 = mNormDirection.cross( mCrossVec ); + else mCrossVec2 = mCrossVec.cross( mNormDirection ); + mCrossVec2.normalize(); + + avgDirection += mNormDirection * radAmount * -cos( phase + distance * frequency * glm::pi() ); + avgDirection -= mCrossVec2 * tanAmount; + neighborCount++; + + //std::cout << "agent " << mAgent->name().toStdString() << " light " << ( static_cast( positionNeighbors.neighbor(i) ) )->agent()->name().toStdString() << " " << positionNeighbors.neighbor(i)->position() << "\n"; + } + + if(neighborCount == 0) return; + + avgDirection /= static_cast(neighborCount); + + avgDistance = avgDirection.norm(); + if(maxDist > 0.0 && minDist > 0.0) scale = (avgDistance - minDist) / (maxDist - minDist); + else scale = 1.0; + + tmpForce = avgDirection; + + tmpForce.normalize(); + tmpForce *= scale; + tmpForce *= amount; + + //std::cout << "force " << tmpForce << "\n"; + + force += tmpForce; + + //std::cout << "OrbitBehavior::act() end\n"; +} \ No newline at end of file diff --git a/src/dab_flock_orbit_behavior.h b/src/dab_flock_orbit_behavior.h new file mode 100644 index 0000000..cadf2b9 --- /dev/null +++ b/src/dab_flock_orbit_behavior.h @@ -0,0 +1,121 @@ +/** \file dab_flock_orbit_behavior.h + * \class dab::flock::OrbitBehavior cause agents to orbit around the positions of neighboring agents + * \brief cause agents to orbit around the positions of neighboring agents + * + * This behavior causes agents to orbit around the positions of neighboring agents.\n + * A cosine function that extends from the position of the neighboring agent establishes rings of concentric peaks and valleys to which the oribiting agent respond to.\n + * Peaks in the cosine function are avoided by the orbiting agent.\n + * Valleys in the cosine function attract the orbiting agent.\n + * The frequency and position of the cosine function's peaks and valleys can be controlled via the phase abd frequency parameters.\n + * The radAmount parameter controls the attraction and repulsion of the orbiting agent perpendicular to the rings of peaks and valleys\n. + * The tanAmount parameter controls the acceleration of the orbiting agent in a tangential direction with respect to the rings of peaks and valleys\n. + * The orbiting behavior is active when an agent is within a distance from the neighbor agent that lies within the values of minDist and maxDist parameters.\n + * The amount parameter controls the strength of the orbiting behavior.\n + * + * The Behavior causes Agent to move withing a ring\n + * Input Parameter:\n + * type: position dim: nD neighbors: required\n + * type: velocity dim: nD neighbors: ignored\n + * \n + * Output Parameter:\n + * type: force dim: nD write: add\n + * \n + * Internal Parameter:\n + * name: xxx_frequency dim: 1D defaultValue: 2.0\n + * name: xxx_phase dim: 1D defaultValue: 0.0\n + * name: xxx_minDist dim: 1D defaultValue: 0.0\n + * name: xxx_maxDist dim: 1D defaultValue: 0.5\n + * name: xxx_radAmount dim: 1D defaultValue: 3.0\n + * name: xxx_tanAmount dim: 1D defaultValue: 6.0\n + * name: xxx_amount dim: 1D defaultValue: 0.1\n + * \n + * Created by Daniel Bisig, Tasuo Unemi, Koichiro Mori, John Flury on 11/16/07. + * Ported to OpenFrameworks by Daniel Bisig on 22/10/2017. + */ + +#ifndef _dab_flock_orbit_behavior_h_ +#define _dab_flock_orbit_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class Agent; + +class OrbitBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + OrbitBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + OrbitBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~OrbitBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mPositionPar; /// \brief position parameter (input) + Parameter* mVelocityPar; /// \brief velocity parameter (input) + Parameter* mForcePar; /// \brief force parameter (output) + Parameter* mFrequencyPar; /// \brief frequency parameter (internal) + Parameter* mPhasePar; /// \brief phase parameter (internal) + Parameter* mMinDistPar; /// \brief minimum distance parameter (internal) + Parameter* mMaxDistPar; /// \brief maximum distance parameter (internal) + Parameter* mRadAmountPar; /// \brief radial amount parameter (internal) + Parameter* mTanAmountPar; /// \brief tangential amount parameter (internal) + Parameter* mAmountPar; /// \brief behaviour amount parameter (internal) + space::NeighborGroup* mPositionNeighbors; /// \brief position neighbor group + Eigen::Vector3f mNormDirection; ///brief normalized neighbor direction + Eigen::Vector3f mNormVelocity; ///\brief normalized agent velocity + Eigen::Vector3f mCrossVec; ///\brief vector cross product (norm dir, norm vel) + Eigen::Vector3f mCrossVec2; ///\brief normalized agent velocity (cross vec, norm dir) + Eigen::VectorXf mAvgDirection; /// \brief avg of neighboring value directions + Eigen::VectorXf mTmpForce; /// \brief temporary force +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_osc_control.cpp b/src/dab_flock_osc_control.cpp new file mode 100644 index 0000000..bf6067c --- /dev/null +++ b/src/dab_flock_osc_control.cpp @@ -0,0 +1,949 @@ +/** \file dab_flock_osc_control.cpp +*/ + +#include "dab_flock_osc_control.h" +#include "dab_flock_event_includes.h" +#include "dab_flock_visual_event_includes.h" +#include "dab_flock_euler_integration.h" +#include "dab_flock_behavior_includes.h" +#include "dab_flock_serialize.h" +#include "dab_flock_visual.h" +#include "dab_flock_visual_swarm.h" + +using namespace dab; +using namespace dab::flock; + +OscControl::OscControl() +: Singleton() +, OscListener() +, mErrorSender(nullptr) +{} + +OscControl::OscControl( std::shared_ptr pErrorSender ) +: Singleton() +, OscListener() +, mErrorSender(pErrorSender) +{} + +OscControl::~OscControl() +{} + +void +OscControl::setErrorSender( std::shared_ptr pErrorSender ) +{ + mErrorSender = pErrorSender; +} + +void +OscControl::initCreationMaps() +{ + mSpaceAlgMap["PermanentNeighbors"] = space::PermanentNeighborsAlgType; + mSpaceAlgMap["NTree"] = space::NTreeAlgType; + mSpaceAlgMap["KDTree"] = space::KDTreeAlgType; + mSpaceAlgMap["ANN"] = space::ANNAlgType; + mSpaceAlgMap["RTree"] = space::RTreeAlgType; + mSpaceAlgMap["Grid"] = space::GridAlgType; + + mGridUpdateModeMap["NoUpdate"] = space::GridAlg::NoUpdateMode; + mGridUpdateModeMap["NearestReplace"] = space::GridAlg::NearestReplaceMode; + mGridUpdateModeMap["NearestAdd"] = space::GridAlg::NearestAddMode; + mGridUpdateModeMap["AvgReplace"] = space::GridAlg::AvgReplaceMode; + mGridUpdateModeMap["AvgAdd"] = space::GridAlg::AvgAddMode; + + mGridNeighborModeMap["CellLocation"] = space::GridAlg::CellLocationMode; + mGridNeighborModeMap["GridLocation"] = space::GridAlg::GridLocationMode; + mGridNeighborModeMap["AvgLocation"] = space::GridAlg::AvgLocationMode; + mGridNeighborModeMap["AvgRegion"] = space::GridAlg::AvgRegionMode; + + mBehaviorMap["EulerIntegration"] = new EulerIntegration("", ""); + mBehaviorMap["Acceleration"] = new AccelerationBehavior("", ""); + mBehaviorMap["Alignment"] = new AlignmentBehavior("", ""); + mBehaviorMap["BoundaryMirror"] = new BoundaryMirrorBehavior("", ""); + mBehaviorMap["BoundaryRepulsion"] = new BoundaryRepulsionBehavior("", ""); + mBehaviorMap["BoundaryWrap"] = new BoundaryWrapBehavior("", ""); + mBehaviorMap["Circular"] = new CircularBehavior("", "") ; + mBehaviorMap["Cohesion"] = new CohesionBehavior("", ""); + mBehaviorMap["Copy"] = new CopyBehavior("", ""); + mBehaviorMap["Damping"] = new DampingBehavior("", ""); + mBehaviorMap["DistanceFieldFollow"] = new DistanceFieldFollowBehavior("", ""); + mBehaviorMap["Evasion"] = new EvasionBehavior("", ""); + mBehaviorMap["GridAvg"] = new GridAvgBehavior("", ""); + mBehaviorMap["ConeVision"] = new ConeVisionBehavior("", ""); + mBehaviorMap["NeighborIndexStore"] = new NeighborIndexStoreBehavior("", ""); + mBehaviorMap["NeighborDistanceStore"] = new NeighborDistanceStoreBehavior("", ""); + mBehaviorMap["NeighborDirectionStore"] = new NeighborDirectionStoreBehavior("", ""); + mBehaviorMap["NeighborParameterStore"] = new NeighborParameterStoreBehavior("", ""); + mBehaviorMap["ParameterCombine"] = new ParameterCombineBehavior("", ""); + mBehaviorMap["ParameterMap"] = new ParameterMapBehavior("", ""); + mBehaviorMap["ParameterPrint"] = new ParameterPrintBehavior("", ""); + mBehaviorMap["ParameterScale"] = new ParameterScaleBehavior("", ""); + mBehaviorMap["ParameterThresholdToEvent"] = new ParameterThresholdToEventBehavior("", ""); + mBehaviorMap["Randomize"] = new RandomizeBehavior("", ""); + mBehaviorMap["Reset"] = new ResetBehavior("", ""); + mBehaviorMap["Spiral"] = new SpiralBehavior("", ""); + mBehaviorMap["LineFollow"] = new LineFollowBehavior("", ""); + mBehaviorMap["TargetParameter"] = new TargetParameterBehavior("", ""); +} + +space::SpaceAlgType +OscControl::spaceAlgType( const std::string& pSpaceAlgType ) throw (Exception) +{ + if( mSpaceAlgMap.find(pSpaceAlgType) == mSpaceAlgMap.end() ) throw Exception("FLOCK ERROR: space algorithm of type " + pSpaceAlgType + " does not exist", __FILE__, __FUNCTION__, __LINE__); + + return mSpaceAlgMap[pSpaceAlgType]; +} + +space::GridAlg::GridNeighborMode +OscControl::gridNeighborMode( const std::string& pGridNeighborMode ) throw (Exception) +{ + if( mGridNeighborModeMap.find(pGridNeighborMode) == mGridNeighborModeMap.end() ) throw Exception("FLOCK ERROR: grid neighnor mode of type " + pGridNeighborMode + " does not exist", __FILE__, __FUNCTION__, __LINE__); + + return mGridNeighborModeMap[pGridNeighborMode]; +} + +space::GridAlg::GridUpdateMode +OscControl::gridUpdateMode( const std::string& pGridUpdateMode ) throw (Exception) +{ + if( mGridUpdateModeMap.find(pGridUpdateMode) == mGridUpdateModeMap.end() ) throw Exception("FLOCK ERROR: grid update mode of type " + pGridUpdateMode + " does not exist", __FILE__, __FUNCTION__, __LINE__); + + return mGridUpdateModeMap[pGridUpdateMode]; +} + +void +OscControl::groupOscArgs( std::shared_ptr pMessage, std::vector< std::shared_ptr<_OscArg> >& pGroupedArgs ) +{ +// std::cout << *pMessage << "\n"; +// +// std::cout << "arrayCount " << pMessage->arrayCount() << "\n"; + + const std::vector<_OscArg*> arguments = pMessage->arguments(); + int argCount = arguments.size(); + + if(pMessage->arrayCount() > 0) // message alread contains value groups, simple copy them + { + for(int aI=0; aIvalueCount() << "\n"; + + pGroupedArgs.push_back( std::shared_ptr<_OscArg>(arg->copy())); + } + } + else + { + std::vector< std::vector<_OscArg*> > groupedArgs; + + OscType currentType = OSC_TYPE_NONE; + std::vector<_OscArg*> currentGroup; + std::string tmp; + + for(int aI=0; aIvalueCount() << "\n"; +// std::cout << "byteCount " << arg->byteCount() << "\n"; + + if(arg->oscType() == currentType && arg->oscType() != OSC_TYPE_STRING) + { + currentGroup.push_back(arg); + } + else + { + if( currentGroup.size() > 0 ) + { + groupedArgs.push_back(currentGroup); + currentGroup.clear(); + } + + if(arg->oscType() == OSC_TYPE_CHAR) + { + currentType = OSC_TYPE_NONE; + } + else if(arg->oscType() == OSC_TYPE_STRING && arg->valueCount() == 1 ) + { + currentType = OSC_TYPE_NONE; + } + else + { + currentGroup.push_back(arg); + currentType = arg->oscType(); + } + } + } + + if(currentGroup.size() > 0) groupedArgs.push_back(currentGroup); + + int groupCount = groupedArgs.size(); + + //std::cout << "groupCount " << groupCount << "\n"; + + for(int gI=0; gI& group = groupedArgs[gI]; + int groupSize = group.size(); + OscType groupType = group[0]->oscType(); + + //std::cout << "group " << gI << " size " << groupSize << " type " << groupType << "\n"; + + if(groupSize == 1) + { + pGroupedArgs.push_back( std::shared_ptr<_OscArg>(group[0]->copy())); + } + else + { + if(groupType == OSC_TYPE_INT32) + { + std::vector valueVec(groupSize); + for(int vI=0; vI(new OscArg( valueVec.data(), valueVec.size()))); + } + else if(groupType == OSC_TYPE_FLOAT) + { + + + std::vector valueVec(groupSize); + for(int vI=0; vI(new OscArg( valueVec.data(), valueVec.size()))); + } + // etc more types + } + + //std::cout << "new group " << *(pGroupedArgs[ pGroupedArgs.size() - 1]) << "\n"; + } + } +} + + +void +OscControl::notify(std::shared_ptr pMessage) +{ + mLock.lock(); + + //std::cout << "OSCControl::notify\n"; + + try + { + std::string oscCommand = pMessage->address(); + std::vector< std::shared_ptr<_OscArg> > groupedOscArgs; + groupOscArgs(pMessage, groupedOscArgs); + + if(oscCommand == "/ClearSimulation") clearSimulation(); + else if(oscCommand == "/RestoreSimulation") restoreSimulation(groupedOscArgs); + else if(oscCommand == "/SaveSimulation") saveSimulation(groupedOscArgs); + else if(oscCommand == "/SetSimulationRate") setSimulationRate(groupedOscArgs); + else if(oscCommand == "/FreezeSimulation") freezeSimulation(groupedOscArgs); + else if(oscCommand == "/AddSpace") addSpace(groupedOscArgs); + else if(oscCommand == "/AddAgents") addAgents(groupedOscArgs); + else if(oscCommand == "/RemoveAgents") removeAgents(groupedOscArgs); + else if(oscCommand == "/SetParameter") setParameter(groupedOscArgs); + else if(oscCommand == "/ShowSwarm") showSwarm(groupedOscArgs); + else if(oscCommand == "/HideSwarm") hideSwarm(groupedOscArgs); + else if(oscCommand == "/ShowSpace") showSpace(groupedOscArgs); + else if(oscCommand == "/HideSpace") hideSpace(groupedOscArgs); + else if(oscCommand == "/AgentColor") setAgentColor(groupedOscArgs); + else if(oscCommand == "/AgentScale") setAgentScale(groupedOscArgs); + else if(oscCommand == "/AgentLineWidth") setAgentLineWidth(groupedOscArgs); + else if(oscCommand == "/TrailColor") setTrailColor(groupedOscArgs); + else if(oscCommand == "/TrailLength") setTrailLength(groupedOscArgs); + else if(oscCommand == "/TrailDecay") setTrailDecay(groupedOscArgs); + else if(oscCommand == "/TrailLineWidth") setTrailLineWidth(groupedOscArgs); + } + catch(dab::Exception& e) + { + e += dab::Exception("COM ERROR: OscControl notify failed", __FILE__, __FUNCTION__, __LINE__); + throw e; + } + + mLock.unlock(); +} + +void +OscControl::clearSimulation() throw (Exception) +{ + try + { + Simulation::get().event().addEvent( std::shared_ptr(new ClearSimulationEvent()) ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::restoreSimulation(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 1 && pParameters[0]->oscType() == OSC_TYPE_STRING) + { + std::string fileName = pParameters[0]->operator const std::string&(); + Simulation::get().event().addEvent( std::shared_ptr(new RestoreSimulationEvent( fileName )) ); + } + else if(pParameters.size() == 2 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_STRING) + { + std::string fileName = pParameters[0]->operator const std::string&(); + std::string restoreModeString = pParameters[1]->operator const std::string&(); + + if( restoreModeString == "Config" ) Simulation::get().event().addEvent( std::shared_ptr(new RestoreSimulationEvent( fileName, SerializeTools::ConfigMode )) ); + else if( restoreModeString == "Values" ) Simulation::get().event().addEvent( std::shared_ptr(new RestoreSimulationEvent( fileName, SerializeTools::ValuesMode )) ); + else Simulation::get().event().addEvent( std::shared_ptr(new RestoreSimulationEvent( fileName )) ); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /RestoreSimulation", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::saveSimulation(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 1 && pParameters[0]->oscType() == OSC_TYPE_STRING) + { + std::string fileName = pParameters[0]->operator const std::string&(); + Simulation::get().event().addEvent( std::shared_ptr(new SaveSimulationEvent( fileName )) ); + } + else if(pParameters.size() == 2 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_STRING) + { + std::string fileName = pParameters[0]->operator const std::string&(); + std::string restoreModeString = pParameters[1]->operator const std::string&(); + + if( restoreModeString == "Config" ) Simulation::get().event().addEvent( std::shared_ptr(new SaveSimulationEvent( fileName, SerializeTools::ConfigMode )) ); + else if( restoreModeString == "Values" ) Simulation::get().event().addEvent( std::shared_ptr(new SaveSimulationEvent( fileName, SerializeTools::ValuesMode )) ); + else Simulation::get().event().addEvent( std::shared_ptr(new SaveSimulationEvent( fileName )) ); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /SaveSimulation", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::setSimulationRate(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 1 && pParameters[0]->oscType() == OSC_TYPE_FLOAT) + { + float simulationRate = *(pParameters[0]); + Simulation::get().event().addEvent( std::shared_ptr(new SetSimulationRateEvent(simulationRate)) ); + } + else if(pParameters.size() == 1 && pParameters[0]->oscType() == OSC_TYPE_INT32) + { + // simulation rate + int simulationRate = *(pParameters[0]); + Simulation::get().event().addEvent( std::shared_ptr(new SetSimulationRateEvent(static_cast(simulationRate))) ); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /SetSimulationRate", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::freezeSimulation(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 1 && pParameters[0]->oscType() == OSC_TYPE_INT32) + { + int freeze = *(pParameters[0]); + Simulation& simulation = Simulation::get(); + + if( static_cast(freeze) == false && simulation.frozen() == true ) simulation.switchFrozen(); + else if( static_cast(freeze) == true && simulation.frozen() == false ) simulation.switchFrozen(); + } + else if(pParameters.size() == 1 && pParameters[0]->oscType() == OSC_TYPE_FLOAT) + { + float freeze = *(pParameters[0]); + Simulation& simulation = Simulation::get(); + + if( static_cast(freeze) == false && simulation.frozen() == true ) simulation.switchFrozen(); + else if( static_cast(freeze) == true && simulation.frozen() == false ) simulation.switchFrozen(); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /FreezeSimulation", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::addSpace(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 3 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_STRING && pParameters[2]->oscType() == OSC_TYPE_INT32) + { + std::string spaceName = pParameters[0]->operator const std::string&(); + std::string spaceAlgName = pParameters[1]->operator const std::string&(); + int spaceDim = *(pParameters[2]); + + Simulation::get().event().addEvent( std::shared_ptr(new AddSpaceEvent( spaceName, spaceAlgType(spaceAlgName), spaceDim)) ); + + } + else if(pParameters.size() == 4 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_STRING && pParameters[2]->oscType() == EXT_TYPE_ARG_FLOAT_ARRAY && pParameters[3]->oscType() == EXT_TYPE_ARG_FLOAT_ARRAY ) + { + std::string spaceName = pParameters[0]->operator const std::string&(); + std::string spaceAlgName = pParameters[1]->operator const std::string&(); + int spaceDim = pParameters[2]->valueCount(); + float* spaceMinPosValues = *(pParameters[2]); + float* spaceMaxPosValues = *(pParameters[3]); + + Eigen::VectorXf spaceMinPos(spaceDim); + for(int d=0; d(new AddSpaceEvent( spaceName, spaceAlgType(spaceAlgName), spaceMinPos, spaceMaxPos)) ); + } + else if(pParameters.size() == 8 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_STRING && pParameters[2]->oscType() == OSC_TYPE_INT32 && pParameters[3]->oscType() == EXT_TYPE_ARG_INT32_ARRAY && pParameters[4]->oscType() == EXT_TYPE_ARG_FLOAT_ARRAY && pParameters[5]->oscType() == EXT_TYPE_ARG_FLOAT_ARRAY && pParameters[6]->oscType() == OSC_TYPE_STRING && pParameters[7]->oscType() == OSC_TYPE_STRING) + { + std::string spaceName = pParameters[0]->operator const std::string&(); + std::string spaceAlgName = pParameters[1]->operator const std::string&(); + int gridValueDim = *(pParameters[2]); + int spaceDim = pParameters[3]->valueCount(); + int* gridSubdivisionValues = *(pParameters[3]); + float* spaceMinPosValues = *(pParameters[4]); + float* spaceMaxPosValues = *(pParameters[5]); + std::string gridNeighborModeName = pParameters[6]->operator const std::string&(); + std::string gridUpdateModeName = pParameters[7]->operator const std::string&(); + + dab::Array gridSubdivisionCount(spaceDim); + for(int d=0; d(new AddSpaceEvent(spaceName, spaceAlgType(spaceAlgName), gridValueDim, gridSubdivisionCount, spaceMinPos, spaceMaxPos, gridNeighborMode(gridNeighborModeName), gridUpdateMode(gridUpdateModeName))) ); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /AddSpace", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::addAgents(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 2 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_INT32) + { + // swarm name / agent count + std::string swarmName = pParameters[0]->operator const std::string&(); + int agentCount = *(pParameters[1]); + + Simulation::get().event().addEvent( std::shared_ptr(new AddAgentsEvent( swarmName, agentCount ))); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /AddAgents", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::removeAgents(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 1 && pParameters[0]->oscType() == OSC_TYPE_STRING) + { + // swarm name + std::string swarmName = pParameters[0]->operator const std::string&(); + + Simulation::get().event().addEvent( std::shared_ptr(new RemoveAgentsEvent( swarmName ))); + } + else if(pParameters.size() == 2 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_INT32) + { + // swarm name / agent count + std::string swarmName = pParameters[0]->operator const std::string&(); + int agentCount = *(pParameters[1]); + + Simulation::get().event().addEvent( std::shared_ptr(new RemoveAgentsEvent( swarmName, agentCount ))); + } + else if(pParameters.size() == 2 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == EXT_TYPE_ARG_INT32_ARRAY) + { + // swarm name / agent start index / agent end index + std::string swarmName = pParameters[0]->operator const std::string&(); + int parameterDim = pParameters[1]->valueCount(); + int* agentIndices = *(pParameters[1]); + int agentStartIndex = 0; + int agentEndIndex = 0; + + if(parameterDim == 1) + { + agentStartIndex = agentIndices[0]; + agentEndIndex = agentStartIndex; + } + else if(parameterDim > 1) + { + agentStartIndex = agentIndices[0]; + agentEndIndex = agentIndices[1]; + } + + Simulation::get().event().addEvent( std::shared_ptr(new RemoveAgentsEvent( swarmName, agentStartIndex, agentEndIndex ))); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /RemoveAgents", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::setParameter(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 3 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_STRING && pParameters[2]->oscType() == OSC_TYPE_FLOAT) + { + // swarm name / parameter name / parameter value + std::string swarmName = pParameters[0]->operator const std::string&(); + std::string parameterName = pParameters[1]->operator const std::string&(); + float parameterValue = *(pParameters[2]); + + Eigen::VectorXf parameterVec(1); + parameterVec[0] = parameterValue; + + Simulation::get().event().addEvent( std::shared_ptr(new SetParameterEvent(swarmName, parameterName, parameterVec))); + } + else if(pParameters.size() == 3 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_STRING && pParameters[2]->oscType() == EXT_TYPE_ARG_FLOAT_ARRAY) + { + // swarm name / parameter name / parameter values + std::string swarmName = pParameters[0]->operator const std::string&(); + std::string parameterName = pParameters[1]->operator const std::string&(); + int parameterDim = pParameters[2]->valueCount(); + float* parameterValues = *(pParameters[2]); + + Eigen::VectorXf parameterVec(parameterDim); + for(int d=0; d(new SetParameterEvent(swarmName, parameterName, parameterVec))); + } + else if(pParameters.size() == 4 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_STRING && pParameters[2]->oscType() == OSC_TYPE_FLOAT && pParameters[3]->oscType() == OSC_TYPE_FLOAT) + { + // swarm name / parameter name / parameter value / duration + std::string swarmName = pParameters[0]->operator const std::string&(); + std::string parameterName = pParameters[1]->operator const std::string&(); + float parameterValue = *(pParameters[2]); + float duration = *(pParameters[3]); + + Eigen::VectorXf parameterVec(1); + parameterVec[0] = parameterValue; + + Simulation::get().event().addEvent( std::shared_ptr(new SetParameterEvent(swarmName, parameterName, parameterVec, duration))); + } + else if(pParameters.size() == 4 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_STRING && pParameters[2]->oscType() == EXT_TYPE_ARG_FLOAT_ARRAY && pParameters[3]->oscType() == OSC_TYPE_FLOAT) + { + // swarm name / parameter name / parameter values / duration + std::string swarmName = pParameters[0]->operator const std::string&(); + std::string parameterName = pParameters[1]->operator const std::string&(); + int parameterDim = pParameters[2]->valueCount(); + float* parameterValues = *(pParameters[2]); + float duration = *(pParameters[3]); + + Eigen::VectorXf parameterVec(parameterDim); + for(int d=0; d(new SetParameterEvent(swarmName, parameterName, parameterVec, duration))); + } + else if(pParameters.size() == 4 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_STRING && pParameters[2]->oscType() == OSC_TYPE_INT32 && pParameters[3]->oscType() == OSC_TYPE_FLOAT) + { + // swarm name / parameter name / agent index / parameter value + + std::string swarmName = pParameters[0]->operator const std::string&(); + std::string parameterName = pParameters[1]->operator const std::string&(); + int agentIndex = *(pParameters[2]); + float parameterValue = *(pParameters[3]); + + Eigen::VectorXf parameterVec(1); + parameterVec[0] = parameterValue; + + Simulation::get().event().addEvent( std::shared_ptr(new SetParameterEvent(swarmName, parameterName, agentIndex, parameterVec))); + } + else if(pParameters.size() == 4 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_STRING && pParameters[2]->oscType() == OSC_TYPE_INT32 && pParameters[3]->oscType() == EXT_TYPE_ARG_FLOAT_ARRAY) + { + // swarm name / parameter name / agent index / parameter values + + std::string swarmName = pParameters[0]->operator const std::string&(); + std::string parameterName = pParameters[1]->operator const std::string&(); + int agentIndex = *(pParameters[2]); + int parameterDim = pParameters[3]->valueCount(); + float* parameterValues = *(pParameters[3]); + + Eigen::VectorXf parameterVec(parameterDim); + for(int d=0; d(new SetParameterEvent(swarmName, parameterName, agentIndex, parameterVec))); + } + else if(pParameters.size() == 5 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_STRING && pParameters[2]->oscType() == OSC_TYPE_INT32 && pParameters[3]->oscType() == OSC_TYPE_FLOAT && pParameters[4]->oscType() == OSC_TYPE_FLOAT) + { + // swarm name / parameter name / agent index / parameter value / interpolation duration + + std::string swarmName = pParameters[0]->operator const std::string&(); + std::string parameterName = pParameters[1]->operator const std::string&(); + int agentIndex = *(pParameters[2]); + float parameterValue = *(pParameters[3]); + float duration = *(pParameters[4]); + + Eigen::VectorXf parameterVec(1); + parameterVec[0] = parameterValue; + + Simulation::get().event().addEvent( std::shared_ptr(new SetParameterEvent(swarmName, parameterName, agentIndex, parameterVec, duration))); + } + else if(pParameters.size() == 5 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_STRING && pParameters[2]->oscType() == OSC_TYPE_INT32 && pParameters[3]->oscType() == EXT_TYPE_ARG_FLOAT_ARRAY && pParameters[4]->oscType() == OSC_TYPE_FLOAT) + { + // swarm name / parameter name / agent index / parameter values / interpolation duration + + std::string swarmName = pParameters[0]->operator const std::string&(); + std::string parameterName = pParameters[1]->operator const std::string&(); + int agentIndex = *(pParameters[2]); + int parameterDim = pParameters[3]->valueCount(); + float* parameterValues = *(pParameters[3]); + float duration = *(pParameters[4]); + + Eigen::VectorXf parameterVec(parameterDim); + for(int d=0; d(new SetParameterEvent(swarmName, parameterName, agentIndex, parameterVec, duration))); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /SetParameter", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::showSwarm(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 2 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_STRING) + { + std::string swarmName = pParameters[0]->operator const std::string&(); + std::string posParName = pParameters[1]->operator const std::string&(); + + FlockVisuals::get().event().addEvent( std::shared_ptr(new ShowSwarmEvent(swarmName, posParName))); + } + else if(pParameters.size() == 3 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_STRING && pParameters[2]->oscType() == OSC_TYPE_STRING) + { + std::string swarmName = pParameters[0]->operator const std::string&(); + std::string posParName = pParameters[1]->operator const std::string&(); + std::string velParName = pParameters[2]->operator const std::string&(); + + FlockVisuals::get().event().addEvent( std::shared_ptr(new ShowSwarmEvent(swarmName, posParName, velParName))); + } + else if(pParameters.size() == 4 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_STRING && pParameters[2]->oscType() == OSC_TYPE_STRING && pParameters[3]->oscType() == OSC_TYPE_INT32) + { + std::string swarmName = pParameters[0]->operator const std::string&(); + std::string posParName = pParameters[1]->operator const std::string&(); + std::string velParName = pParameters[2]->operator const std::string&(); + int trailLength = *(pParameters[3]); + + FlockVisuals::get().event().addEvent( std::shared_ptr(new ShowSwarmEvent(swarmName, posParName, velParName, trailLength))); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /ShowSwarm", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::hideSwarm(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 1 && pParameters[0]->oscType() == OSC_TYPE_STRING) + { + std::string swarmName = pParameters[0]->operator const std::string&(); + + FlockVisuals::get().event().addEvent( std::shared_ptr(new HideSwarmEvent(swarmName))); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /HideSwarm", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::showSpace(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 1 && pParameters[0]->oscType() == OSC_TYPE_STRING) + { + std::string spaceName = pParameters[0]->operator const std::string&(); + + FlockVisuals::get().event().addEvent( std::shared_ptr(new ShowSpaceEvent(spaceName))); + } + else if(pParameters.size() == 2 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == EXT_TYPE_ARG_FLOAT_ARRAY) + { + std::string spaceName = pParameters[0]->operator const std::string&(); + + int colorDim = pParameters[1]->valueCount(); + float* colorValues = *(pParameters[1]); + + if(colorDim != 4) throw Exception("FLOCK ERROR: iWrong Parameters for /ShowSwarm", __FILE__, __FUNCTION__, __LINE__ ); + + std::array color = { colorValues[0], colorValues[1], colorValues[2], colorValues[3] }; + + FlockVisuals::get().event().addEvent( std::shared_ptr(new ShowSpaceEvent(spaceName, color))); + } + else if(pParameters.size() == 3 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == EXT_TYPE_ARG_FLOAT_ARRAY && pParameters[2]->oscType() == OSC_TYPE_FLOAT) + { + std::string spaceName = pParameters[0]->operator const std::string&(); + int colorDim = pParameters[1]->valueCount(); + float* colorValues = *(pParameters[1]); + float valueScale = *(pParameters[2]); + + + if(colorDim != 4) throw Exception("FLOCK ERROR: iWrong Parameters for /ShowSwarm", __FILE__, __FUNCTION__, __LINE__ ); + + std::array color = { colorValues[0], colorValues[1], colorValues[2], colorValues[3] }; + + FlockVisuals::get().event().addEvent( std::shared_ptr(new ShowSpaceEvent(spaceName, color, valueScale))); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /ShowSwarm", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::hideSpace(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 1 && pParameters[0]->oscType() == OSC_TYPE_STRING) + { + std::string spaceName = pParameters[0]->operator const std::string&(); + + FlockVisuals::get().event().addEvent( std::shared_ptr(new HideSpaceEvent(spaceName))); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /HideSpace", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::setAgentColor(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 2 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == EXT_TYPE_ARG_FLOAT_ARRAY) + { + std::string swarmName = pParameters[0]->operator const std::string&(); + + int colorDim = pParameters[1]->valueCount(); + float* colorValues = *(pParameters[1]); + + if(colorDim != 4) throw Exception("FLOCK ERROR: Wrong Parameters for /AgentColor", __FILE__, __FUNCTION__, __LINE__ ); + + std::array color = { colorValues[0], colorValues[1], colorValues[2], colorValues[3] }; + + VisSwarm* visSwarm = FlockVisuals::get().visualSwarm(swarmName); + + visSwarm->setAgentColor(color); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /AgentColor", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::setAgentScale(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 2 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_FLOAT) + { + std::string swarmName = pParameters[0]->operator const std::string&(); + float agentScale = *(pParameters[1]); + + VisSwarm* visSwarm = FlockVisuals::get().visualSwarm(swarmName); + + visSwarm->setAgentScale( ofVec3f(agentScale, agentScale, agentScale) ); + } + else if(pParameters.size() == 2 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == EXT_TYPE_ARG_FLOAT_ARRAY) + { + std::string swarmName = pParameters[0]->operator const std::string&(); + + int agentScaleDim = pParameters[1]->valueCount(); + float* agentScaleValues = *(pParameters[1]); + + if(agentScaleDim != 3) throw Exception("FLOCK ERROR: Wrong Parameters for /AgentScale", __FILE__, __FUNCTION__, __LINE__ ); + + ofVec3f agentScale( agentScaleValues[0], agentScaleValues[1], agentScaleValues[2] ); + + VisSwarm* visSwarm = FlockVisuals::get().visualSwarm(swarmName); + + visSwarm->setAgentScale( agentScale ); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /AgentScale", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::setAgentLineWidth(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 2 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_FLOAT) + { + std::string swarmName = pParameters[0]->operator const std::string&(); + float agentLineWidth = *(pParameters[1]); + + VisSwarm* visSwarm = FlockVisuals::get().visualSwarm(swarmName); + + visSwarm->setAgentLineWidth( agentLineWidth ); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /AgentLineWidth", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::setTrailColor(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 2 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == EXT_TYPE_ARG_FLOAT_ARRAY) + { + std::string swarmName = pParameters[0]->operator const std::string&(); + + int trailColorDim = pParameters[1]->valueCount(); + float* trailColorValues = *(pParameters[1]); + + if(trailColorDim != 4) throw Exception("FLOCK ERROR: Wrong Parameters for /TrailColor", __FILE__, __FUNCTION__, __LINE__ ); + + std::array trailColor = { trailColorValues[0], trailColorValues[1], trailColorValues[2], trailColorValues[3] }; + + VisSwarm* visSwarm = FlockVisuals::get().visualSwarm(swarmName); + + visSwarm->setTrailColor(trailColor); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /TrailColor", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::setTrailLength(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 2 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_INT32) + { + std::string swarmName = pParameters[0]->operator const std::string&(); + int trailLength = *(pParameters[1]); + + VisSwarm* visSwarm = FlockVisuals::get().visualSwarm(swarmName); + + visSwarm->setTrailLength(trailLength); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /TrailLength", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::setTrailDecay(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 2 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_FLOAT) + { + std::string swarmName = pParameters[0]->operator const std::string&(); + float trailDecay = *(pParameters[1]); + + VisSwarm* visSwarm = FlockVisuals::get().visualSwarm(swarmName); + + visSwarm->setTrailDecay(trailDecay); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /TrailFloat", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +OscControl::setTrailLineWidth(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception) +{ + try + { + if(pParameters.size() == 2 && pParameters[0]->oscType() == OSC_TYPE_STRING && pParameters[1]->oscType() == OSC_TYPE_FLOAT) + { + std::string swarmName = pParameters[0]->operator const std::string&(); + float trailWidth = *(pParameters[1]); + + VisSwarm* visSwarm = FlockVisuals::get().visualSwarm(swarmName); + + visSwarm->setTrailWidth(trailWidth); + } + else throw Exception( "FLOCK ERROR: Wrong Parameters for /TrailLineWidth", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} \ No newline at end of file diff --git a/src/dab_flock_osc_control.h b/src/dab_flock_osc_control.h new file mode 100644 index 0000000..64798ac --- /dev/null +++ b/src/dab_flock_osc_control.h @@ -0,0 +1,158 @@ +/** \file iso_dab_osc_control.h + * + * Created by Daniel Bisig on 6/7/09. + * Ported to OpenFrameworks by Daniel Bisig on 26.08.2017 + * + */ + +#ifndef _dab_flock_osc_control_h_ +#define _dab_flock_osc_control_h_ + +#include "dab_exception.h" +#include "dab_singleton.h" +#include "dab_osc_sender.h" +#include "dab_osc_receiver.h" +#include "dab_space_types.h" +#include "dab_space_alg.h" +#include "dab_space_alg_grid.h" +#include "dab_flock_behavior.h" +#include "dab_flock_add_space_event.h" +#include "ofTypes.h" + +namespace dab +{ + +namespace event +{ +class Event; +} + +namespace flock +{ + +class OscControl : public Singleton, public OscListener +{ +public: + OscControl(); + OscControl( std::shared_ptr pErrorSender ); + ~OscControl(); + + void setErrorSender( std::shared_ptr pErrorSender ); + + virtual void notify(std::shared_ptr pMessage); + +protected: + std::shared_ptr mErrorSender; + + std::map< std::string, space::SpaceAlgType > mSpaceAlgMap; + std::map< std::string, space::GridAlg::GridNeighborMode > mGridNeighborModeMap; + std::map< std::string, space::GridAlg::GridUpdateMode > mGridUpdateModeMap; + std::map< std::string, Behavior* > mBehaviorMap; + + ofMutex mLock; + + void initCreationMaps(); + space::SpaceAlgType spaceAlgType( const std::string& pSpaceAlgType ) throw (Exception); + space::GridAlg::GridNeighborMode gridNeighborMode( const std::string& pGridNeighborMode ) throw (Exception); + space::GridAlg::GridUpdateMode gridUpdateMode( const std::string& pGridUpdateMode ) throw (Exception); + + void groupOscArgs( std::shared_ptr pMessage, std::vector< std::shared_ptr<_OscArg> >& pGroupedArgs ); + + + void clearSimulation( ) throw (Exception); + void restoreSimulation(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); + void saveSimulation(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); + void setSimulationRate(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); + void freezeSimulation(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); + void addSpace(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); +// void removeSpace(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void addSender(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void removeSender(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void addReceiver(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void removeReceiver(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void addSwarm(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void removeSwarm(std::vector<_OscArg*>& pParameters()) throw (Exception); + void addAgents(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); + void removeAgents(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); +// void addParameter(std::vector<_OscArg*>& pParameters()) throw (Exception); + void setParameter(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); +// void randomizeParameter(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void removeParameter(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void assignNeighbors(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void removeNeigbors(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void registerParameter(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void deregisterParameter(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void addBehavior(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void moveBehavior(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void removeBehavior(std::vector<_OscArg*>& pParameters()) throw (Exception); + void showSwarm(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); + void hideSwarm(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); + void showSpace(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); + void hideSpace(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); +// void setDisplayColor(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void setDisplayPosition(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void setDisplayOrientation(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void changeDisplayOrientation(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void setDisplayZoom(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void setWindowSettings(std::vector<_OscArg*>& pParameters()) throw (Exception); +// virtual void toggleFullScreen( ) throw (Exception); + void setAgentColor(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); + void setAgentScale(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); + void setAgentLineWidth(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); + void setTrailColor(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); + void setTrailLength(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); + void setTrailDecay(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); + void setTrailLineWidth(const std::vector< std::shared_ptr<_OscArg> >& pParameters) throw (Exception); +// void setSpaceColor(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void setSpaceValueScale(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void saveImage(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void startRecordMovie(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void stopRecordMovie(std::vector<_OscArg*>& pParameters()) throw (Exception); +// +// void queryAgentParameterCount(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void queryAgentParameterName(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void queryAgentParameterValue(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void querySwarmCount(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void querySpaceCount(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void querySenderCount(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void querySwarm(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void querySpace(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void querySender(std::vector<_OscArg*>& pParameters()) throw (Exception); +// void queryParameter(std::vector<_OscArg*>& pParameters()) throw (Exception); + + /* + base::String stringPar( com::MessageValueGroup* pParameter ) throw (FlockException); + int intPar( com::MessageValueGroup* pParameter ) throw (FlockException); + math::Vector intVecPar( com::MessageValueGroup* pParameter ) throw (FlockException); + float floatPar( com::MessageValueGroup* pParameter ) throw (FlockException); + math::Vector floatVecPar( com::MessageValueGroup* pParameter ) throw (FlockException); + bool boolPar( com::MessageValueGroup* pParameter ) throw (FlockException); + SpaceAlgType spaceAlgPar( com::MessageValueGroup* pParameter ) throw (FlockException); + com::Protocol comProtocolPar( com::MessageValueGroup* pParameter ) throw (FlockException); + com::Format comFormatPar( com::MessageValueGroup* pParameter ) throw (FlockException); + base::String behaviorParameterPar( com::MessageValueGroup* pParameter ) throw (FlockException); + */ + + /* + com::Message mMessage; + base::String mOSCCommand; + com::Message mOSCParameters; + com::Sender* mErrorSender; + + QHash< base::String, SpaceAlgType > mSpaceAlgMap; + QHash< base::String, space::GridAlg::GridNeighborMode > mGridNeighborModeMap; + QHash< base::String, space::GridAlg::GridUpdateMode > mGridUpdateModeMap; + QHash< base::String, com::Protocol > mComProtocolMap; + QHash< base::String, com::Format > mComFormatMap; + QHash< base::String, Behavior* > mBehaviorMap; + */ + + template void groupOscArgs( const std::vector<_OscArg*>& pInputArgs, int& pGoupStartIndex, std::vector<_OscArg*>& pGroupedArgs ); + +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_parameter.cpp b/src/dab_flock_parameter.cpp new file mode 100644 index 0000000..787e5f1 --- /dev/null +++ b/src/dab_flock_parameter.cpp @@ -0,0 +1,388 @@ +/** \file dab_flock_parameter.cpp + */ + +#include "dab_flock_parameter.h" +#include "dab_math.h" +#include "dab_space_manager.h" +#include "dab_space_neighbor_group_alg.h" +#include "dab_flock_agent.h" +#include "dab_flock_simulation.h" + +using namespace dab; +using namespace dab::flock; + +const std::string Parameter::sClassName = "Parameter"; + +Parameter::Parameter() +: SpaceObject(1) +, mAgent(nullptr) +, mValues(mPosition) +, mBackupValues(mPosition) +{} + +Parameter::Parameter(Agent* pAgent, const std::string& pName, unsigned int pDim) +: SpaceObject(pDim) +, mName(pName) +, mAgent(pAgent) +, mValues(mPosition) +, mBackupValues(mPosition) +{} + +Parameter::Parameter(Agent* pAgent, const std::string& pName, const std::initializer_list& pValues) +: SpaceObject(pValues.size()) +, mName(pName) +, mValues(mPosition) +, mBackupValues(mPosition) +{ + auto iter = pValues.begin(); + + for( int d=0; d < mDim; ++d, ++iter) + { + mValues[d] = *iter; + mBackupValues[d] = *iter; + } +} + +Parameter::Parameter(Agent* pAgent, const std::string& pName, const std::vector& pValues) +: SpaceObject(pValues.size()) +, mName(pName) +, mValues(mPosition) +, mBackupValues(mPosition) +{ + auto iter = pValues.begin(); + + for( int d=0; d < mDim; ++d, ++iter) + { + mValues[d] = *iter; + mBackupValues[d] = *iter; + } +} + +Parameter::Parameter(Agent* pAgent, const std::string& pName, unsigned int pValueCount, const float* pValues) +: SpaceObject(pValueCount) +, mName(pName) +, mValues(mPosition) +, mBackupValues(mPosition) +{ + for(int d=0; d& pValues) throw (Exception) +{ + if(pValues.size() != mDim) throw Exception( "FLOCK ERROR: valueCount mismatch: " + std::to_string(mDim) + " != " + std::to_string(pValues.size()) + " for parameter " + mName, __FILE__, __FUNCTION__, __LINE__ ); + + auto iter = pValues.begin(); + + for( int d=0; d < mDim; ++d, ++iter) + { + if( isnan( *iter ) == false )mBackupValues[d] = *iter; + } +} + +void +Parameter::set(unsigned int pValueCount, const float* pValues) throw (Exception) +{ + if(pValueCount != mDim) throw Exception( "FLOCK ERROR: valueCount mismatch: " + std::to_string(mDim) + " != " + std::to_string(pValueCount) + " for parameter " + mName, __FILE__, __FUNCTION__, __LINE__ ); + + for(unsigned int d=0; d& pValues) throw (Exception) +{ + if(pValues.size() != mDim) throw Exception( "FLOCK ERROR: valueCount mismatch: " + std::to_string(mDim) + " != " + std::to_string(pValues.size()) + " for parameter " + mName, __FILE__, __FUNCTION__, __LINE__ ); + + auto iter = pValues.begin(); + + for( int d=0; d < mDim; ++d, ++iter) + { + if( isnan( *iter ) == false ) mBackupValues[d] += *iter; + } +} + +void +Parameter::change(unsigned int pValueCount, float* pValues) throw (Exception) +{ + if(pValueCount != mDim) throw Exception( "FLOCK ERROR: valueCount mismatch: " + std::to_string(mDim) + " != " + std::to_string(pValueCount) + " for parameter " + mName, __FILE__, __FUNCTION__, __LINE__ ); + + for(unsigned int d=0; d& math = math::Math<>::get(); + + for(unsigned int d=0; d& pMinParameterValues, const std::initializer_list& pMaxParameterValues) throw (Exception) +{ + if(pMinParameterValues.size() != mDim) throw Exception( "FLOCK ERROR: valueCount mismatch: " + std::to_string(mDim) + " != " + std::to_string(pMinParameterValues.size()) + " for parameter " + mName, __FILE__, __FUNCTION__, __LINE__ ); + if(pMaxParameterValues.size() != mDim) throw Exception( "FLOCK ERROR: valueCount mismatch: " + std::to_string(mDim) + " != " + std::to_string(pMaxParameterValues.size()) + " for parameter " + mName, __FILE__, __FUNCTION__, __LINE__ ); + + math::Math<>& math = math::Math<>::get(); + + auto minIter = pMinParameterValues.begin(); + auto maxIter = pMaxParameterValues.begin(); + + for(int d=0; d& math = math::Math<>::get(); + + for(unsigned int d=0; dsetValues(mValues); +} + +Eigen::VectorXf& +Parameter::values() +{ + return mValues; +} + +const Eigen::VectorXf& +Parameter::values() const +{ + return mValues; +} + +float& +Parameter::value(unsigned int pIndex) throw (Exception) +{ + if( pIndex >= mDim ) throw Exception( "FLOCK ERROR: Index " + std::to_string(pIndex) + " Out Of Bounds (Parameter Dim " + std::to_string(mDim) + ") ", __FILE__, __FUNCTION__, __LINE__ ); + + return mValues[pIndex]; +} + +Eigen::VectorXf& +Parameter::backupValues() +{ + return mBackupValues; +} + +float& +Parameter::backupValue(unsigned int pIndex) throw (Exception) +{ + if( pIndex >= mDim ) throw Exception( "FLOCK ERROR: Index " + std::to_string(pIndex) + " Out Of Bounds (Parameter Dim " + std::to_string(mDim) + ") ", __FILE__, __FUNCTION__, __LINE__ ); + + return mBackupValues[pIndex]; +} + +const Eigen::VectorXf& +Parameter::operator=( const Eigen::VectorXf& pValues) throw (Exception) +{ + if( pValues.rows() != mBackupValues.rows() ) throw Exception( "FLOCK ERROR: Incompatible Parameter Dimension " + std::to_string(mBackupValues.rows()) + " Values Dimension " + std::to_string(pValues.rows()) + ") ", __FILE__, __FUNCTION__, __LINE__ ); + + mBackupValues = pValues; + + return mBackupValues; +} + +const Eigen::VectorXf& +Parameter::operator=( const std::initializer_list& pValues) throw (Exception) +{ + if( pValues.size() != mBackupValues.rows() ) throw Exception( "FLOCK ERROR: Incompatible Parameter Dimension " + std::to_string(mBackupValues.rows()) + " Values Dimension " + std::to_string(pValues.size()) + ") ", __FILE__, __FUNCTION__, __LINE__ ); + + auto iter = pValues.begin(); + + for(int d=0; d& pValues) throw (Exception) +{ + if( pValues.size() != mValues.rows() ) throw Exception( "FLOCK ERROR: Incompatible Parameter Dimension " + std::to_string(mValues.rows()) + " Values Dimension " + std::to_string(pValues.size()) + ") ", __FILE__, __FUNCTION__, __LINE__ ); + + auto iter = pValues.begin(); + + for(unsigned int d=0; d +#include +#include "dab_exception.h" +#include "dab_index_map.h" +#include "dab_space_object.h" + +namespace dab +{ + +namespace flock +{ + +class Agent; + +class Parameter : public space::SpaceObject +{ +public: + /** + \brief class name + */ + static const std::string sClassName; + + /** + \brief create parameter + \param pAgent agent this parameter belongs to + \param pName parameter name + \param pDim dimension of parameter (> 0) + */ + Parameter(Agent* pAgent, const std::string& pName, unsigned int pDim); + + /** + \brief create parameter + \param pAgent agent this parameter belongs to + \param pName parameter name + \param pValueCount number of values + \param pValues values + \exception Exception number of values cannot be changed + */ + Parameter(Agent* pAgent, const std::string& pName, unsigned int pValueCount, const float* pValues); + + /** + \brief create parameter + \param pAgent agent this parameter belongs to + \param pName parameter name + \param pValues parameter values + */ + Parameter(Agent* pAgent, const std::string& pName, const std::initializer_list& pValues); + + /** + \brief create parameter + \param pAgent agent this parameter belongs to + \param pName parameter name + \param pValues parameter values + */ + Parameter(Agent* pAgent, const std::string& pName, const std::vector& pValues); + + /** + \brief create parameter + \param pAgent agent this parameter belongs to + \param pName parameter name + \param pValues parameter values + */ + Parameter(Agent* pAgent, const std::string& pName, const Eigen::VectorXf& pValues); + + /** + \brief copy constructor + \param pAgent agent this parameter belongs to + \param pParameter parameter to copy + */ + Parameter(Agent* pAgent, const Parameter& pParameter); + + /** + \brief destructor + */ + virtual ~Parameter(); + + /** + \brief return name + \return name + */ + const std::string& name() const; + + /** + \brief returns expected number of values + \return expected number of values + */ + virtual unsigned int dim() const; + + /** + \brief returns expected number of values + \return expected number of values + */ + virtual unsigned int count() const; + + /** + \brief set values + \param pValue single value + */ + virtual void set(float pValue); + + /** + \brief set values + \param pValues values + \exception Exception number of values cannot be changed + */ + virtual void set(const std::initializer_list& pValues) throw (Exception); + + /** + \brief set values + \param pValueCount number of values + \param pValues values + \exception Exception number of values cannot be changed + */ + virtual void set(unsigned int pValueCount, const float* pValues) throw (Exception); + + /** + \brief set values + \param pValues values + \exception Exception number of values cannot be changed + */ + virtual void set(const Eigen::VectorXf& pValues) throw (Exception); + + /** + \brief change values + \param pValue single value + */ + virtual void change(float pValue); + + /** + \brief change values + \param pValues values + \exception Exception number of values cannot be changed + */ + virtual void change(const std::initializer_list& pValues) throw (Exception); + + /** + \brief change values + \param pValueCount number of values + \param pValues values + \exception Exception number of values cannot be changed + */ + virtual void change(unsigned int pValueCount, float* pValues) throw (Exception); + + /** + \brief change values + \param pValues values + \exception FlockException number of values cannot be changed + */ + virtual void change(const Eigen::VectorXf& pValues) throw (Exception); + + /** + \brief randomize parameter value + \param pMinParameterValue minimum parameter value + \param pMaxParameterValue minimum parameter value + */ + virtual void randomize(float pMinParameterValue, float pMaxParameterValue); + + /** + \brief randomize parameter value + \param pMinParameterValues minimum parameter values + \param pMaxParameterValues minimum parameter values + \exception Exception number of values cannot be changed + */ + virtual void randomize(const std::initializer_list& pMinParameterValues, const std::initializer_list& pMaxParameterValues) throw (Exception); + + /** + \brief randomize parameter value + \param pMinParameterValues minimum parameter values + \param pMaxParameterValues minimum parameter values + \exception Exception number of values cannot be changed + */ + virtual void randomize(const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues) throw (Exception); + + /** + \brief return agent this parameter belongs to + */ + Agent* agent(); + + /** + \brief return parameter values + \return parameter values + */ + Eigen::VectorXf& values(); + + /** + \brief return parameter values + \return parameter values + */ + const Eigen::VectorXf& values() const; + + /** + \brief return parameter value + \param pIndex value index + \return parameter value + \exception Exception index out of bounds + */ + float& value(unsigned int pIndex = 0) throw (Exception); + + /** + \brief return parameter backup values + \return parameter backup values + */ + Eigen::VectorXf& backupValues(); + + /** + \brief return parameter backup value + \param pIndex backup value index + \return parameter backup value + \exception Exception index out of bounds + */ + float& backupValue(unsigned int pIndex = 0) throw (Exception); + + /** + \brief copy backup value into current value + */ + virtual void flush(); + + /** + \brief parameter = vector + \param pValues vector to copy values from + \return Vector + \exception Exception dimension mismatch + + copy vector values to backup values + */ + const Eigen::VectorXf& operator=( const Eigen::VectorXf& pValues) throw (Exception); + + /** + \brief parameter = vector + \param pValues vector to copy values from + \return Vector + \exception Exception dimension mismatch + + copy vector values to backup values + */ + const Eigen::VectorXf& operator=( const std::initializer_list& pValues) throw (Exception); + + /** + \brief parameter += vector + \param pValues vector to add values from + \return Vector + \exception Exception dimension mismatch + + add vector values to backup values + */ + const Eigen::VectorXf& operator+=( const Eigen::VectorXf& pValues) throw (Exception); + + /** + \brief set parameter value + \param pValue parameter value + + sets both value and backup value + */ + void setValue(float pValue); + + /** + \brief set parameter values + \param pValues parameter values + \exception Exception dimension mismatch + + sets both values and backup values + */ + void setValues(const Eigen::VectorXf& pValues) throw (Exception); + + /** + \brief set parameter values + \param pValues parameter values + \exception Exception dimension mismatch + + sets both values and backup values + */ + void setValues(const std::initializer_list& pValues) throw (Exception); + + /** + \brief set parameter values + \param pValueCount value count + \param pValues parameter values + \exception FlockException dimension mismatch + + sets both values and backup values + */ + void setValues(unsigned int pValueCount, float* pValues) throw (Exception); + + /** + \brief print parameter information + */ + virtual operator std::string() const; + + /** + \brief print parameter information + \param pPropagationLevel how far the propagation method proceeds through composite classes (-1: unlimited, 0: no proceeding, >0: limited proceeding) + */ + virtual std::string info(int pPropagationLevel = 0) const; + + /** + \brief retrieve textual parameter info + \param pOstream output text stream + \param pParameter parameter + */ + friend std::ostream& operator << ( std::ostream& pOstream, const Parameter& pParameter ) + { + pOstream << pParameter.info(); + + return pOstream; + }; + +protected: + /** + \brief default constructor + */ + Parameter(); + + /** + \brief parameter name + */ + std::string mName; + + /** + \brief agent this parameter belongs to + */ + Agent* mAgent; + + /** + \brief parameter values + */ + Eigen::VectorXf& mValues; + + /** + \brief parameter backup values + + parameter backup values are required for correctly updating parameter values + */ + Eigen::VectorXf mBackupValues; + + /** + \brief neighbor lists + */ + IndexMap mNeighborLists; + +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_parameter_combine_behavior.cpp b/src/dab_flock_parameter_combine_behavior.cpp new file mode 100644 index 0000000..16f1880 --- /dev/null +++ b/src/dab_flock_parameter_combine_behavior.cpp @@ -0,0 +1,81 @@ +/** \file dab_flock_parameter_combine_behavior.cpp + */ + +#include "dab_flock_parameter_combine_behavior.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +ParameterCombineBehavior::ParameterCombineBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "ParameterCombineBehavior"; +} + +ParameterCombineBehavior::ParameterCombineBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "ParameterCombineBehavior"; + + if( mInputParameters.size() < 2 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, at least " + std::to_string(2) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + unsigned int outputDim = 0; + for( unsigned int i=0; idim(); + if(mOutputParameters[0]->dim() != outputDim) throw Exception( "FLOCK ERROR: illegal output parameter dim, is " + std::to_string( mOutputParameters[0]->dim()) + " should be " + std::to_string(outputDim), __FILE__, __FUNCTION__, __LINE__ ); + + // output parameter + mOutputPar = mOutputParameters[0]; + + //std::cout << "scales " << mapValues << "\n"; +} + +ParameterCombineBehavior::~ParameterCombineBehavior() +{} + +Behavior* +ParameterCombineBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new ParameterCombineBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new ParameterCombineBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +ParameterCombineBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new ParameterCombineBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +ParameterCombineBehavior::act() +{ + Eigen::VectorXf& outputValues = mOutputPar->backupValues(); + + unsigned int inputParCount = mInputParameters.size(); + unsigned int inputParDim; + for(unsigned int outIndex=0, inputParNr=0; inputParNr < inputParCount; ++inputParNr) + { + Eigen::VectorXf& inputValues = mInputParameters[inputParNr]->values(); + inputParDim = inputValues.rows(); + + for(unsigned int inIndex=0; inIndex < inputParDim; ++inIndex, ++outIndex) + { + outputValues[outIndex] = inputValues[inIndex]; + } + } +} \ No newline at end of file diff --git a/src/dab_flock_parameter_combine_behavior.h b/src/dab_flock_parameter_combine_behavior.h new file mode 100644 index 0000000..07c9b47 --- /dev/null +++ b/src/dab_flock_parameter_combine_behavior.h @@ -0,0 +1,87 @@ +/** \file dab_flock_parameter_combine_behavior.h + * \class dab::flock::ParameterCombineBehavior combine several input parameters into single output parameter + * \brief combine several input parameters into single output parameter + * + * The behavior concatenations all input parameter values into a single output parameter.\n + * + * + * Input Parameters:\n + * type: InputParameter1 dim: nD neighbors: ignore\n + * type: InputParameter2 dim: nD neighbors: ignore\n + * etc\n + * \n + * Output Parameter:\n + * type: OutputParameter dim: the sum of the dimensions of all input parameters write: replace\n + * \n + * Created by Daniel Bisig on 2/7/08. + * Ported to OpenFrameworks by Daniel Bisig on 20/10/2017. + */ + +#ifndef _dab_flock_parameter_combine_behavior_h_ +#define _dab_flock_parameter_combine_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class ParameterCombineBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + ParameterCombineBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + ParameterCombineBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~ParameterCombineBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mOutputPar; /// \brief output parameter +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_parameter_list.cpp b/src/dab_flock_parameter_list.cpp new file mode 100644 index 0000000..5c1a012 --- /dev/null +++ b/src/dab_flock_parameter_list.cpp @@ -0,0 +1,185 @@ +/** \file dab_flock_parameter_list.cpp + */ + +#include "dab_space_neighbor_group_alg.h" +#include "dab_flock_parameter_list.h" +#include "dab_space_manager.h" + +using namespace dab; +using namespace dab::flock; + +const std::string ParameterList::sClassName = "ParameterList"; + +ParameterList::ParameterList() +{} + +ParameterList::~ParameterList() +{ + unsigned int parameterCount = mParameters.size(); + + for(unsigned int i=0; i= mParameters.size() ) throw Exception( "FLOCK ERROR: parameter index " + std::to_string(pIndex) + " out of bounds", __FILE__, __FUNCTION__, __LINE__ ); + + return mParameters[pIndex]; +} + +const Parameter* +ParameterList::parameter(unsigned int pIndex) const throw (Exception) +{ + if( pIndex >= mParameters.size() ) throw Exception( "FLOCK ERROR: parameter index " + std::to_string(pIndex) + " out of bounds", __FILE__, __FUNCTION__, __LINE__ ); + + return mParameters[pIndex]; +} + +Parameter* +ParameterList::parameter(const std::string& pName) throw (Exception) +{ + if( mParameters.contains(pName) == false ) throw Exception( "FLOCK ERROR: parameter name " + pName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + return mParameters[pName]; +} + +const Parameter* +ParameterList::parameter(const std::string& pName) const throw (Exception) +{ + if( mParameters.contains(pName) == false ) throw Exception( "FLOCK ERROR: parameter name " + pName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + return mParameters[pName]; +} + +void +ParameterList::addParameter(Parameter* pParameter) throw (Exception) +{ + if( mParameters.contains(pParameter->name()) == true ) throw Exception( "FLOCK ERROR: parameter name " + pParameter->name() + " already exists", __FILE__, __FUNCTION__, __LINE__ ); + + mParameters.add(pParameter->name(), pParameter); +} + +void +ParameterList::addParameter(Agent* pAgent, const std::string& pName, unsigned int pDim) throw (Exception) +{ + if( mParameters.contains(pName) == true ) throw Exception( "FLOCK ERROR: parameter name " + pName + " already exists", __FILE__, __FUNCTION__, __LINE__ ); + + Parameter* par = new Parameter(pAgent, pName, pDim); + mParameters.add(pName, par); +} + +void +ParameterList::removeParameter(const std::string& pName) throw (Exception) +{ + if( mParameters.contains(pName) == false ) throw Exception( "FLOCK ERROR: parameter name " + pName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + Parameter* par = mParameters[pName]; + mParameters.remove(pName); + + delete par; +} + +Eigen::VectorXf& +ParameterList::values(const std::string& pName) throw (Exception) +{ + if( mParameters.contains(pName) == false ) throw Exception( "FLOCK ERROR: parameter name " + pName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + return mParameters[pName]->values(); +} + +void +ParameterList::setValue(const std::string& pName, float pValue) throw (Exception) +{ + if( mParameters.contains(pName) == false ) throw Exception( "FLOCK ERROR: parameter name " + pName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + Parameter* par = mParameters[pName]; + par->setValue(pValue); +} + +void +ParameterList::setValues(const std::string& pName, const Eigen::VectorXf& pValues) throw (Exception) +{ + if( mParameters.contains(pName) == false ) throw Exception( "FLOCK ERROR: parameter name " + pName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + Parameter* par = mParameters[pName]; + + try + { + par->setValues(pValues); + } + catch (Exception& e) + { + throw; + } +} + +void +ParameterList::flush() +{ + unsigned int parameterCount = mParameters.size(); + + for(unsigned int i=0; iflush(); +} + + +ParameterList::operator std::string() const +{ + return info(0); +} + +std::string +ParameterList::info(int pPropagationLevel) const +{ + std::stringstream ss; + + unsigned int parameterCount = mParameters.size(); + + for(unsigned int i=0; iname() << " dim: " << par->dim() << " values: " << par->values().transpose() << "\n"; + } + else if(pPropagationLevel < 0 || pPropagationLevel >= 1) + { + ss << par->info(pPropagationLevel - 1) << "\n"; + } + } + + return ss.str(); +} \ No newline at end of file diff --git a/src/dab_flock_parameter_list.h b/src/dab_flock_parameter_list.h new file mode 100644 index 0000000..f515557 --- /dev/null +++ b/src/dab_flock_parameter_list.h @@ -0,0 +1,182 @@ +/** \file dab_flock_parameter_list.h + * \class dab::flock::ParameterList list of parameters + * \brief list of parameters + * + * + * Created by Daniel Bisig on 3/29/07. + * Ported to OpenFrameworks by Daniel Bisig on 3/08/17. + * Copyright 2006 Daniel Bisig All rights reserved. + */ + +#ifndef _dab_flock_parameter_list_h_ +#define _dab_flock_parameter_list_h_ + +#include +#include "dab_exception.h" +#include "dab_index_map.h" +#include "dab_flock_parameter.h" + +namespace dab +{ + +namespace flock +{ + +class ParameterList +{ +public: + /** + \brief default name + */ + static const std::string sClassName; + + /** + \brief default constructor + */ + ParameterList(); + + /** + \brief destructor + */ + ~ParameterList(); + + /** + \brief return number of parameters this list contains + \return number of parameters this list contains + */ + unsigned int parameterCount() const; + + /** + \brief checks if parameter list contains parameter + \param pName parameter name + \return true, if parameter name exists + */ + bool contains(const std::string& pName) const; + + /** + \brief return index of parameter + \param pName parameter name + \return index of parameter + \exception Exception parameter not found + */ + unsigned int parameterIndex(const std::string& pName) const throw (Exception); + + /** + \brief get parameter + \param pIndex parameter index + \return parameter + \exception Exception parameter not found + */ + Parameter* parameter(unsigned int pIndex) throw (Exception); + + /** + \brief get parameter + \param pIndex parameter index + \return parameter + \exception Exception parameter not found + */ + const Parameter* parameter(unsigned int pIndex) const throw (Exception); + + /** + \brief get parameter + \param pName parameter name + \return parameter + \exception Exception parameter not found + */ + Parameter* parameter(const std::string& pName) throw (Exception); + + /** + \brief get parameter + \param pName parameter name + \return parameter + \exception Exception parameter not found + */ + const Parameter* parameter(const std::string& pName) const throw (Exception); + + /** + \brief add parameter + \param pParameter parameter + \exception Exception parameter already exists + */ + void addParameter(Parameter* pParameter) throw (Exception); + + /** + \brief add parameter + \param pAgent agent this parameter list belongs to + \param pName parameter name + \param pDim dimension of parameter + \exception Exception parameter already exists + */ + void addParameter(Agent* pAgent, const std::string& pName, unsigned int pDim) throw (Exception); + + /** + \brief remove parameter + \param pName parameter name + \exception Exception parameter not found + */ + void removeParameter(const std::string& pName) throw (Exception); + + /** + \brief return parameter values + \param pName parameter name + \return parameter values + \exception FlockException parameter not found + */ + Eigen::VectorXf& values(const std::string& pName) throw (Exception); + + /** + \brief set parameter value + \param pName parameter name + \param pValue parameter value + \exception Exception parameter not found + */ + void setValue(const std::string& pName, float pValue) throw (Exception); + + /** + \brief set parameter values + \param pName parameter name + \param pValues parameter values + \exception Exception parameter not found or incompatible dimension + */ + void setValues(const std::string& pName, const Eigen::VectorXf& pValues) throw (Exception); + + /** + \brief update all parameters + + copies their backup values into their current values + */ + void flush(); + + /** + \brief print parameter list information + */ + virtual operator std::string() const; + + /** + \brief print parameter list information + \param pPropagationLevel how far the propagation method proceeds through composite classes (-1: unlimited, 0: no proceeding, >0: limited proceeding) + */ + virtual std::string info(int pPropagationLevel = 0) const; + + /** + \brief print parameter list information + */ + friend std::ostream& operator<< (std::ostream& pOstream, const ParameterList& pParameterList) + { + pOstream << pParameterList.info(); + + return pOstream; + }; + +protected: + /** + \brief parameters + */ + IndexMap mParameters; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_parameter_mag_behavior.cpp b/src/dab_flock_parameter_mag_behavior.cpp new file mode 100644 index 0000000..fa5d540 --- /dev/null +++ b/src/dab_flock_parameter_mag_behavior.cpp @@ -0,0 +1,73 @@ +/** \file dab_flock_parameter_mag_behavior.cpp + */ + +#include "dab_flock_parameter_mag_behavior.h" +#include "dab_flock_parameter.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +ParameterMagBehavior::ParameterMagBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "ParameterMagBehavior"; +} + +ParameterMagBehavior::ParameterMagBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "ParameterMagBehavior"; + + if(mInputParameters.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if(mOutputParameters.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if(mOutputParameters[0]->dim() != 1 ) throw Exception( "FLOCK ERROR: output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()) + " must be " + std::to_string(1), __FILE__, __FUNCTION__, __LINE__ ); + + // input parameters + mParameter = mInputParameters[0]; + + // output parameters + mMagParameter = mOutputParameters[0]; +} + +ParameterMagBehavior::~ParameterMagBehavior() +{} + +Behavior* +ParameterMagBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new ParameterMagBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new ParameterMagBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +ParameterMagBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new ParameterMagBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +ParameterMagBehavior::act() +{ + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& parValues = mParameter->values(); + float& parMag = mMagParameter->backupValue(); + + parMag = parValues.norm(); + +} \ No newline at end of file diff --git a/src/dab_flock_parameter_mag_behavior.h b/src/dab_flock_parameter_mag_behavior.h new file mode 100644 index 0000000..0e5be2e --- /dev/null +++ b/src/dab_flock_parameter_mag_behavior.h @@ -0,0 +1,88 @@ +/** \file dab_flock_parameter_mag_behavior.h + * \class dab::flock::ParameterMagBehavior stores magnitude of input parameter in output parameter + * \brief stores magnitude of input parameter in output parameter + * + * \n + * Input Parameter:\n + * type: any dim: nD neighbors: ignored\n + * \n + * Output Parameter:\n + * type: magnitude dim: 1D write: replace\n + * \n + * Internal Parameter:\n + * \n + * Created by Daniel Bisig on 09/11/09. + * Ported to OpenFrameworks by Daniel Bisig on 20/10/2017. + */ + +#ifndef _dab_flock_parameter_mag_behavior_h_ +#define _dab_flock_parameter_mag_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + + namespace flock + { + + class Agent; + + class ParameterMagBehavior : public Behavior + { + public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + ParameterMagBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + ParameterMagBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~ParameterMagBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + + protected: + Parameter* mParameter; ///\brief parameter (input) + Parameter* mMagParameter; ///\brief magnitude parameter (output) + }; + + }; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_parameter_map_behavior.cpp b/src/dab_flock_parameter_map_behavior.cpp new file mode 100644 index 0000000..4b2165e --- /dev/null +++ b/src/dab_flock_parameter_map_behavior.cpp @@ -0,0 +1,98 @@ +/** \file dab_flock_parameter_map_behavior.cpp + */ + +#include "dab_flock_parameter_map_behavior.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +ParameterMapBehavior::ParameterMapBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "ParameterMapBehavior"; +} + +ParameterMapBehavior::ParameterMapBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "ParameterMapBehavior"; + + if( mInputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mInputPar = mInputParameters[0]; + + // output parameter + mOutputPar = mOutputParameters[0]; + + // create internal parameters + mMapPar = createInternalParameter("map", std::vector( mInputPar->dim() * mOutputPar->dim(), 0.0 ) ); + Eigen::VectorXf& mapValues = mMapPar->values(); + + if(mInputPar->dim() < mOutputPar->dim()) for(unsigned int i=0; idim(); ++i ) mapValues[i * mInputPar->dim() + i] = 1.0; + else for(unsigned int i=0; idim(); ++i ) mapValues[i * mInputPar->dim() + i] = 1.0; + + //std::cout << "scales " << mapValues << "\n"; +} + +ParameterMapBehavior::~ParameterMapBehavior() +{} + +Behavior* +ParameterMapBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new ParameterMapBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new ParameterMapBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +ParameterMapBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new ParameterMapBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +ParameterMapBehavior::act() +{ + Eigen::VectorXf& inputValues = mInputPar->values(); + Eigen::VectorXf& outputValues = mOutputPar->backupValues(); + Eigen::VectorXf& mapValues = mMapPar->values(); + + unsigned int inputDim = inputValues.rows(); + unsigned int outputDim = outputValues.rows(); + + /* + for(unsigned int outIndex=0, scaleIndex=0; outIndex < outputDim; ++outIndex, scaleIndex += ) + { + if(std::isnan(mapValues[scaleIndex]) == false) outputValues[outIndex] = 0.0; + } + */ + + for(unsigned int scaleIndex=0, outIndex=0; outIndex < outputDim; ++outIndex) + { + for(unsigned int inIndex=0; inIndex < inputDim; ++scaleIndex, ++inIndex) + { + if(std::isnan(mapValues[scaleIndex]) == false) outputValues[outIndex] += inputValues[inIndex] * mapValues[scaleIndex]; + + //std::cout << "inI " << inIndex << " outI " << outIndex << " scaleI " << scaleIndex << " inV " << inputValues[inIndex] << " scaleV " << mapValues[scaleIndex] << " outV " << outputValues[outIndex] << "\n"; + } + } + + //std::cout << "--------------------\n"; +} \ No newline at end of file diff --git a/src/dab_flock_parameter_map_behavior.h b/src/dab_flock_parameter_map_behavior.h new file mode 100644 index 0000000..5b938b9 --- /dev/null +++ b/src/dab_flock_parameter_map_behavior.h @@ -0,0 +1,98 @@ +/** \file dab_flock_parameter_map_behavior.h + * \class dab::flock::ParameterMapBehavior map input parameter into output parameter + * \brief map input parameter into output parameter + * + * The Behavior maps input parameter into output parameter\n + * Any combination of input parameter components can be combined, scaled and copied into any combination of output parameter components\n + * This behavior can for instance be used to copy parameter values into a parameter of different dimension\n + * Or it can be used to scale the range of some parameter components\n + * The mapping relies on the values stored in the internal map parameter\n + * This parameter represents the mapping as follows:\n + * in0->out0, in0->out1,... in0->outY, in1->out0, in1->out1,... in1->outX,... inX->out0, inX->out1,... inX->outY\n + * For example to map a 3D parameter to a 2D parameter by combining the second and third component of the input into the second component of the output: + * 1, 0, 0, 0, 0.5, 0.5 + * \n + * Input Parameter:\n + * type: input dim: nD neighbors: ignored\n + * \n + * Output Parameter:\n + * type: output dim: mD write: replace\n + * \n + * Internal Parameter:\n + * name: xxx_map dim: m*nD defaultValue: 1.0 for all components that map input component into the same output component, 0.0 for all the others\n + * name: xxx_active dim: 1D defaultValue: 0.1\n + * \n + * Created by Daniel Bisig on 3/5/08. + * Ported to OpenFrameworks by Daniel Bisig on 20/10/2017. + */ + +#ifndef _dab_flock_parameter_map_behavior_h_ +#define _dab_flock_parameter_map_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class ParameterMapBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + ParameterMapBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + ParameterMapBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~ParameterMapBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mInputPar; /// \brief input parameter + Parameter* mOutputPar; /// \brief output parameter + Parameter* mMapPar; /// \brief map parameter (internal) +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_parameter_print_behavior.cpp b/src/dab_flock_parameter_print_behavior.cpp new file mode 100644 index 0000000..ee96bfb --- /dev/null +++ b/src/dab_flock_parameter_print_behavior.cpp @@ -0,0 +1,64 @@ +/** \file dab_flock_parameter_print_behavior.cpp + */ + +#include "dab_flock_parameter_print_behavior.h" +#include "dab_flock_parameter.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +ParameterPrintBehavior::ParameterPrintBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "ParameterPrintBehavior"; +} + +ParameterPrintBehavior::ParameterPrintBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "ParameterPrintBehavior"; + + if(mInputParameters.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameters + mParameter = mInputParameters[0]; +} + +ParameterPrintBehavior::~ParameterPrintBehavior() +{} + +Behavior* +ParameterPrintBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new ParameterPrintBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new ParameterPrintBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +ParameterPrintBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new ParameterPrintBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +ParameterPrintBehavior::act() +{ + if(mActivePar->value() <= 0.0) return; + + std::cout << "agent " << mAgent->name()<< " par " << mParameter->name() << " values " << mParameter->values() << " bValues " << mParameter->backupValues() << "\n"; +} \ No newline at end of file diff --git a/src/dab_flock_parameter_print_behavior.h b/src/dab_flock_parameter_print_behavior.h new file mode 100644 index 0000000..0837311 --- /dev/null +++ b/src/dab_flock_parameter_print_behavior.h @@ -0,0 +1,90 @@ +/** \file dab_flock_parameter_print_behavior.h + * \class dab:flock::ParameterPrintBehavior print parameter to console + * \brief print parameter to console + * + * The Behavior prints parameter to console\n + * It prints the agent name and the parameter's value and backup value\n + * Might come in handy for debugging purposes\n + * \n + * Input Parameter:\n + * type: any dim: nD neighbors: ignored\n + * \n + * Output Parameter:\n + * \n + * Internal Parameter:\n + * name: xxx_active dim: 1D defaultValue: 0.1\n + * \n + * Created by Daniel Bisig on 05/12/08. + * Ported to OpenFrameworks by Daniel Bisig on 01/10/2017. + */ + +#ifndef _dab_flock_parameter_print_behavior_h_ +#define _dab_flock_parameter_print_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class Agent; + +class ParameterPrintBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + ParameterPrintBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + ParameterPrintBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~ParameterPrintBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mParameter; ///\brief observed parameter +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_parameter_scale_behavior.cpp b/src/dab_flock_parameter_scale_behavior.cpp new file mode 100644 index 0000000..5011a77 --- /dev/null +++ b/src/dab_flock_parameter_scale_behavior.cpp @@ -0,0 +1,94 @@ +/** \file dab_flock_parameter_scale_behavior.cpp + */ + +#include "dab_flock_parameter_scale_behavior.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +ParameterScaleBehavior::ParameterScaleBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "ParameterScaleBehavior"; +} + +ParameterScaleBehavior::ParameterScaleBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "ParameterScaleBehavior"; + + if( mInputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mInputPar = mInputParameters[0]; + + // output parameter + mOutputPar = mOutputParameters[0]; + + // create internal parameters + mMinInPar = createInternalParameter("minInput", std::vector( mInputPar->dim(), 0.0 ) ); + mMaxInPar = createInternalParameter("maxInput", std::vector( mInputPar->dim(), 1.0 ) ); + mMinOutPar = createInternalParameter("minOutput", std::vector( mInputPar->dim(), 0.0 ) ); + mMaxOutPar = createInternalParameter("maxOutput", std::vector( mInputPar->dim(), 1.0 ) ); +} + +ParameterScaleBehavior::~ParameterScaleBehavior() +{} + +Behavior* +ParameterScaleBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new ParameterScaleBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new ParameterScaleBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +ParameterScaleBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new ParameterScaleBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +ParameterScaleBehavior::act() +{ + //std::cout << "ParameterScaleBehavior " << mName.toStdString() << " act()\n"; + + Eigen::VectorXf& inputValues = mInputPar->values(); + Eigen::VectorXf& outputValues = mOutputPar->backupValues(); + Eigen::VectorXf& minInValues = mMinInPar->values(); + Eigen::VectorXf& maxInValues = mMaxInPar->values(); + Eigen::VectorXf& minOutValues = mMinOutPar->values(); + Eigen::VectorXf& maxOutValues = mMaxOutPar->values(); + + unsigned int parDim = inputValues.rows(); + float parValue; + + for(unsigned int d=0; d 1.0) parValue = 1.0; + + outputValues[d] = minOutValues[d] + parValue * (maxOutValues[d] - minOutValues[d]); + } + + //std::cout << "in " << inputValues << " out " << outputValues << "\n"; +} \ No newline at end of file diff --git a/src/dab_flock_parameter_scale_behavior.h b/src/dab_flock_parameter_scale_behavior.h new file mode 100644 index 0000000..e5b6f0f --- /dev/null +++ b/src/dab_flock_parameter_scale_behavior.h @@ -0,0 +1,97 @@ +/** \file dab_flock_parameter_scale_behavior.h + * \class dab::flock::ParameterScaleBehavior scale parameter values + * \brief scale parameter values + * + * The Behavior scales parameter values\n + * It copies the scaled values into an output parameter\n + * \n + * Input Parameter:\n + * type: input dim: nD neighbors: ignored\n + * \n + * Output Parameter:\n + * type: output dim: nD write: replace\n + * \n + * Internal Parameter:\n + * name: xxx_minInput dim: nD defaultValue: 0.0\n + * name: xxx_maxInput dim: nD defaultValue: 1.0\n + * name: xxx_minOutput dim: nD defaultValue: 0.0\n + * name: xxx_maxOutput dim: nD defaultValue: 1.0\n + * name: xxx_active dim: 1D defaultValue: 0.1\n + * \n + * Created by Daniel Bisig on 4/5/08. + * Ported to OpenFrameworks by Daniel Bisig on 20/10/2017. + */ + +#ifndef _dab_flock_parameter_scale_behavior_h_ +#define _dab_flock_parameter_scale_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class ParameterScaleBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + ParameterScaleBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + ParameterScaleBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~ParameterScaleBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mInputPar; /// \brief input parameter + Parameter* mOutputPar; /// \brief output parameter + Parameter* mMinInPar; /// \brief minimum input value parameter (internal) + Parameter* mMaxInPar; /// \brief maximum input value parameter (internal) + Parameter* mMinOutPar; /// \brief minimum output value parameter (internal) + Parameter* mMaxOutPar; /// \brief maximum output value parameter (internal) +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_parameter_threshold_to_event_behavior.cpp b/src/dab_flock_parameter_threshold_to_event_behavior.cpp new file mode 100644 index 0000000..f20d3fc --- /dev/null +++ b/src/dab_flock_parameter_threshold_to_event_behavior.cpp @@ -0,0 +1,161 @@ +/** \file dab_flock_parameter_threshold_to_event_behavior.cpp +*/ + +#include "dab_flock_parameter_threshold_to_event_behavior.h" +#include "dab_flock_parameter.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +ParameterThresholdToEventBehavior::ParameterThresholdToEventBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) + : Behavior(pInputParameterString, pOutputParameterString) + , mInitialized(false) +{ + mClassName = "ParameterThresholdToEventBehavior"; +} + +ParameterThresholdToEventBehavior::ParameterThresholdToEventBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) + : Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) + , mInitialized(false) +{ + mClassName = "ParameterThresholdToEventBehavior"; + + if (mInputParameters.size() < 2) throw Exception("FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(2) + " needed", __FILE__, __FUNCTION__, __LINE__); + if (mOutputParameters.size() < 1) throw Exception("FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__); + if (mInputParameters[1]->dim() != mOutputParameters[0]->dim()) throw Exception("FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__); + + // input parameters + mObservePar = mInputParameters[0]; + mSendPar = mInputParameters[1]; + + // output parameter + mTargetPar = mOutputParameters[0]; + + // create internal parameters + mLowerThresholdPar = createInternalParameter("lowerThreshold", std::vector(mInputParameters[0]->dim(), 0.0)); + mUpperThresholdPar = createInternalParameter("upperThreshold", std::vector(mInputParameters[0]->dim(), 1.0)); + mEventTriggerCriteriaPar = createInternalParameter("eventTriggerCriteria", { 1.0 }); + mThresholdComparisonModePar = createInternalParameter("thresholdComparisonCriteria", { 1.0 }); + mEventTriggerFrequencyPar = createInternalParameter("eventTriggerFrequency", { 1.0 }); + + // other member variables + mThresholdExceededFlag = false; + mInitialized = false; +} + +ParameterThresholdToEventBehavior::~ParameterThresholdToEventBehavior() +{} + +Behavior* +ParameterThresholdToEventBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if (pAgent != NULL) return new ParameterThresholdToEventBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new ParameterThresholdToEventBehavior(mInputParameterString, mOutputParameterString); + } + catch (Exception& e) + { + throw; + } +} + +Behavior* +ParameterThresholdToEventBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new ParameterThresholdToEventBehavior(pInputParameterString, pOutputParameterString); + } + catch (Exception& e) + { + throw; + } +} + +void +ParameterThresholdToEventBehavior::init() +{ + mEventTriggerCriteria = static_cast(static_cast(mEventTriggerCriteriaPar->value())); + mThresholdComparisonMode = static_cast(static_cast(mThresholdComparisonModePar->value())); + mEventTriggerFrequency = static_cast(static_cast(mEventTriggerFrequencyPar->value())); + + mInitialized = true; +} + +void +ParameterThresholdToEventBehavior::act() +{ + if (mInitialized == false) init(); + if (mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& observeValues = mObservePar->values(); + Eigen::VectorXf& sendValues = mSendPar->values(); + Eigen::VectorXf& targetValues = mTargetPar->backupValues(); + Eigen::VectorXf& lowerThresholdValues = mLowerThresholdPar->values(); + Eigen::VectorXf& upperThresholdValues = mUpperThresholdPar->values(); + EventTriggerCriteria& eventTriggerCriteria = mEventTriggerCriteria; + ThresholdComparisonMode& thresholdComparisonMode = mThresholdComparisonMode; + EventTriggerFrequency& eventTriggerFrequency = mEventTriggerFrequency; + bool& thresholdExceededFlag = mThresholdExceededFlag; + bool tmpExceeededFlag = false; + unsigned int dim = observeValues.rows(); + unsigned int d; + + // test whether parameter values exceed threshold + if (eventTriggerCriteria == EnterThresholdRange) + { + if (thresholdComparisonMode == SignedComponentComparisonMode) + { + for (d = 0; d upperThresholdValues[d]); ++d) {} + if (d < dim) tmpExceeededFlag = true; + } + else if (thresholdComparisonMode == UnsignedComponentComparisonMode) + { + for (d = 0; d fabs(upperThresholdValues[d])); ++d) {} + if (d < dim) tmpExceeededFlag = true; + } + else if (thresholdComparisonMode == LengthComparisonMode) + { + if (observeValues.squaredNorm() >= lowerThresholdValues.squaredNorm() && observeValues.squaredNorm() <= upperThresholdValues.squaredNorm()) tmpExceeededFlag = true; + } + + } + else if (eventTriggerCriteria == LeaveThresholdRange) + { + if (thresholdComparisonMode == SignedComponentComparisonMode) + { + for (d = 0; d lowerThresholdValues[d] || observeValues[d] < upperThresholdValues[d]); ++d) {} + if (d < dim) tmpExceeededFlag = true; + } + else if (thresholdComparisonMode == UnsignedComponentComparisonMode) + { + for (d = 0; d fabs(lowerThresholdValues[d]) || fabs(observeValues[d]) < fabs(upperThresholdValues[d])); ++d) {} + if (d < dim) tmpExceeededFlag = true; + } + else if (thresholdComparisonMode == LengthComparisonMode) + { + if (observeValues.squaredNorm() <= lowerThresholdValues.squaredNorm() || observeValues.squaredNorm() >= upperThresholdValues.squaredNorm()) tmpExceeededFlag = true; + } + } + + //std::cout << "vel " << observeValues.lengthSquared() << " low thresh " << lowerThresholdValues.lengthSquared() << " high thresh " << upperThresholdValues.lengthSquared() << " tmpExceeededFlag " << tmpExceeededFlag << "\n"; + + + // decide whether to create event + if (tmpExceeededFlag == true) + { + if (thresholdExceededFlag == false || eventTriggerFrequency == ContinuousTrigger) + { + + //Simulation::get().event().addEvent( new SetParameterEvent( 0.0, mTargetPar->agent()->name(), "alignment_amount", sendValues ) ); + //mTargetPar->schedule(0.0, sendValues ); + // TODO: broken for the moment + thresholdExceededFlag = true; + + //std::cout << "observeValues " << observeValues << " lowT " << lowerThresholdValues << " upT " << upperThresholdValues << " sendValues " << sendValues << "\n"; + } + } + else thresholdExceededFlag = false; +} \ No newline at end of file diff --git a/src/dab_flock_parameter_threshold_to_event_behavior.h b/src/dab_flock_parameter_threshold_to_event_behavior.h new file mode 100644 index 0000000..16f0db4 --- /dev/null +++ b/src/dab_flock_parameter_threshold_to_event_behavior.h @@ -0,0 +1,152 @@ +/** \file dab_flock_parameter_threshold_to_event_behavior.h +* \class dab::flock::ParameterThresholdToEventBehavior create events depending on whether the values an observed parameter enter or leave a value range +* \brief create events depending on whether the values an observed parameter enter or leave a value range +* +* The Behavior creates events depending on whether the values an observed parameter enter or leave a value range\n +* The value range is defined by the two internal parameters : lowerThreshold & upperThreshold +* Depending on the value of the internal parameter thresholdComparisonCriteria, an event is generated when the observed parameters values enter or leave the threshold range\n +* EnterThresholdRange : event is created when observed parameter is within threshold range +* LeaveThresholdRange : event is created when observed parameter is outside threshold range +* Depending on the value of the internal parameter thresholdComparisonCriteria, the observed parameters values are compared differently against the treshold range +* SignedComponentComparisonMode compare individual signed parameter components +* UnsignedComponentComparisonMode compare individual unsigned parameter components +* LengthComparisonMode compare length of parameter +* Depending on the value of the internal parameter eventTriggerFrequency events are either always created or only once +* SingleTrigger event is triggered only in the moment were a parameter that didn't fulfill the event criteria fulfills it now +* ContinuousTrigger event is triggered always when a parameter fulfills event criteria +* The value of the event is copied from the specified send input parameter\n +* The event is sent to the specified target parameter\n +* \n +* Input Parameter:\n +* type: observed dim: nD neighbors: ignored\n +* type: send dim: nD neighbors: ignored\n +* \n +* Output Parameter:\n +* type: target dim: nD write: replace via event\n +* \n +* Internal Parameter:\n +* name: xxx_lowerThreshold dim: nD defaultValue: 0.0\n +* name: xxx_upperThreshold dim: nD defaultValue: 1.0\n +* name: xxx_eventTriggerCriteria dim: 1D defaultValue: LeaveThresholdRange\n +* name: xxx_thresholdComparisonCriteria dim: 1D defaultValue: UnsignedComponentComparisonMode\n +* name: xxx_eventTriggerFrequency dim: 1D defaultValue: ContinuousTrigger\n +* name: xxx_active dim: 1D defaultValue: 0.1\n +* \n +* Created by Daniel Bisig on 05/12/08. +* Ported to OpenFrameworks by Daniel Bisig on 20/10/2017. +*/ + +#ifndef _dab_flock_parameter_threshold_to_event_behavior_h_ +#define _dab_flock_parameter_threshold_to_event_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + + namespace flock + { + + class Agent; + + class ParameterThresholdToEventBehavior : public Behavior + { + public: + /** + \brief criteria for triggering event + */ + enum EventTriggerCriteria + { + EnterThresholdRange, ///\brief value enter treshold range + LeaveThresholdRange ///\brief value leaves threshold range + }; + + /** + \brief threshold comparison Mode + */ + enum ThresholdComparisonMode + { + SignedComponentComparisonMode, ///\brief compare signed component values of parameter and threshold + UnsignedComponentComparisonMode, ///\brief compare unsigned component values of parameter and threshold + LengthComparisonMode ///\brief compare length of parameter and threshold + }; + + /** + \brief event trigger frequency + */ + enum EventTriggerFrequency + { + SingleTrigger, ///\brief event is triggered only in the moment were a parameter that didn't exceed the treshold beforehand exceed it now + ContinuousTrigger///\brief event is triggered always when a parameter exceeds the treshold + }; + + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + ParameterThresholdToEventBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + ParameterThresholdToEventBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~ParameterThresholdToEventBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + + protected: + void init(); + + Parameter* mObservePar; ///\brief observed parameter + Parameter* mSendPar; ///\brief parameter that is sent + Parameter* mTargetPar; ///\brief event parameter (the parameter the event is being sent to) + Parameter* mLowerThresholdPar; ///\brief threshold for observed parameter (whenever it exceeds that, event is sent) + Parameter* mUpperThresholdPar; ///\brief threshold for observed parameter (whenever it exceeds that, event is sent) + Parameter* mEventTriggerCriteriaPar; ///\brief event trigger criteria + Parameter* mThresholdComparisonModePar; ///\brief threshold comparison mode + Parameter* mEventTriggerFrequencyPar; ///\brief event trigger frequency + + bool mInitialized; + + EventTriggerCriteria mEventTriggerCriteria; ///\brief event trigger criteria + ThresholdComparisonMode mThresholdComparisonMode; ///\brief threshold comparison mode + EventTriggerFrequency mEventTriggerFrequency; ///\brief event trigger frequency + bool mThresholdExceededFlag; ///\brief flag whether threshold has previously been exceeded or not + }; + + }; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_randomize_behavior.cpp b/src/dab_flock_randomize_behavior.cpp new file mode 100644 index 0000000..37bb803 --- /dev/null +++ b/src/dab_flock_randomize_behavior.cpp @@ -0,0 +1,80 @@ +/** \file dab_flock_randomize_behavior.cpp + */ + +#include "dab_flock_randomize_behavior.h" +#include "dab_flock_agent.h" +#include "dab_math.h" + +using namespace dab; +using namespace dab::flock; + +RandomizeBehavior::RandomizeBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "RandomizeBehavior"; +} + +RandomizeBehavior::RandomizeBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "RandomizeBehavior"; + + if(mOutputParameters.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // output parameter + mRandomizePar = mOutputParameters[0]; + + // create internal parameters + mRangePar = createInternalParameter("range", mOutputParameters[0]->dim(), 1.0); +} + +RandomizeBehavior::~RandomizeBehavior() +{} + +Behavior* +RandomizeBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new RandomizeBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new RandomizeBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +RandomizeBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new RandomizeBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +RandomizeBehavior::act() +{ + //std::cout << "RandomizeBehavior begin: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& output = mRandomizePar->backupValues(); + Eigen::VectorXf& range = mRangePar->values(); + + math::Math<>& math = math::Math<>::get(); + unsigned int dim = output.rows(); + + for(unsigned int i=0; ivalues() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + //assert(std::isnan(output[0]) == false && "isNan"); +} \ No newline at end of file diff --git a/src/dab_flock_randomize_behavior.h b/src/dab_flock_randomize_behavior.h new file mode 100644 index 0000000..91d5b04 --- /dev/null +++ b/src/dab_flock_randomize_behavior.h @@ -0,0 +1,87 @@ +/** \file dab_flock_randomize_behavior.h + * \class dab::flock::RandomizeBehavior randomize parameter value + * \brief randomize parameter value + * + * The Behavior randomizes parameter value\n + * \n + * Input Parameter:\n + * \n + * Output Parameter:\n + * type: output dim: nD write: add\n + * \n + * Internal Parameter:\n + * name: xxx_range dim: nD defaultValue: 1.0\n + * name: xxx_active dim: 1D defaultValue: 0.1\n + * \n + * Created by Daniel Bisig on 4/16/07. + * Ported to OpenFrameworks by Daniel Bisig on 01/10/2017. + */ + +#ifndef _dab_flock_randomize_behavior_h_ +#define _dab_flock_randomize_behavior_h_ + +#include "dab_flock_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class RandomizeBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + RandomizeBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + RandomizeBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~RandomizeBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior action + */ + virtual void act(); + +protected: + Parameter* mRandomizePar; /// \brief randomize parameter (output) + Parameter* mRangePar; /// \brief randomize range parameter (internal) +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_remove_agents_event.cpp b/src/dab_flock_remove_agents_event.cpp new file mode 100644 index 0000000..63c7bb1 --- /dev/null +++ b/src/dab_flock_remove_agents_event.cpp @@ -0,0 +1,101 @@ +/** \file dab_flock_remove_agents_event.cpp + */ + +#include "dab_flock_remove_agents_event.h" + +using namespace dab; +using namespace dab::flock; + +RemoveAgentsEvent::RemoveAgentsEvent(const std::string& pSwarmName) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mStartAgentIndex( -1 ) +, mAgentCount(-1) +{} + +RemoveAgentsEvent::RemoveAgentsEvent(const std::string& pSwarmName, int pAgentCount) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mStartAgentIndex( -1 ) +, mAgentCount(pAgentCount) +{} + +RemoveAgentsEvent::RemoveAgentsEvent(const std::string& pSwarmName, int pStartAgentIndex, int pEndAgentIndex) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mStartAgentIndex( pStartAgentIndex ) +, mAgentCount( pEndAgentIndex - pStartAgentIndex ) +{} + +RemoveAgentsEvent::RemoveAgentsEvent(double pTime, const std::string& pSwarmName) +: event::Event(pTime, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mStartAgentIndex( -1 ) +, mAgentCount(-1) +{} + +RemoveAgentsEvent::RemoveAgentsEvent(double pTime, const std::string& pSwarmName, int pAgentCount) +: event::Event(pTime, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mStartAgentIndex( -1 ) +, mAgentCount(pAgentCount) +{} + +RemoveAgentsEvent::RemoveAgentsEvent(double pTime, const std::string& pSwarmName, int pStartAgentIndex, int pEndAgentIndex ) +: event::Event(pTime, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mStartAgentIndex( pStartAgentIndex ) +, mAgentCount( pEndAgentIndex - pStartAgentIndex ) +{} + +RemoveAgentsEvent::RemoveAgentsEvent( const RemoveAgentsEvent& pEvent ) +: event::Event( pEvent ) +, mSwarmName( pEvent.mSwarmName ) +, mStartAgentIndex( pEvent.mStartAgentIndex ) +, mAgentCount( pEvent.mAgentCount ) +{} + +RemoveAgentsEvent::RemoveAgentsEvent( double pTime, const RemoveAgentsEvent& pEvent ) +: event::Event( pTime, pEvent ) +, mSwarmName( pEvent.mSwarmName ) +, mStartAgentIndex( pEvent.mStartAgentIndex ) +, mAgentCount( pEvent.mAgentCount ) +{} + +RemoveAgentsEvent::~RemoveAgentsEvent() +{} + +event::Event* +RemoveAgentsEvent::copy() const +{ + return new RemoveAgentsEvent( *this ); +} + +event::Event* +RemoveAgentsEvent::copy( double pTime ) const +{ + return new RemoveAgentsEvent( pTime, *this ); +} + +void +RemoveAgentsEvent::execute() throw (Exception) +{ + mStarted = true; + mFinished = false; + + try + { + Swarm* swarm = Simulation::get().swarm(mSwarmName); + + if( mAgentCount < 0 ) swarm->removeAgents(); + if( mStartAgentIndex >= 0 ) swarm->removeAgents(mStartAgentIndex, mAgentCount); + else swarm->removeAgents(mAgentCount); + } + catch(Exception& e) + { + Simulation::get().exceptionReport( e ); + } + + mStarted = false; + mFinished = true; +} \ No newline at end of file diff --git a/src/dab_flock_remove_agents_event.h b/src/dab_flock_remove_agents_event.h new file mode 100644 index 0000000..b6d5152 --- /dev/null +++ b/src/dab_flock_remove_agents_event.h @@ -0,0 +1,47 @@ +/** \file dab_flock_remove_agents_event.h + * + * Created by Daniel Bisig on 1/28/09. + * Ported to OpenFraemworks by Daniel Bisig on 13/10/2017. + */ + +#ifndef _dab_flock_remove_agents_event_h_ +#define _dab_flock_remove_agents_event_h_ + +#include "dab_flock_simulation.h" +#include "dab_flock_swarm.h" +#include "dab_event.h" + +namespace dab +{ + +namespace flock +{ + +class RemoveAgentsEvent : public event::Event +{ +public: + RemoveAgentsEvent( const std::string& pSwarmName ); + RemoveAgentsEvent( const std::string& pSwarmName, int pAgentCount ); + RemoveAgentsEvent( const std::string& pSwarmName, int pStartAgentIndex, int pEndAgentIndex ); + RemoveAgentsEvent( double pTime, const std::string& pSwarmName ); + RemoveAgentsEvent( double pTime, const std::string& pSwarmName, int pAgentCount ); + RemoveAgentsEvent( double pTime, const std::string& pSwarmName, int pStartAgentIndex, int pEndAgentIndex ); + RemoveAgentsEvent( const RemoveAgentsEvent& pEvent ); + RemoveAgentsEvent( double pTime, const RemoveAgentsEvent& pEvent ); + virtual ~RemoveAgentsEvent(); + + event::Event* copy() const; + event::Event* copy( double pTime ) const; + void execute() throw (Exception); + +protected: + std::string mSwarmName; + int mStartAgentIndex; + int mAgentCount; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_reset_behavior.cpp b/src/dab_flock_reset_behavior.cpp new file mode 100644 index 0000000..e0560aa --- /dev/null +++ b/src/dab_flock_reset_behavior.cpp @@ -0,0 +1,85 @@ +/** \file dab_flock_reset_behavior.cpp + */ + +#include "dab_flock_reset_behavior.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +ResetBehavior::ResetBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "ResetBehavior"; +} + +ResetBehavior::ResetBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "ResetBehavior"; + + if(mOutputParameters.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // output parameter + mResetPar = mOutputParameters[0]; + + // create internal parameters + mResetValuePar = createInternalParameter("resetValue", mResetPar->dim(), 0.0); + mResetAmountPar = createInternalParameter("resetAmount", mResetPar->dim(), 1.0); + + // other stuff + int dim = mResetPar->dim(); + + mUnitVector.resize(dim, 1); + mUnitVector.setConstant(1.0); +} + +ResetBehavior::~ResetBehavior() +{} + +Behavior* +ResetBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new ResetBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new ResetBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +ResetBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new ResetBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +ResetBehavior::act() +{ + //std::cout << "ResetBehavior begin: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& origValue = mResetPar->values(); + Eigen::VectorXf& newValue = mResetPar->backupValues(); + Eigen::VectorXf& resetValue = mResetValuePar->values(); + Eigen::VectorXf& resetAmount = mResetAmountPar->values(); + Eigen::VectorXf& unitVector = mUnitVector; + + newValue = resetAmount.cwiseProduct(resetValue) + origValue.cwiseProduct(resetAmount - unitVector); + + //std::cout << "par " << mResetPar->name().toStdString() << " amt " << resetAmount << " orig " << origValue << " new " << newValue << "\n"; + + //std::cout << "ResetBehavior end: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + //assert(std::isnan(valueOut[0]) == false && "isNan"); +} \ No newline at end of file diff --git a/src/dab_flock_reset_behavior.h b/src/dab_flock_reset_behavior.h new file mode 100644 index 0000000..440bcd7 --- /dev/null +++ b/src/dab_flock_reset_behavior.h @@ -0,0 +1,92 @@ +/** \file dab_flock_reset_behavior.h + * \class dab::flock::ResetBehavior reset parameter value + * \brief reset parameter value + * + * The Behavior randomizes parameter value\n + * \n + * Input Parameter:\n + * \n + * Output Parameter:\n + * type: output dim: nD write: replace\n + * \n + * Internal Parameter:\n + * name: xxx_resetValue dim: nD defaultValue: 0.0\n + * name: xxx_resetAmount dim: nD defaultValue: 1.0\n + * name: xxx_active dim: 1D defaultValue: 0.1\n + * \n + * Created by Daniel Bisig on 4/16/07. + * Ported to OpenFrameworks by Daniel Bisig on 01/10/2017. + */ + +#ifndef _dab_flock_reset_behavior_h_ +#define _dab_flock_reset_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class ResetBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + ResetBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + ResetBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~ResetBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mResetPar; /// \brief reset parameter (output) + Parameter* mResetValuePar; /// \brief reset value parameter (internal) + Parameter* mResetAmountPar; /// \brief reset amount parameters (internal) + + Eigen::VectorXf mUnitVector; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_restore_simulation_event.cpp b/src/dab_flock_restore_simulation_event.cpp new file mode 100644 index 0000000..d6a023b --- /dev/null +++ b/src/dab_flock_restore_simulation_event.cpp @@ -0,0 +1,68 @@ +/** \dab_flock_restore_simulation_event.cpp + */ + +#include "dab_flock_restore_simulation_event.h" +#include "dab_flock_simulation.h" + +using namespace dab; +using namespace dab::flock; + +RestoreSimulationEvent::RestoreSimulationEvent( const std::string& pFileName, SerializeTools::SerializeMode pMode ) +: event::Event(0.0, -1.0, event::RelativeTime) +, mFileName( pFileName ) +, mMode( pMode ) +{ + //std::cout << "RestoreSimulationEvent::RestoreSimulationEvent() \n"; +} + +RestoreSimulationEvent::RestoreSimulationEvent(double pTime, const std::string& pFileName, SerializeTools::SerializeMode pMode ) +: event::Event(pTime, -1.0, event::RelativeTime) +, mFileName( pFileName ) +, mMode( pMode ) +{} + +RestoreSimulationEvent::RestoreSimulationEvent( const RestoreSimulationEvent& pEvent ) +: event::Event( pEvent ) +, mFileName( pEvent.mFileName ) +, mMode( pEvent.mMode ) +{} + +RestoreSimulationEvent::RestoreSimulationEvent( double pTime, const RestoreSimulationEvent& pEvent ) +: event::Event( pTime, pEvent ) +, mFileName( pEvent.mFileName ) +, mMode( pEvent.mMode ) +{} + +RestoreSimulationEvent::~RestoreSimulationEvent() +{} + +event::Event* +RestoreSimulationEvent::copy() const +{ + return new RestoreSimulationEvent( *this ); +} + +event::Event* +RestoreSimulationEvent::copy( double pTime ) const +{ + return new RestoreSimulationEvent( pTime, *this ); +} + +void +RestoreSimulationEvent::execute() throw (Exception) +{ + mStarted = true; + mFinished = false; + + try + { + SerializeTools::get().restore( mFileName, mMode ); + } + catch( Exception& e ) + { + Simulation::get().exceptionReport( e ); + } + + mStarted = false; + mFinished = true; +} \ No newline at end of file diff --git a/src/dab_flock_restore_simulation_event.h b/src/dab_flock_restore_simulation_event.h new file mode 100644 index 0000000..ef622a3 --- /dev/null +++ b/src/dab_flock_restore_simulation_event.h @@ -0,0 +1,42 @@ +/** dab_flock_restore_simulation_event.h + * + * Created by Daniel Bisig on 5/20/10. + * Ported to OpenFrameworks by Daniel Bisig on 02/11/2017. + * + */ + +#ifndef _dab_flock_restore_simulation_event_h_ +#define _dab_flock_restore_simulation_event_h_ + +#include "dab_flock_serialize.h" +#include "dab_event.h" + +namespace dab +{ + +namespace flock +{ + +class RestoreSimulationEvent : public event::Event +{ +public: + RestoreSimulationEvent( const std::string& pFileName, SerializeTools::SerializeMode pMode = SerializeTools::AllMode ); + RestoreSimulationEvent( double pTime, const std::string& pFileName, SerializeTools::SerializeMode pMode = SerializeTools::AllMode ); + RestoreSimulationEvent( const RestoreSimulationEvent& pEvent ); + RestoreSimulationEvent( double pTime, const RestoreSimulationEvent& pEvent ); + virtual ~RestoreSimulationEvent(); + + event::Event* copy() const; + event::Event* copy( double pTime ) const; + void execute() throw (Exception); + +protected: + std::string mFileName; + SerializeTools::SerializeMode mMode; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_save_simulation_event.cpp b/src/dab_flock_save_simulation_event.cpp new file mode 100644 index 0000000..4743562 --- /dev/null +++ b/src/dab_flock_save_simulation_event.cpp @@ -0,0 +1,70 @@ +/** \dab_flock_save_simulation_event.cpp + */ + +#include "dab_flock_save_simulation_event.h" +#include "dab_flock_simulation.h" + +using namespace dab; +using namespace dab::flock; + +SaveSimulationEvent::SaveSimulationEvent( const std::string& pFileName, SerializeTools::SerializeMode pMode ) +: event::Event(0.0, -1.0, event::RelativeTime) +, mFileName( pFileName ) +, mMode( pMode ) +{} + +SaveSimulationEvent::SaveSimulationEvent(double pTime, const std::string& pFileName, SerializeTools::SerializeMode pMode ) +: event::Event(pTime, -1.0, event::RelativeTime) +, mFileName( pFileName ) +, mMode( pMode ) +{} + +SaveSimulationEvent::SaveSimulationEvent( const SaveSimulationEvent& pEvent ) +: event::Event( pEvent ) +, mFileName( pEvent.mFileName ) +, mMode( pEvent.mMode ) +{} + +SaveSimulationEvent::SaveSimulationEvent( double pTime, const SaveSimulationEvent& pEvent ) +: event::Event( pTime, pEvent ) +, mFileName( pEvent.mFileName ) +, mMode( pEvent.mMode ) +{} + +SaveSimulationEvent::~SaveSimulationEvent() +{} + +event::Event* +SaveSimulationEvent::copy() const +{ + return new SaveSimulationEvent( *this ); +} + +event::Event* +SaveSimulationEvent::copy( double pTime ) const +{ + return new SaveSimulationEvent( pTime, *this ); +} + +void +SaveSimulationEvent::execute() throw (Exception) +{ + mStarted = true; + mFinished = false; + + try + { + //std::cout << "SaveSimulationEvent::execute() begin\n"; + + SerializeTools::get().save( mFileName, mMode ); + + //std::cout << "SaveSimulationEvent::execute() end\n"; + } + catch( Exception& e ) + { + Simulation::get().exceptionReport( e ); + } + + mStarted = false; + mFinished = true; +} \ No newline at end of file diff --git a/src/dab_flock_save_simulation_event.h b/src/dab_flock_save_simulation_event.h new file mode 100644 index 0000000..f2379cd --- /dev/null +++ b/src/dab_flock_save_simulation_event.h @@ -0,0 +1,42 @@ +/** dab_flock_save_simulation_event.h + * + * Created by Daniel Bisig on 5/20/10. + * Ported to OpenFrameworks by Daniel Bisig on 02/11/2017. + * + */ + +#ifndef _dab_flock_save_simulation_event_h_ +#define _dab_flock_save_simulation_event_h_ + +#include "dab_flock_serialize.h" +#include "dab_event.h" + +namespace dab +{ + +namespace flock +{ + +class SaveSimulationEvent : public event::Event +{ +public: + SaveSimulationEvent( const std::string& pFileName, SerializeTools::SerializeMode pMode = SerializeTools::AllMode ); + SaveSimulationEvent( double pTime, const std::string& pFileName, SerializeTools::SerializeMode pMode = SerializeTools::AllMode ); + SaveSimulationEvent( const SaveSimulationEvent& pEvent ); + SaveSimulationEvent( double pTime, const SaveSimulationEvent& pEvent ); + virtual ~SaveSimulationEvent(); + + event::Event* copy() const; + event::Event* copy( double pTime ) const; + void execute() throw (Exception); + +protected: + std::string mFileName; + SerializeTools::SerializeMode mMode; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_serialize.cpp b/src/dab_flock_serialize.cpp new file mode 100644 index 0000000..1e97171 --- /dev/null +++ b/src/dab_flock_serialize.cpp @@ -0,0 +1,2719 @@ +/** \file dab_flock_serialize.cpp +*/ + +#include "dab_flock_serialize.h" +#include "dab_file_io.h" +#include "dab_flock_simulation.h" +#include "dab_flock_swarm.h" +#include "dab_flock_agent.h" +#include "dab_flock_env.h" +#include "dab_flock_behavior.h" +#include "dab_flock_swarm_behavior.h" +#include "dab_flock_behavior_includes.h" +#include "dab_flock_visual.h" +#include "dab_flock_visual_swarm.h" +#include "dab_flock_visual_agent_shape.h" +#include "dab_flock_visual_agent_trail.h" +#include "dab_flock_visual_neighbor_space.h" +#include "dab_flock_visual_grid_space.h" +#include "dab_space_includes.h" + +using namespace dab; +using namespace dab::flock; + +template<> +void +SerializeTools::getValues(const Json::Value& pData, const std::string& pName, dab::Array& pValues ) throw (Exception) +{ + if( pData.isMember(pName) == false ) throw Exception("FLOCK ERROR: no data with name " + pName + " found", __FILE__, __FUNCTION__, __LINE__); + + const Json::Value& data = pData[pName]; + int dataDim = data.size(); + + pValues.setSize(dataDim); + + for(int d=0; d(); + // registerBehavior< EnvDiffusionBehavior >(); + // registerBehavior< EnvGrayScottBehavior >(); + // registerBehavior< EnvGiererMeinhardtBehavior >(); + // registerBehavior< EnvAgentInteractBehavior >(); +} + +void +SerializeTools::registerBehavior(Behavior* pBehavior) +{ + mBehaviorMap[pBehavior->className()] = pBehavior; +} + +void +SerializeTools::save( const std::string& pFileName, SerializeMode pMode ) throw (Exception) +{ + //std::cout << "save begin\n"; + + try + { + if( Simulation::get().paused() == false ) Simulation::get().switchPaused(); + + Json::Value serializeData; + serializeData["className"] = "Swarm"; + serializeData["configName"] = "Swarm"; + + if( pMode == ConfigMode || pMode == AllMode ) + { + saveConfig( serializeData ); + } + + if( pMode == ValuesMode || pMode == AllMode ) + { + saveValues( serializeData ); + } + + if( Simulation::get().paused() == true ) Simulation::get().switchPaused(); + + // write data + try + { + Json::StyledWriter styledWriter; + dab::FileIO::get().write(styledWriter.write(serializeData), ofToDataPath(pFileName)); + } + catch(dab::Exception& e) + { + e += dab::Exception("FILE ERROR: failed to write file " + pFileName, __FILE__, __FUNCTION__, __LINE__); + throw e; + } + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to save to file " + pFileName, __FILE__, __FUNCTION__, __LINE__); + throw e; + } + + //std::cout << "save end\n"; +} + +void +SerializeTools::saveConfig( Json::Value& pSerializeData ) throw (Exception) +{ + try + { + Json::Value configData; + configData["className"] = "SwarmConfig"; + configData["configName"] = "SwarmConfig"; + + serializeSim(configData); + serializeCom(configData); + serializeSpace(configData); + serializeSwarms(configData); + serializeVis(configData); + + pSerializeData["SwarmConfig"] = configData; + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: failed to save configuration", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +SerializeTools::saveValues( Json::Value& pSerializeData ) throw (Exception) +{ + try + { + Json::Value valuesData; + valuesData["className"] = "SwarmValues"; + valuesData["configName"] = "SwarmValues"; + + serializeValues(valuesData); + + pSerializeData["SwarmValues"] = valuesData; + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: failed to save values", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +SerializeTools::restore( const std::string& pFileName, SerializeMode pMode ) throw (Exception) +{ + try + { + if( Simulation::get().paused() == false ) Simulation::get().switchPaused(); + + std::string serializeString; + dab::FileIO::get().read(ofToDataPath(pFileName), serializeString); + + Json::Reader reader; + Json::Value serializeData; + + bool parsingSuccessful = reader.parse(serializeString, serializeData); + + if(parsingSuccessful == false) throw Exception("FLOCK ERROR: failed to parse file " + pFileName, __FILE__, __FUNCTION__, __LINE__); + + if( pMode == ConfigMode || pMode == AllMode ) + { + const Json::Value& configData = getValue(serializeData,"SwarmConfig"); + + restoreConfig( configData ); + } + + if( pMode == ValuesMode || pMode == AllMode ) + { + const Json::Value& valuesData = getValue(serializeData,"SwarmValues"); + + restoreValues( valuesData ); + } + + + if( Simulation::get().paused() == true ) Simulation::get().switchPaused(); + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: failed to restore file " + pFileName, __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +SerializeTools::restoreConfig( const Json::Value& pConfigData ) throw (Exception) +{ + try + { + deSerializeSim( pConfigData ); + deSerializeCom( pConfigData ); + deSerializeSpace( pConfigData ); + deSerializeSwarms( pConfigData ); + deSerializeVis( pConfigData ); + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: failed to restore config", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +SerializeTools::restoreValues( const Json::Value& pValuesData ) throw (Exception) +{ + //std::cout << "SerializeTools::restoreValues begin\n"; + + try + { + deSerializeValues( pValuesData ); + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: failed to restore values", __FILE__, __FUNCTION__, __LINE__); + throw e; + } + + //std::cout << "SerializeTools::restoreValues end\n"; +} + +void +SerializeTools::serializeSim( Json::Value& pSerializeData ) throw (Exception) +{ + try + { + float simUpdateInterval = Simulation::get().updateInterval(); + + Json::Value simData; + simData["className"] = "Simulation"; + simData["configName"] = "Simulation"; + simData["rate"] = simUpdateInterval; + + pSerializeData["Simulation"] = simData; + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: failed to serialize simulation", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +SerializeTools::serializeCom( Json::Value& pSerializeData ) throw (Exception) +{ + try + { + FlockCom& flockCom = Simulation::get().com(); + + std::vector< std::string > senderNames = flockCom.senderNames(); + std::vector< std::string > receiverNames = flockCom.receiverNames(); + + int comCount = senderNames.size() + receiverNames.size(); + + if( comCount > 0 ) + { + Json::Value comSerializeData; + comSerializeData["className"] = "Communication"; + comSerializeData["configName"] = "Communication"; + + int senderCount = senderNames.size(); + + if( senderCount > 0 ) + { + Json::Value sendersSerializeData; + for( int sI=0; sI < senderCount; ++sI ) + { + std::string senderName = senderNames[sI]; + std::string senderIP = flockCom.senderIP( senderName ); + unsigned senderPort = flockCom.senderPort( senderName ); + bool extendedOscMode = flockCom.extendedOscMode(senderName); + + Json::Value senderSerializeData; + senderSerializeData["className"] = "Sender"; + senderSerializeData["configName"] = "Sender"; + senderSerializeData["configNr"] = sI; + senderSerializeData["name"] = senderName;; + senderSerializeData["ip"] = senderIP; + senderSerializeData["port"] = senderPort; + senderSerializeData["extOscMode"] = extendedOscMode; + + sendersSerializeData.append(senderSerializeData); + } + + comSerializeData["Senders"] = sendersSerializeData; + } + + int receiverCount = receiverNames.size(); + + if( receiverCount > 0) + { + Json::Value receiversSerializeData; + + for( int rI=0; rI < receiverCount; ++rI ) + { + std::string receiverName = receiverNames[rI]; + unsigned receiverPort = flockCom.receiverPort( receiverName ); + + Json::Value receiverSerializeData; + receiverSerializeData["className"] = "Receiver"; + receiverSerializeData["configName"] = "Receiver"; + receiverSerializeData["configNr"] = rI; + receiverSerializeData["name"] = receiverName; + receiverSerializeData["port"] = receiverPort; + + receiversSerializeData.append(receiverSerializeData); + } + + comSerializeData["Receivers"] = receiversSerializeData; + } + + pSerializeData["Communication"] = comSerializeData; + + } + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: failed to serialize communication", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +SerializeTools::serializeSpace( Json::Value& pSerializeData ) throw (Exception) +{ + //std::cout << "SerializeTools::serializeSpace begin\n"; + + try + { + space::SpaceManager& spaceManager = space::SpaceManager::get(); + + std::vector< std::string > spaceNames = spaceManager.spaceNames(); + int spaceCount = spaceNames.size(); + + if( spaceCount > 0 ) + { + Json::Value spacesSerializeData; + + for(int sI=0; sI space = spaceManager.space(spaceNames[sI]); + space::SpaceAlg* spaceAlg = space->spaceAlg(); + const std::string& spaceName = space->name(); + unsigned int spaceDim = spaceAlg->dim(); + + // only deal with grid spaces that own their own grids. The other grid spaces are created from environments and will be dealt with there + if( dynamic_cast< space::GridAlg* >( spaceAlg ) != NULL && ( dynamic_cast< space::GridAlg* >( spaceAlg ) )->gridOwner() == false ) continue; + + Json::Value spaceSerializeData; + spaceSerializeData["className"] = "Space"; + spaceSerializeData["configName"] = "Space"; + spaceSerializeData["configNr"] = sI; + spaceSerializeData["name"] = spaceName; + spaceSerializeData["dim"] = spaceDim; + + std::cout << "space name " << spaceName << "\n"; + + if( spaceAlg->fixedSize() == true ) + { + spaceSerializeData["minPos"] = addValues(spaceAlg->minPos()); + spaceSerializeData["maxPos"] = addValues(spaceAlg->maxPos()); + } + + if( dynamic_cast< space::RTreeAlg* >( spaceAlg ) != nullptr ) + { + spaceSerializeData["algorithm"] = "RTree"; + + if( ( dynamic_cast< space::RTreeAlg* >( spaceAlg ) )->closestShapePointType() == space::ClosestPointAABB ) + { + spaceSerializeData["closestPointType"] = "AABB"; + } + else + { + spaceSerializeData["closestPointType"] = "Shape"; + } + } + else if( dynamic_cast< space::PermanentNeighborsAlg* >( spaceAlg ) != nullptr ) + { + spaceSerializeData["algorithm"] = "Manual"; + } + else if( dynamic_cast< space::NTreeAlg* >( spaceAlg ) != nullptr ) + { + spaceSerializeData["algorithm"] = "NTree"; + } + else if( dynamic_cast< space::KDTreeAlg* >( spaceAlg ) != nullptr ) + { + spaceSerializeData["algorithm"] = "KDTree"; + } + else if( dynamic_cast< space::ANNAlg* >( spaceAlg ) != nullptr ) + { + spaceSerializeData["algorithm"] = "ANN"; + } + else if( dynamic_cast< space::GridAlg* >( spaceAlg ) != nullptr ) + { + spaceSerializeData["algorithm"] = "Grid"; + + space::GridAlg* gridAlg = dynamic_cast< space::GridAlg* >( spaceAlg ); + space::SpaceGrid* spaceGrid = &( gridAlg->grid() ); + + spaceSerializeData["valueDim"] = spaceGrid->valueDim(); + spaceSerializeData["subdivisionCount"] = addValues(spaceGrid->subdivisionCount()); + + if( gridAlg->neighborMode() == space::GridAlg::CellLocationMode ) spaceSerializeData["neighborMode"] = "CellLocationMode"; + else if( gridAlg->neighborMode() == space::GridAlg::GridLocationMode ) spaceSerializeData["neighborMode"] = "GridLocationMode"; + else if( gridAlg->neighborMode() == space::GridAlg::AvgLocationMode ) spaceSerializeData["neighborMode"] = "AvgLocationMode"; + else if( gridAlg->neighborMode() == space::GridAlg::AvgRegionMode ) spaceSerializeData["neighborMode"] = "AvgRegionMode"; + + if( gridAlg->updateMode() == space::GridAlg::NoUpdateMode ) spaceSerializeData["updateMode"] = "NoUpdateMode"; + else if( gridAlg->updateMode() == space::GridAlg::NearestReplaceMode ) spaceSerializeData["updateMode"] = "NearestReplaceMode"; + else if( gridAlg->updateMode() == space::GridAlg::NearestAddMode ) spaceSerializeData["updateMode"] = "NearestAddMode"; + else if( gridAlg->updateMode() == space::GridAlg::AvgReplaceMode ) spaceSerializeData["updateMode"] = "AvgReplaceMode"; + else if( gridAlg->updateMode() == space::GridAlg::AvgAddMode ) spaceSerializeData["updateMode"] = "AvgAddMode"; + } + + pSerializeData["Spaces"].append(spaceSerializeData); + } + } + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: failed to serialize spaces", __FILE__, __FUNCTION__, __LINE__); + throw e; + } + + //std::cout << "SerializeTools::serializeSpace end\n"; +} + +void +SerializeTools::serializeSwarms( Json::Value& pSerializeData ) throw (Exception) +{ + try + { + + // **** + // Envs + // **** + + std::vector& envs = Simulation::get().envs(); + int envCount = envs.size(); + + if( envCount > 0 ) + { + for(int eI=0; eIname(); + unsigned int envDim = env->dim(); + + envSerializeData["name"] = envName; + envSerializeData["dim"] = envDim; + + // **************** + // Env Parameters + // **************** + + int parameterCount = env->parameterCount(); + + if( parameterCount > 0 ) + { + for(int epI=0; epI < parameterCount; ++epI ) + { + Json::Value parameterSerializeData; + + Parameter* parameter = env->parameter(epI); + EnvParameter* envParameter = dynamic_cast< EnvParameter* >( parameter ); + const std::string& parameterName = parameter->name(); + unsigned int parameterDim = parameter->values().rows(); + + parameterSerializeData["name"] = parameterName; + + if( envParameter != nullptr ) + { + parameterSerializeData["className"] = "EnvParameter"; + parameterSerializeData["configName"] = "EnvParameter"; + parameterSerializeData["configNr"] = epI; + parameterSerializeData["valueDim"] = parameterDim; + parameterSerializeData["gridSize"] = addValues(envParameter->gridSize()); + parameterSerializeData["minPos"] = addValues(envParameter->minPos()); + parameterSerializeData["maxPos"] = addValues(envParameter->maxPos()); + } + else + { + parameterSerializeData["className"] = "Parameter"; + parameterSerializeData["configName"] = "EnvParameter"; + parameterSerializeData["configNr"] = epI; + parameterSerializeData["dim"] = parameterDim; + parameterSerializeData["values"] = addValues(parameter->values()); + } + + //******************** + // Parameter Neighbors + //******************** + + int neighborGroupCount = parameter->neighbors()->neighborGroupCount(); + + if( neighborGroupCount > 0 ) + { + for( int nI=0; nIneighborGroup( nI )->space()->name(); + + neighborSerializeData["spaceName"] = neighborSpaceName; + neighborSerializeData["visible"] = parameter->visible( neighborSpaceName ); + + if( parameter->canHaveNeighbors( neighborSpaceName ) == true ) + { + neighborSerializeData["radius"] = parameter->neighborRadius( neighborSpaceName ); + neighborSerializeData["maxNeighborCount"] = parameter->maxNeighborCount( neighborSpaceName ); + neighborSerializeData["replaceNeighborMode"] = parameter->replaceNeighborMode( neighborSpaceName ); + } + + parameterSerializeData["Neighbors"].append( neighborSerializeData ); + } + } + + //************************ + // Parameter Communication + //************************ + + std::vector< ParameterRegistration* > comInfos = Simulation::get().com().parameterRegistrations( envName, parameterName ); + int cC = comInfos.size(); + + if( cC > 0 ) + { + for( int cI=0; cIsenderName(); + comSerializeData["sendInterval"] = comInfo->sendInterval(); + + if( comInfo->normalise() == true ) + { + comSerializeData["minParValue"] = addValues(comInfo->minParValue()); + comSerializeData["maxParValue"] = addValues(comInfo->maxParValue()); + } + + comSerializeData["agentRange"] = addValues(comInfo->agentRange()); + comSerializeData["agentGroupSize"] = comInfo->agentGroupSize(); + + parameterSerializeData["Communications"].append( comSerializeData ); + } + } + + envSerializeData["Parameters"].append( parameterSerializeData ); + + } + } + + // ************** + // Env behaviors + // ************** + + int behaviorCount = env->behaviorCount(); + + if( behaviorCount > 0 ) + { + for(int ebI=0; ebI < behaviorCount; ++ebI ) + { + Json::Value envBehaviorSerializeData; + + Behavior* behavior = env->behavior( ebI ); + + const std::string& behaviorName = behavior->name(); + const std::string& behaviorClassName = behavior->className(); + + envBehaviorSerializeData["className"] = behaviorClassName; + envBehaviorSerializeData["configName"] = behaviorClassName; + envBehaviorSerializeData["configNr"] = ebI; + + envBehaviorSerializeData["name"] = behaviorName; + + envBehaviorSerializeData["inputParameters"] = behavior->inputParameterString(); + envBehaviorSerializeData["outputParameters"] = behavior->outputParameterString(); + + + envSerializeData["Behaviors"].append(envBehaviorSerializeData); + } + } + + pSerializeData["Envs"].append(envSerializeData); + + } + } + + // ****** + // Swarms + // ****** + + std::vector& swarms = Simulation::get().swarms(); + int swarmCount = swarms.size(); + + if( swarmCount > 0 ) + { + for(int sI=0; sIname(); + unsigned int agentCount = swarm->agentCount(); + + //std::cout << "serialize swarm " << swarmName.toStdString() << "\n"; + + swarmSerializeData["name"] = swarmName; + swarmSerializeData["agentCount"] = agentCount; + + // **************** + // Swarm Parameters + // **************** + + int swarmParameterCount = swarm->swarmParameterCount(); + + if( swarmParameterCount > 0 ) + { + for(int spI=0; spI < swarmParameterCount; ++spI ) + { + Json::Value swarmParameterSerializeData; + swarmParameterSerializeData["className"] = "SwarmParameter"; + swarmParameterSerializeData["configName"] = "SwarmParameter"; + swarmParameterSerializeData["configNr"] = spI; + + Parameter* swarmParameter = swarm->swarmParameter( spI ); + const std::string& swarmParameterName = swarmParameter->name(); + unsigned int swarmParameterDim = swarmParameter->dim(); + const Eigen::VectorXf& swarmParameterValues = swarmParameter->values(); + + swarmParameterSerializeData["name"] = swarmParameterName; + swarmParameterSerializeData["dim"] = swarmParameterDim; + swarmParameterSerializeData["values"] = addValues(swarmParameterValues); + + //******************** + // Parameter Neighbors + //******************** + + std::vector< NeighborAssignInfo* > neighborInfos = swarm->swarmNeighborInfo( swarmParameterName ); + int nC = neighborInfos.size(); + + if( nC > 0 ) + { + for( int nI=0; nImSpaceName; + neighborSerializeData["visible"] = neighborInfo->mVisible; + + if( neighborInfo->mNeighborGroupAlg != nullptr ) + { + neighborSerializeData["radius"] = neighborInfo->mNeighborGroupAlg->neighborRadius(); + neighborSerializeData["maxNeighborCount"] = neighborInfo->mNeighborGroupAlg->maxNeighborCount(); + neighborSerializeData["replaceNeighborMode"] = neighborInfo->mNeighborGroupAlg->replaceNeighborMode(); + } + + swarmParameterSerializeData["Neighbors"].append( neighborSerializeData ); + } + } + + //************************ + // Parameter Communication + //************************ + + std::vector< ParameterRegistration* > comInfos = Simulation::get().com().parameterRegistrations( swarmName, swarmParameterName ); + int cC = comInfos.size(); + + if( cC > 0 ) + { + for( int cI=0; cIsenderName(); + comSerializeData["sendInterval"] = comInfo->sendInterval(); + + if( comInfo->normalise() == true ) + { + comSerializeData["minParValue"] = addValues(comInfo->minParValue()); + comSerializeData["maxParValue"] = addValues(comInfo->maxParValue()); + } + + comSerializeData["agentRange"] = addValues(comInfo->agentRange()); + comSerializeData["agentGroupSize"] = comInfo->agentGroupSize(); + + swarmParameterSerializeData["Communications"].append( comSerializeData ); + } + } + + swarmSerializeData["SwarmParameters"].append( swarmParameterSerializeData ); + } + } + + // *************** + // Swarm behaviors + // *************** + + int swarmBehaviorCount = swarm->swarmBehaviorCount(); + + if( swarmBehaviorCount > 0 ) + { + for(int sbI=0; sbI < swarmBehaviorCount; ++sbI ) + { + Json::Value swarmBehaviorSerializeData; + + Behavior* behavior = swarm->swarmBehavior( sbI ); + SwarmBehavior* swarmBehavior = dynamic_cast< SwarmBehavior* >( behavior ); + + const std::string& behaviorClassName = behavior->className(); + + swarmBehaviorSerializeData["className"] = behaviorClassName; + + if( swarmBehavior != nullptr ) + { + swarmBehaviorSerializeData["configName"] = "SwarmBehavior"; + } + else + { + swarmBehaviorSerializeData["configName"] = "Behavior"; + } + + swarmBehaviorSerializeData["configNr"] = sbI; + + const std::string& swarmBehaviorName = behavior->name(); + + swarmBehaviorSerializeData["name"] = swarmBehaviorName; + + if( swarmBehavior != nullptr ) + { + swarmBehaviorSerializeData["inputAgentParameters"] = swarmBehavior->inputAgentParameterString(); + swarmBehaviorSerializeData["outputAgentParameters"] = swarmBehavior->outputAgentParameterString(); + swarmBehaviorSerializeData["inputSwarmParameters"] = swarmBehavior->inputSwarmParameterString(); + swarmBehaviorSerializeData["outputSwarmParameters"] = swarmBehavior->outputSwarmParameterString(); + } + else + { + swarmBehaviorSerializeData["inputParameters"] = swarmBehavior->inputParameterString(); + swarmBehaviorSerializeData["outputParameters"] = swarmBehavior->outputParameterString(); + } + + swarmSerializeData["SwarmBehaviors"].append( swarmBehaviorSerializeData ); + } + } + + // **************** + // Agent Parameters + // **************** + + int agentParameterCount = swarm->parameterCount(); + + if( agentParameterCount > 0 ) + { + for(int apI=0; apI( swarm )->parameter( apI ); + const std::string& parameterName = parameter->name(); + unsigned int parameterDim = parameter->dim(); + const Eigen::VectorXf& parameterValues = parameter->values(); + + agentParameterSerializeData["name"] = parameterName; + agentParameterSerializeData["dim"] = parameterDim; + agentParameterSerializeData["values"] = addValues(parameterValues); + + //******************** + // Parameter Neighbors + //******************** + + std::vector< NeighborAssignInfo* > neighborInfos = swarm->agentNeighborInfo( parameterName ); + int nC = neighborInfos.size(); + + if( nC > 0 ) + { + for( int nI=0; nImSpaceName; + neighborSerializeData["visible"] = neighborInfo->mVisible; + + if( neighborInfo->mNeighborGroupAlg != nullptr ) + { + neighborSerializeData["radius"] = neighborInfo->mNeighborGroupAlg->neighborRadius(); + neighborSerializeData["maxNeighborCount"] = neighborInfo->mNeighborGroupAlg->maxNeighborCount(); + neighborSerializeData["replaceNeighborMode"] = neighborInfo->mNeighborGroupAlg->replaceNeighborMode(); + } + + agentParameterSerializeData["Neighbors"].append( neighborSerializeData ); + } + } + + //************************ + // Parameter Communication + //************************ + + std::vector< ParameterRegistration* > comInfos = Simulation::get().com().parameterRegistrations( swarmName, parameterName ); + int cC = comInfos.size(); + + if( cC > 0 ) + { + Json::Value communicationsSerializeData; + + for( int cI=0; cIswarmName().toStdString() << " par " << comInfo->parameterName().toStdString() << " sender " << comInfo->senderName().toStdString() << "\n"; + + comSerializeData["senderName"] = comInfo->senderName(); + comSerializeData["sendInterval"] = comInfo->sendInterval(); + + if( comInfo->normalise() == true ) + { + comSerializeData["minParValue"] = addValues(comInfo->minParValue()); + comSerializeData["maxParValue"] = addValues(comInfo->maxParValue()); + } + + comSerializeData["agentRange"] = addValues(comInfo->agentRange()); + comSerializeData["agentGroupSize"] = comInfo->agentGroupSize(); + + communicationsSerializeData[comInfo->senderName()].append( comSerializeData ); + } + + agentParameterSerializeData["Communications"] = communicationsSerializeData; + } + + swarmSerializeData["AgentParameters"].append( agentParameterSerializeData ); + } + } + + // *************** + // Agent behaviors + // *************** + + int behaviorCount = swarm->behaviorCount(); + + if( behaviorCount > 0 ) + { + for(int abI=0; abI < behaviorCount; ++abI ) + { + Json::Value agentBehaviorSerializeData; + + Behavior* behavior = swarm->behavior( abI ); + + const std::string& behaviorName = behavior->name(); + const std::string& behaviorClassName = behavior->className(); + + agentBehaviorSerializeData["className"] = behaviorClassName; + agentBehaviorSerializeData["configName"] = "AgentBehavior"; + agentBehaviorSerializeData["configNr"] = abI; + + agentBehaviorSerializeData["name"] = behaviorName; + + agentBehaviorSerializeData["inputParameters"] = behavior->inputParameterString(); + agentBehaviorSerializeData["outputParameters"] = behavior->outputParameterString(); + + swarmSerializeData["AgentBehaviors"].append( agentBehaviorSerializeData ); + } + } + + pSerializeData["Swarms"].append(swarmSerializeData); + } + } + + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: Failed to serialize swarms", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +SerializeTools::serializeVis( Json::Value& pSerializeData ) throw (Exception) +{ + try + { + FlockVisuals& flockVisuals = FlockVisuals::get(); + + Json::Value visualSerializeData; + visualSerializeData["className"] = "Visual"; + visualSerializeData["configName"] = "Visual"; + + //***************** + // Display Settings + //***************** + + const glm::vec3& displayPosition = flockVisuals.displayPosition(); + const ofQuaternion& displayOrientation = flockVisuals.displayOrientation(); + const ofQuaternion& displayOrientationChange = flockVisuals.displayOrientationChange(); + + float displayZoom = flockVisuals.displayZoom(); + const std::array& displayColor = flockVisuals.displayColor(); + + visualSerializeData["displayPosition"] = addValues(displayPosition); + visualSerializeData["displayOrientation"] = addValues(displayOrientation); + visualSerializeData["displayOrientationChange"] = addValues(displayOrientationChange); + visualSerializeData["displayZoom"] = displayZoom; + visualSerializeData["displayColor"] = addValues(displayColor); + + const std::vector< VisSwarm* >& visualSwarms = flockVisuals.visualSwarms(); + unsigned int visualSwarmCount = visualSwarms.size(); + + if( visualSwarmCount > 0 ) + { + //************** + // Visual Swarms + //************** + + for(int i=0; iswarmName(); + visualSwarmSerializeData["posParName"] = visualSwarm->posParmName(); + visualSwarmSerializeData["velParName"] = visualSwarm->velParName(); + visualSwarmSerializeData["agentColor"] = addValues(visualSwarm->agentColor()); + visualSwarmSerializeData["agentScale"] = addValues(visualSwarm->agentScale()); + visualSwarmSerializeData["agentLineWidth"] = visualSwarm->agentLineWidth(); + visualSwarmSerializeData["trailColor"] = addValues(visualSwarm->trailColor()); + visualSwarmSerializeData["trailLength"] = visualSwarm->trailLength(); + visualSwarmSerializeData["trailWidth"] = visualSwarm->trailWidth(); + visualSwarmSerializeData["trailDecay"] = visualSwarm->trailDecay(); + + visualSerializeData["VisualSwarms"].append(visualSwarmSerializeData); + } + } + + const std::vector< VisNeighborSpace* >& visualNeighbors = flockVisuals.visualNeighbors(); + unsigned int visualNeighborCount = visualNeighbors.size(); + + if( visualNeighborCount > 0 ) + { + //***************** + // Visual Neighbors + //***************** + + for(int i=0; ispaceName(); + visualNeighborSerializeData["spaceColor"] = addValues(visualNeighbor->color()); + visualNeighborSerializeData["lineWidth"] = visualNeighbor->lineWidth(); + + visualSerializeData["VisualNeighbors"].append(visualNeighborSerializeData); + } + } + + const std::vector< VisGridSpace* >& visualGrids = flockVisuals.visualGrids(); + unsigned int visualGridCount = visualGrids.size(); + + if( visualGridCount > 0 ) + { + //************* + // Visual Grids + //************* + + Json::Value visualGridsSerializeData; + + for(int i=0; ispaceName(); + visualGridSerializeData["spaceColor"] = addValues(visualGrid->color()); + visualGridSerializeData["lineWidth"] = visualGrid->lineWidth(); + visualGridSerializeData["valueScale"] = visualGrid->valueScale(); + + visualSerializeData["VisualGrids"].append(visualGridSerializeData); + } + } + + pSerializeData["Visual"] = visualSerializeData; + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: failed to serialize visualization", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +SerializeTools::serializeValues( Json::Value& pSerializeData ) throw (Exception) +{ + try + { + std::vector& swarms = Simulation::get().swarms(); + int swarmCount = swarms.size(); + + if( swarmCount > 0 ) + { + // ***************** + // Swarms Parameters + // ***************** + + for(int sI=0; sIname(); + unsigned int agentCount = swarm->agentCount(); + + swarmSerializeData["name"] = swarmName; + swarmSerializeData["agentCount"] = agentCount; + + // **************** + // Swarm Parameters + // **************** + + int swarmParameterCount = swarm->swarmParameterCount(); + + if( swarmParameterCount > 0 ) + { + Json::Value swarmParametersSerializeData; + + int swarmParameterCount = swarm->swarmParameterCount(); + + for(int spI=0; spI < swarmParameterCount; ++spI ) + { + Json::Value swarmParameterSerializeData; + swarmParameterSerializeData["className"] = "SwarmParameter"; + swarmParameterSerializeData["configName"] = "SwarmParameter"; + + Parameter* swarmParameter = swarm->swarmParameter( spI ); + const std::string& swarmParameterName = swarmParameter->name(); + + swarmParameterSerializeData["name"] = swarmParameterName; + swarmParameterSerializeData["values"] = addValues(swarmParameter->values()); + + swarmSerializeData["SwarmParameters"].append(swarmParameterSerializeData); + } + } + + // **************** + // Agent Parameters + // **************** + + int agentParameterCount = swarm->parameterCount(); + + if( agentParameterCount > 0 ) + { + + Json::Value agentParametersSerializeData; + + int agentParameterCount = swarm->parameterCount(); + + for(int apI=0; apI( swarm )->parameter( apI ); + const std::string& agentParameterName = agentParameter->name(); + + agentParameterSerializeData["name"] = agentParameterName; + agentParameterSerializeData["values"] = addValues(agentParameter->values()); + + bool saveIndividualAgentParameterValues = false; + + for(int aI=0; aI < agentCount; ++aI) + { + const Parameter* individualAgentParameter = swarm->parameter(aI,agentParameterName ); + + if( individualAgentParameter->values() != agentParameter->values() ) + { + saveIndividualAgentParameterValues = true; + break; + } + } + + if( saveIndividualAgentParameterValues == true ) + { + for(int aI=0; aI < agentCount; ++aI) + { + const Parameter* individualAgentParameter = swarm->parameter(aI,agentParameterName ); + agentParameterSerializeData[ "value" + std::to_string(aI) ] = addValues(individualAgentParameter->values()); } + } + + swarmSerializeData["AgentParameters"].append(agentParameterSerializeData); + } + } + + pSerializeData["Swarms"].append( swarmSerializeData ); + } + } + + // *************** + // Envs Parameters + // *************** + + + std::vector& envs = Simulation::get().envs(); + int envCount = envs.size(); + + if( envCount > 0 ) + { + Json::Value envsSerializeData; + + for(int eI=0; eIname(); + unsigned int envDim = env->dim(); + + envSerializeData["name"] = envName; + envSerializeData["dim"] = envDim; + + // **************** + // Env Parameters + // **************** + + int parameterCount = env->parameterCount(); + + if( parameterCount > 0 ) + { + Json::Value envParametersSerializeData; + + for(int epI=0; epI < parameterCount; ++epI ) + { + Json::Value parameterSerializeData; + + Parameter* parameter = env->parameter(epI); + EnvParameter* envParameter = dynamic_cast< EnvParameter* >( parameter ); + const std::string& parameterName = parameter->name(); + unsigned int parameterDim = parameter->values().rows(); + + parameterSerializeData["name"] = parameterName; + + if( envParameter != nullptr ) + { + parameterSerializeData["className"] = "EnvParameter"; + parameterSerializeData["configName"] = "EnvParameter"; + parameterSerializeData["valueDim"] = parameterDim; + parameterSerializeData["gridSize"] = addValues(envParameter->gridSize()); + + space::SpaceGrid* parameterGrid = envParameter->grid(); + const math::VectorField& parameterField = parameterGrid->vectorField(); + unsigned int parameterVectorCount = parameterField.vectorCount(); + const std::vector& parameterVectors = parameterField.vectors(); + + for(unsigned int pvI=0; pvI < parameterVectorCount; ++pvI) + { + parameterSerializeData[ "vec" + std::to_string(pvI) ] = addValues(parameterVectors[pvI]); + } + } + else + { + parameterSerializeData["className"] = "Parameter"; + parameterSerializeData["configName"] = "EnvParameter"; + parameterSerializeData["dim"] = parameterDim; + parameterSerializeData["values"] = addValues(parameter->values()); + } + + envSerializeData["Parameters"].append(parameterSerializeData); + } + } + + pSerializeData["Envs"].append(envSerializeData); + } + } + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: Failed to serialize value", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +SerializeTools::deSerializeSim( const Json::Value& pSerializeData ) throw (Exception) +{ + try + { + if( pSerializeData.isMember("Simulation") == true ) + { + const Json::Value& simSerializeData = pSerializeData["Simulation"]; + float simRate = simSerializeData["rate"].asFloat(); + + Simulation::get().setUpdateInterval( simRate ); + } + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: failed to deserialize simulation", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +SerializeTools::deSerializeCom( const Json::Value& pSerializeData ) throw (Exception) +{ + try + { + if( pSerializeData.isMember("Communication") == true ) + { + FlockCom& flockCom = Simulation::get().com(); + + const Json::Value& comSerializeData = pSerializeData["Communication"]; + + if( comSerializeData.isMember( "Senders" ) ) + { + const Json::Value& sendersSerializeData = comSerializeData["Senders"]; + + int senderCount = sendersSerializeData.size(); + + for(int sI=0; sIsetClosestPointType(closestShapePointType); + spaceManager.addSpace( std::shared_ptr(new space::Space( name, alg ))); + } + } + else if( algName == "Manual" ) + { + if( fixedSize == false ) + { + spaceManager.addSpace( std::shared_ptr(new space::Space( name, new space::PermanentNeighborsAlg( dim )))); + } + else + { + spaceManager.addSpace( std::shared_ptr(new space::Space( name, new space::PermanentNeighborsAlg( minPosValues, maxPosValues )))); + } + } + else if( algName == "NTree" ) + { + if( fixedSize == false ) + { + spaceManager.addSpace( std::shared_ptr(new space::Space( name, new space::NTreeAlg( dim )))); + } + else + { + spaceManager.addSpace( std::shared_ptr(new space::Space( name, new space::NTreeAlg( minPosValues, maxPosValues )))); + } + } + else if( algName == "KDTree" ) + { + if( fixedSize == false ) + { + spaceManager.addSpace( std::shared_ptr(new space::Space( name, new space::KDTreeAlg( dim )))); + } + else + { + spaceManager.addSpace( std::shared_ptr(new space::Space( name, new space::KDTreeAlg( minPosValues, maxPosValues)))); + } + } + else if( algName == "ANN" ) + { + if( fixedSize == false ) + { + spaceManager.addSpace( std::shared_ptr(new space::Space( name, new space::ANNAlg( dim )))); + } + else + { + spaceManager.addSpace( std::shared_ptr(new space::Space( name, new space::ANNAlg( minPosValues, maxPosValues)))); + } + } + else if( algName == "Grid" ) + { + unsigned int valueDim = spaceSerial["valueDim"].asUInt(); + dab::Array subdivisionCount; + getValues(spaceSerial, "subdivisionCount", subdivisionCount); + std::string neighborModeName = spaceSerial["neighborMode"].asString(); + space::GridAlg::GridNeighborMode neighborMode; + + if( neighborModeName == "CellLocationMode" ) neighborMode = space::GridAlg::CellLocationMode; + else if( neighborModeName == "GridLocationMode" ) neighborMode = space::GridAlg::GridLocationMode; + else if( neighborModeName == "AvgLocationMode" ) neighborMode = space::GridAlg::AvgLocationMode; + else if( neighborModeName == "AvgRegionMode" ) neighborMode = space::GridAlg::AvgRegionMode; + + std::string updateModeName = spaceSerial["updateMode"].asString(); + space::GridAlg::GridUpdateMode updateMode; + + if( updateModeName == "NoUpdateMode" ) updateMode = space::GridAlg::NoUpdateMode; + else if( updateModeName == "NearestReplaceMode" ) updateMode = space::GridAlg::NearestReplaceMode; + else if( updateModeName == "NearestAddMode" ) updateMode = space::GridAlg::NearestAddMode; + else if( updateModeName == "AvgReplaceMode" ) updateMode = space::GridAlg::AvgReplaceMode; + else if( updateModeName == "AvgAddMode" ) updateMode = space::GridAlg::AvgAddMode; + + spaceManager.addSpace( std::shared_ptr(new space::Space( name, new space::GridAlg( valueDim, subdivisionCount, minPosValues, maxPosValues, neighborMode, updateMode )))); + + } + } + } + } + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to deserialize space", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +SerializeTools::deSerializeSwarms( const Json::Value& pSerializeData ) throw (Exception) +{ + try + { + //std::cout << "SerializeTools::deSerializeSwarms( serialize::SerializeData& pSerializeData ) begin\n"; + + Simulation& simulation = Simulation::get(); + FlockCom& flockCom = simulation.com(); + + // ********** + // Parameters + // ********** + + if( pSerializeData.isMember("Envs") == true ) + { + + // **** + // Envs + // **** + + const Json::Value& envsSerializeData = pSerializeData["Envs"]; + unsigned int envCount = envsSerializeData.size(); + + for( int eI =0; eI < envCount; ++eI ) + { + const Json::Value& envSerial = envsSerializeData[eI]; + + std::string envName = envSerial["name"].asString(); + unsigned int envDim = envSerial["dim"].asUInt(); + + Env* env = new Env( envName, envDim ); + + if( envSerial.isMember("Parameters") == true ) + { + + // **************** + // Env Parameters + // **************** + + const Json::Value& envParametersSerialData = envSerial["Parameters"]; + unsigned int envParameterCount = envParametersSerialData.size(); + + for( int epI =0; epI < envParameterCount; ++epI ) + { + const Json::Value& parameterSerial = envParametersSerialData[epI]; + + std::string parameterName = parameterSerial["name"].asString(); + unsigned int parameterDim; + + if( parameterSerial.isMember("gridSize") ) + { + if( env->checkParameter( parameterName ) == false ) + { + unsigned int valueDim = parameterSerial["valueDim"].asUInt(); + parameterDim = valueDim; + unsigned int gridDim; + dab::Array subDivisionCount; + Eigen::VectorXf minPos; + Eigen::VectorXf maxPos; + + getValues(parameterSerial, "gridSize", subDivisionCount); + getValues(parameterSerial, "minPos", minPos); + getValues(parameterSerial, "maxPos", maxPos); + + env->addParameter( parameterName, valueDim, subDivisionCount, minPos, maxPos ); + + } + } + else + { + parameterDim = parameterSerial["dim"].asUInt(); + Eigen::VectorXf parameterValues; + + getValues(parameterSerial, "values", parameterValues); + + if( env->checkParameter( parameterName ) == false ) + { + env->addParameter( parameterName, parameterValues ); + } + else + { + env->set( parameterName, parameterValues ); + } + } + + if( parameterSerial.isMember("Neighbors") == true ) + { + + // ************************ + // Env Parameters Neighbors + // ************************ + + const Json::Value& neighborSerialData = parameterSerial["Neighbors"]; + unsigned int envNeighborCount = neighborSerialData.size(); + + for( int enI =0; enI < envNeighborCount; ++enI ) + { + const Json::Value& neighborSerial = neighborSerialData[enI]; + + std::string spaceName = neighborSerial["spaceName"].asString(); + + if( env->parameter( parameterName )->checkNeighborGroup( spaceName ) == false ) + { + bool visible = neighborSerial["visible"].asBool(); + space::NeighborGroupAlg* neighborAlg = nullptr; + + if( neighborSerial.isMember("radius") ) + { + float radius = neighborSerial["radius"].asFloat(); + unsigned int maxNeighborCount = neighborSerial["maxNeighborCount"].asUInt(); + bool replaceNeighborMode = neighborSerial["replaceNeighborMode"].asBool(); + + neighborAlg = new space::NeighborGroupAlg( radius, maxNeighborCount, replaceNeighborMode ); + } + + env->assignNeighbors( parameterName, spaceName, visible, neighborAlg ); + } + } + } + + if( parameterSerial.isMember("Communications") == true ) + { + + //**************************** + // Env Parameter Communication + //**************************** + + const Json::Value& communicationSerialData = parameterSerial["Communications"]; + unsigned int envCommunicationCount = communicationSerialData.size(); + + for( int ecI =0; ecI < envCommunicationCount; ++ecI ) + { + const Json::Value& communicationSerial = communicationSerialData[ecI]; + + std::string senderName = communicationSerial["senderName"].asString(); + + if( flockCom.checkParameter( senderName, envName, parameterName ) == false ) + { + std::array agentRange; + getValues(communicationSerial, "agentRange", agentRange); + + + int sendInterval = 1; + if( communicationSerial.isMember("sendInterval") ) + { + sendInterval = communicationSerial["sendInterval"].asInt(); + } + + int agentGroupSize = 1; + if( communicationSerial.isMember("agentGroupSize") == true ) + { + agentGroupSize = communicationSerial["agentGroupSize"].asInt(); + } + + if( communicationSerial.isMember("minParValue") == true ) + { + Eigen::VectorXf minParValue; + Eigen::VectorXf maxParValue; + + getValues(communicationSerial, "minParValue", minParValue); + getValues(communicationSerial, "maxParValue", maxParValue); + + flockCom.registerParameter(senderName, sendInterval, envName, parameterName, agentRange, agentGroupSize, minParValue, maxParValue ); + } + else + { + flockCom.registerParameter(senderName, sendInterval, envName, parameterName, agentRange, agentGroupSize ); + } + } + } + } + } + } + } + } + + if( pSerializeData.isMember("Swarms") == true ) + { + // ****** + // Swarms + // ****** + + const Json::Value& swarmsSerialData = pSerializeData["Swarms"]; + + unsigned int swarmCount = swarmsSerialData.size(); + + for(int sI=0; sIcheckSwarmParameter( parameterName ) == false ) + { + swarm->addSwarmParameter( parameterName, parameterValues ); + } + else + { + swarm->set( parameterName, parameterValues ); + } + + if( parameterSerial.isMember("Neighbors") == true ) + { + + // ************************** + // Swarm Parameters Neighbors + // ************************** + + const Json::Value& neighborsSerialData = parameterSerial["Neighbors"]; + unsigned int neighborCount = neighborsSerialData.size(); + + for( int nI =0; nI < neighborCount; ++nI ) + { + const Json::Value& neighborSerial = neighborsSerialData[nI]; + + std::string spaceName = neighborSerial["spaceName"].asString(); + + if( swarm->swarmParameter( parameterName )->checkNeighborGroup( spaceName ) == false ) + { + bool visible = neighborSerial["visible"].asBool(); + space::NeighborGroupAlg* neighborAlg = nullptr; + + if( neighborSerial.isMember("radius") ) + { + float radius = neighborSerial["radius"].asFloat(); + unsigned int maxNeighborCount = neighborSerial["maxNeighborCount"].asUInt(); + bool replaceNeighborMode = neighborSerial["replaceNeighborMode"].asBool(); + + neighborAlg = new space::NeighborGroupAlg( radius, maxNeighborCount, replaceNeighborMode ); + } + + swarm->assignNeighbors( parameterName, spaceName, visible, neighborAlg ); + } + } + + } + + if( parameterSerial.isMember("Communications") == true ) + { + + //************************ + // Parameter Communication + //************************ + + const Json::Value communicationsSerialData = parameterSerial["Communications"]; + unsigned int communicationCount = communicationsSerialData.size(); + + for( int cI =0; cI < communicationCount; ++cI ) + { + const Json::Value& communicationSerial = communicationsSerialData[cI]; + + std::string senderName = communicationSerial["senderName"].asString(); + + if( flockCom.checkParameter( senderName, swarmName, parameterName ) == false ) + { + std::array agentRange; + getValues(communicationSerial, "agentRange", agentRange); + + int sendInterval = 1; + if( communicationSerial.isMember("sendInterval") ) + { + sendInterval = communicationSerial["sendInterval"].asInt(); + } + + int agentGroupSize = 1; + + if( communicationSerial.isMember("agentGroupSize") == true ) + { + agentGroupSize = communicationSerial["agentGroupSize"].asInt(); + } + + if( communicationSerial.isMember("minParValue") == true ) + { + Eigen::VectorXf minParValue; + Eigen::VectorXf maxParValue; + + getValues(communicationSerial, "minParValue", minParValue); + getValues(communicationSerial, "maxParValue", maxParValue); + + flockCom.registerParameter(senderName, sendInterval, swarmName, parameterName, agentRange, agentGroupSize, minParValue, maxParValue ); + } + else + { + flockCom.registerParameter(senderName, sendInterval, swarmName, parameterName, agentRange, agentGroupSize ); + } + } + } + } + } + } + + if( swarmSerial.isMember("AgentParameters") == true ) + { + + // **************** + // Agent Parameters + // **************** + + const Json::Value& agentParametersSerialData = swarmSerial["AgentParameters"]; + unsigned int agentParameterCount = agentParametersSerialData.size(); + + for( int apI =0; apI < agentParameterCount; ++apI ) + { + const Json::Value& parameterSerial = agentParametersSerialData[apI]; + + std::string parameterName = parameterSerial["name"].asString(); + unsigned int parameterDim = parameterSerial["dim"].asInt(); + + //std::cout << "agent parameter swarmName " << swarmName.toStdString() << " parameterName " << parameterName.toStdString() << " parameterDim " << parameterDim << "\n"; + + Eigen::VectorXf parameterValues; + getValues(parameterSerial, "values", parameterValues); + + if( swarm->checkParameter( parameterName ) == false ) + { + swarm->addParameter( parameterName, parameterValues ); + } + else + { + swarm->set( parameterName, parameterValues ); + } + + if( parameterSerial.isMember("Neighbors") == true ) + { + + // ************************** + // Agent Parameters Neighbors + // ************************** + + const Json::Value& neighborsSerialData = parameterSerial["Neighbors"]; + unsigned int neighborCount = neighborsSerialData.size(); + + for( int nI =0; nI < neighborCount; ++nI ) + { + const Json::Value& neighborSerial = neighborsSerialData[nI]; + + std::string spaceName = neighborSerial["spaceName"].asString(); + + if( static_cast( swarm )->parameter( parameterName )->checkNeighborGroup( spaceName ) == false ) + { + bool visible = neighborSerial["visible"].asBool(); + space::NeighborGroupAlg* neighborAlg = nullptr; + + if( neighborSerial.isMember("radius") ) + { + float radius = neighborSerial["radius"].asFloat(); + unsigned int maxNeighborCount = neighborSerial["maxNeighborCount"].asUInt(); + bool replaceNeighborMode = neighborSerial["replaceNeighborMode"].asBool(); + + neighborAlg = new space::NeighborGroupAlg( radius, maxNeighborCount, replaceNeighborMode ); + } + + swarm->assignNeighbors( parameterName, spaceName, visible, neighborAlg ); + } + } + } + + if( parameterSerial.isMember("Communications") == true ) + { + + //****************************** + // Agent Parameter Communication + //****************************** + + const Json::Value& communicationSerialData = parameterSerial["Communications"]; + unsigned int communicationCount = communicationSerialData.size(); + + for( int cI =0; cI < communicationCount; ++cI ) + { + const Json::Value& communicationSerial = communicationSerialData[cI]; + + std::string senderName = communicationSerial["senderName"].asString(); + + if( flockCom.checkParameter( senderName, swarmName, parameterName ) == false ) + { + std::array agentRange; + getValues(communicationSerial, "agentRange", agentRange); + + int sendInterval = 1; + if( communicationSerial.isMember("sendInterval") ) + { + sendInterval = communicationSerial["sendInterval"].asInt(); + } + + int agentGroupSize = 1; + + if( communicationSerial.isMember("agentGroupSize") == true ) + { + agentGroupSize = communicationSerial["agentGroupSize"].asInt(); + } + + if( communicationSerial.isMember("minParValue") == true ) + { + Eigen::VectorXf minParValue; + Eigen::VectorXf maxParValue; + + getValues(communicationSerial, "minParValue", minParValue); + getValues(communicationSerial, "maxParValue", maxParValue); + + flockCom.registerParameter(senderName, sendInterval, swarmName, parameterName, agentRange, agentGroupSize, minParValue, maxParValue ); + } + else + { + flockCom.registerParameter(senderName, sendInterval, swarmName, parameterName, agentRange, agentGroupSize ); + } + } + } + } + } + } + + //swarm->addAgents( agentCount ); + } + } + + //********** + // Behaviors + //********** + + if( pSerializeData.isMember("Envs") == true ) + { + + // **** + // Envs + // **** + + const Json::Value& envsSerializeData = pSerializeData["Envs"]; + unsigned int envCount = envsSerializeData.size(); + + for( int eI =0; eI < envCount; ++eI ) + { + const Json::Value& envSerial = envsSerializeData[eI]; + + std::string envName = envSerial["name"].asString(); + unsigned int envDim = envSerial["dim"].asUInt(); + + Env* env = simulation.env( envName ); + + if( envSerial.isMember("Behaviors") == true ) + { + + // ************* + // Env behaviors + // ************* + + const Json::Value& envBehaviorsSerialData = envSerial["Behaviors"]; + unsigned int envBehaviorCount = envBehaviorsSerialData.size(); + + for( int ebI =0; ebI < envBehaviorCount; ++ebI ) + { + const Json::Value& behaviorSerial = envBehaviorsSerialData[ebI]; + + std::string behaviorName = behaviorSerial["name"].asString(); + + if( env->checkBehavior(behaviorName) == false ) + { + std::string behaviorClass = behaviorSerial["className"].asString(); + std::string inputParameterString = behaviorSerial["inputParameters"].asString(); + std::string outputParameterString = behaviorSerial["outputParameters"].asString(); + + if(mBehaviorMap.find(behaviorClass) == mBehaviorMap.end()) throw Exception("FLOCK ERROR: behavior class " + behaviorClass + " cannot be deserialized", __FILE__, __FUNCTION__, __LINE__); + + Behavior* behavior = mBehaviorMap[behaviorClass]->create( inputParameterString, outputParameterString ); + + env->addBehavior( behaviorName, *behavior ); + + delete behavior; + } + } + } + } + } + + if( pSerializeData.isMember("Swarms") == true ) + { + // ****** + // Swarms + // ****** + + const Json::Value& swarmsSerialData = pSerializeData["Swarms"]; + unsigned int swarmCount = swarmsSerialData.size(); + + for(int sI=0; sIcheckSwarmBehavior( behaviorName ) == false ) + { + + std::string behaviorClass = behaviorSerial["className"].asString(); + std::string behaviorType = behaviorSerial["configName"].asString(); + + if( behaviorType == "SwarmBehavior" ) + { + std::string inputAgentParameterString = behaviorSerial["inputAgentParameters"].asString(); + std::string outputAgentParameterString = behaviorSerial["outputAgentParameters"].asString(); + std::string inputSwarmParameterString = behaviorSerial["inputSwarmParameters"].asString(); + std::string outputSwarmParameterString = behaviorSerial["outputSwarmParameters"].asString(); + + //std::cout << "swarmBehaviorMapSize: " << mSwarmBehaviorMap.size() << "\n"; + //std::cout << "behaviorMapSize: " << mBehaviorMap.size() << "\n"; + + //std::cout << "behaviorClass " << behaviorClass.toStdString() << " behavior " << mSwarmBehaviorMap.value( behaviorClass ) << "\n"; + + //std::cout << "behavior className " << mSwarmBehaviorMap.value( behaviorClass )->className().toStdString() << "\n"; + + if(mBehaviorMap.find(behaviorClass) == mBehaviorMap.end()) throw Exception("FLOCK ERROR: behavior class " + behaviorClass + " cannot be deserialized", __FILE__, __FUNCTION__, __LINE__); + + Behavior* behavior = mSwarmBehaviorMap[behaviorClass]->create( inputSwarmParameterString, inputAgentParameterString, outputSwarmParameterString, outputAgentParameterString ); + + swarm->addSwarmBehavior( behaviorName, *behavior ); + + delete behavior; + + } + else + { + std::string inputParameterString = behaviorSerial["inputParameters"].asString(); + std::string outputParameterString = behaviorSerial["outputParameters"].asString(); + + if(mBehaviorMap.find(behaviorClass) == mBehaviorMap.end()) throw Exception("FLOCK ERROR: behavior class " + behaviorClass + " cannot be deserialized", __FILE__, __FUNCTION__, __LINE__); + + Behavior* behavior = mBehaviorMap[behaviorClass]->create( inputParameterString, outputParameterString ); + + swarm->addSwarmBehavior( behaviorName, *behavior ); + + delete behavior; + } + } + } + } + + if( swarmSerial.isMember("AgentBehaviors") == true ) + { + + // *************** + // Agent behaviors + // *************** + + const Json::Value& agentBehaviorsSerialData = swarmSerial["AgentBehaviors"]; + unsigned int agentBehaviorCount = agentBehaviorsSerialData.size(); + + for( int abI =0; abI < agentBehaviorCount; ++abI ) + { + const Json::Value& behaviorSerial = agentBehaviorsSerialData[abI]; + + std::string behaviorName = behaviorSerial["name"].asString(); + + if( static_cast(swarm)->checkBehavior(behaviorName) == false ) + { + + std::string behaviorClass = behaviorSerial["className"].asString(); + std::string inputParameterString = behaviorSerial["inputParameters"].asString(); + std::string outputParameterString = behaviorSerial["outputParameters"].asString(); + + if(mBehaviorMap.find(behaviorClass) == mBehaviorMap.end()) throw Exception("FLOCK ERROR: behavior class " + behaviorClass + " cannot be deserialized", __FILE__, __FUNCTION__, __LINE__); + + Behavior* behavior = mBehaviorMap[behaviorClass]->create( inputParameterString, outputParameterString ); + + swarm->addBehavior( behaviorName, *behavior ); + + delete behavior; + } + } + } + + swarm->addAgents( agentCount ); + } + } + + //std::cout << "SerializeTools::deSerializeSwarms( serialize::SerializeData& pSerializeData ) end\n"; + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: failed to deserialize swarms", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +SerializeTools::deSerializeVis( const Json::Value& pSerializeData ) throw (Exception) +{ + try + { + //std::cout << "SerializeTools::deSerializeVis( serialize::SerializeData& pSerializeData ) begin\n"; + + if( pSerializeData.isMember("Visual") == true ) + { + FlockVisuals& flockVisuals = FlockVisuals::get(); + + const Json::Value& visSerializeData = pSerializeData["Visual"]; + + //***************** + // Display Settings + //***************** + + //std::cout << "set display settings begin\n"; + + unsigned int dim; + + glm::vec3 displayPosition; + glm::quat displayOrientation; + + getValues(visSerializeData, "displayPosition", displayPosition); + getValues(visSerializeData, "displayOrientation", displayOrientation); + + float displayZoom = visSerializeData["displayZoom"].asFloat(); + + std::array displayColor; + + getValues(visSerializeData, "displayColor", displayColor); + + flockVisuals.setDisplayPosition( displayPosition ); + flockVisuals.setDisplayOrientation( displayOrientation ); + flockVisuals.setDisplayZoom( displayZoom ); + flockVisuals.setDisplayColor( displayColor ); + + //std::cout << "set display settings end\n"; + + if( visSerializeData.isMember("VisualSwarms") == true ) + { + //************** + // Visual Swarms + //************** + + //std::cout << "show swarms begin\n"; + + const Json::Value& visSwarmsSerializeData = visSerializeData["VisualSwarms"]; + unsigned int visSwarmCount = visSwarmsSerializeData.size(); + + for( int vsI =0; vsI < visSwarmCount; ++vsI ) + { + const Json::Value& visSwarmSerial = visSwarmsSerializeData[vsI]; + + std::string swarmName = visSwarmSerial["swarmName"].asString(); + std::string posParName = visSwarmSerial["posParName"].asString(); + std::string velParName = visSwarmSerial["velParName"].asString(); + + std::array agentColor; + glm::vec3 agentScale; + + getValues(visSwarmSerial, "agentColor", agentColor); + getValues(visSwarmSerial, "agentScale", agentScale); + + float agentLineWidth = visSwarmSerial["agentLineWidth"].asFloat(); + + std::array trailColor; + + getValues(visSwarmSerial, "trailColor", trailColor); + + unsigned int trailLength = visSwarmSerial["trailLength"].asUInt(); + float trailWidth = visSwarmSerial["trailWidth"].asFloat(); + float trailDecay = visSwarmSerial["trailDecay"].asFloat(); + + //std::cout << "show swarm " << swarmName.toStdString() << " begin\n"; + + //const std::string& pSwarmName, const std::string& pPosParName, const std::string& pVelParName, unsigned int pMaxTrailLength + + flockVisuals.showSwarm( swarmName, posParName, velParName ); + + VisSwarm* visSwarm = flockVisuals.visualSwarm(swarmName); + + visSwarm->setAgentColor(agentColor); + visSwarm->setAgentScale(agentScale); + visSwarm->setAgentLineWidth(agentLineWidth); + visSwarm->setTrailColor(trailColor); + visSwarm->setTrailLength(trailLength); + visSwarm->setTrailWidth(trailWidth); + visSwarm->setTrailDecay(trailDecay); + + //std::cout << "show swarm " << swarmName.toStdString() << " end\n"; + } + + //std::cout << "show swarms end\n"; + } + + if( visSerializeData.isMember("VisualNeighbors") == true ) + { + //***************** + // Visual Neighbors + //***************** + + const Json::Value& visNeighborsSerializeData = visSerializeData["VisualNeighbors"]; + unsigned int visNeighborCount = visNeighborsSerializeData.size(); + + for( int vnI =0; vnI < visNeighborCount; ++vnI ) + { + const Json::Value& visNeighborSerial = visNeighborsSerializeData[vnI]; + + std::string spaceName = visNeighborSerial["spaceName"].asString(); + std::array spaceColor; + + getValues(visNeighborSerial, "spaceColor", spaceColor); + + float lineWidth = visNeighborSerial["lineWidth"].asFloat(); + + flockVisuals.showSpace(spaceName); + flockVisuals.setSpaceColor(spaceName, spaceColor); + flockVisuals.setSpaceLineWidth(spaceName, lineWidth); + } + } + + if( visSerializeData.isMember("VisualGrids") == true ) + { + //************* + // Visual Grids + //************* + + const Json::Value visGridsSerializeData = visSerializeData["VisualGrids"]; + unsigned int visGridCount = visGridsSerializeData.size(); + + for( int vgI =0; vgI < visGridCount; ++vgI ) + { + const Json::Value& visGridSerial = visGridsSerializeData[vgI]; + + std::string spaceName = visGridSerial["spaceName"].asString(); + std::array spaceColor; + getValues(visGridSerial, "spaceColor", spaceColor); + float valueScale = visGridSerial["valueScale"].asFloat(); + float lineWidth = visGridSerial["lineWidth"].asFloat(); + + flockVisuals.showSpace(spaceName, spaceColor, valueScale); + flockVisuals.setSpaceLineWidth(spaceName, lineWidth); + } + } + } + + //std::cout << "SerializeTools::deSerializeVis( serialize::SerializeData& pSerializeData ) end\n"; + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: failed to deserialize visualization", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +SerializeTools::deSerializeValues( const Json::Value& pSerializeData ) throw (Exception) +{ + try + { + //std::cout << "SerializeTools::deSerializeValues() begin\n"; + + Simulation& simulation = Simulation::get(); + + // ****** + // Swarms + // ****** + + if( pSerializeData.isMember("Swarms") == true ) + { + const Json::Value& swarmsSerialData = pSerializeData["Swarms"]; + unsigned int swarmCount = swarmsSerialData.size(); + + // std::cout << "swarmCount " << swarmCount << "\n"; + + for(int sI=0; sIagentCount() << " values agentCount " << agentCount << "\n"; + + if( swarm->agentCount() < agentCount ) swarm->addAgents( agentCount - swarm->agentCount() ); + else if( swarm->agentCount() > agentCount ) swarm->removeAgents( swarm->agentCount() - agentCount ); + + //***************** + // Swarm Parameters + //***************** + + if( swarmSerialData.isMember("SwarmParameters") ) + { + const Json::Value& swarmParametersSerialData = swarmSerialData["SwarmParameters"]; + int swarmParameterCount = swarmParametersSerialData.size(); + + for(int spI=0; spIcheckSwarmParameter(swarmParameterName) == true ) + { + Eigen::VectorXf swarmParameterValues; + getValues(swarmParameterSerialData, "values", swarmParameterValues); + swarm->set( swarmParameterName, swarmParameterValues ); + } + } + } + + //***************** + // Agent Parameters + //***************** + + if( swarmSerialData.isMember("AgentParameters") ) + { + const Json::Value& agentParametersSerialData = swarmSerialData["AgentParameters"]; + int agentParameterCount = agentParametersSerialData.size(); + + for(int apI=0; apIcheckParameter(agentParameterName) == true ) + { + Eigen::VectorXf agentParameterValues; + getValues(agentParameterSerialData, "values", agentParameterValues); + + swarm->set( agentParameterName, agentParameterValues ); + } + + if( agentParameterSerialData.isMember("value0") ) + { + for(unsigned int aI=0; aI < agentCount; ++aI) + { + Eigen::VectorXf agentParameterValues; + getValues(agentParameterSerialData, "value" + std::to_string(aI), agentParameterValues); + + swarm->set( aI, agentParameterName, agentParameterValues ); + + // std::cout << "set agentNr " << aI << " values " << math::Vector( agentParameterDim, agentParameterValues ) << "\n"; + } + + } + } + } + } + } + + + // **** + // Envs + // **** + + // TODO: untested!! + + if( pSerializeData.isMember("Envs") == true ) + { + const Json::Value& envsSerialData = pSerializeData["Envs"].asString(); + unsigned int envCount = envsSerialData.size(); + + //std::cout << "envCount " << envCount << "\n"; + + for(int eI=0; eIcheckParameter(envParameterName) == true ) + { + if( envParameterType == "Parameter" ) + { + Eigen::VectorXf envParameterValues; + getValues(envParameterSerialData, "values", envParameterValues); + + env->set( envParameterName, envParameterValues ); + + //std::cout << "set values " << math::Vector( envParameterDim, envParameterValues ) << "\n"; + } + else if( envParameterType == "EnvParameter" ) + { + unsigned int envParameterValueDim = envParameterSerialData["valueDim"].asUInt(); + dab::Array gridSize; + getValues(envParameterSerialData, "gridSize", gridSize); + + math::VectorField envParameterField( gridSize, Eigen::VectorXf(envParameterValueDim) ); + + unsigned int envParameterVectorCount = envParameterField.vectorCount(); + std::vector& envParameterVectors = envParameterField.vectors(); + + for(unsigned int pvI=0; pvIset( envParameterName, envParameterField ); + } + } + } + } + } + } + + //std::cout << "SerializeTools::deSerializeValues() end\n"; + } + catch (Exception& e) + { + e += Exception("FLOCK ERROR: failed to deserialize values", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + + +const Json::Value& +SerializeTools::getValue( const Json::Value& pValue, const std::string& pValueName ) throw (Exception) +{ + if(pValue.isMember(pValueName) == false) throw Exception("JSON ERROR: Value does not contain value name: " + pValueName, __FILE__, __FUNCTION__, __LINE__ ); + + return pValue[pValueName]; +} + +int +SerializeTools::getInt( const Json::Value& pValue, const std::string& pValueName ) throw (Exception) +{ + if(pValue.isMember(pValueName) == false) throw Exception("JSON ERROR: Value does not contain value name: " + pValueName, __FILE__, __FUNCTION__, __LINE__ ); + if(pValue[pValueName].isInt() == false) throw Exception("JSON ERROR: value name " + pValueName + " is not an integer", __FILE__, __FUNCTION__, __LINE__ ); + + return pValue[pValueName].asInt(); +} + +float +SerializeTools::getFloat( const Json::Value& pValue, const std::string& pValueName ) throw (Exception) +{ + if(pValue.isMember(pValueName) == false) throw Exception("JSON ERROR: Value does not contain value name: " + pValueName, __FILE__, __FUNCTION__, __LINE__ ); + if(pValue[pValueName].isDouble() == false) throw Exception("JSON ERROR: value name " + pValueName + " is not a float", __FILE__, __FUNCTION__, __LINE__ ); + + return pValue[pValueName].asFloat(); +} + +std::string +SerializeTools::getString( const Json::Value& pValue, const std::string& pValueName ) throw (Exception) +{ + if(pValue.isMember(pValueName) == false) throw Exception("JSON ERROR: Value does not contain value name: " + pValueName, __FILE__, __FUNCTION__, __LINE__ ); + if(pValue[pValueName].isString() == false) throw Exception("JSON ERROR: value name " + pValueName + " is not a float", __FILE__, __FUNCTION__, __LINE__ ); + + return pValue[pValueName].asString(); +} + +const Json::Value& +SerializeTools::getValue( const Json::Value& pValue, int pValueIndex ) throw (Exception) +{ + if(pValue.size() <= pValueIndex) throw Exception("JSON ERROR: value index " + std::to_string(pValueIndex) + " exceeds size " + std::to_string(pValue.size()), __FILE__, __FUNCTION__, __LINE__ ); + + return pValue[pValueIndex]; +} + +int +SerializeTools::getInt( const Json::Value& pValue, unsigned int pValueIndex ) throw (Exception) +{ + if(pValue.size() <= pValueIndex) throw Exception("JSON ERROR: value index " + std::to_string(pValueIndex) + " exceeds size " + std::to_string(pValue.size()), __FILE__, __FUNCTION__, __LINE__ ); + if(pValue[pValueIndex].isInt() == false) throw Exception("JSON ERROR: value at index " + std::to_string(pValueIndex) + " is not an integer", __FILE__, __FUNCTION__, __LINE__ ); + + return pValue[pValueIndex].asInt(); +} + +float +SerializeTools::getFloat( const Json::Value& pValue, unsigned int pValueIndex ) throw (Exception) +{ + if(pValue.size() <= pValueIndex) throw Exception("JSON ERROR: value index " + std::to_string(pValueIndex) + " exceeds size " + std::to_string(pValue.size()), __FILE__, __FUNCTION__, __LINE__ ); + if(pValue[pValueIndex].isDouble() == false) throw Exception("JSON ERROR: value at index " + std::to_string(pValueIndex) + " is not a float", __FILE__, __FUNCTION__, __LINE__ ); + + return pValue[pValueIndex].asFloat(); +} + +std::string +SerializeTools::getString( const Json::Value& pValue, unsigned int pValueIndex ) throw (Exception) +{ + if(pValue.size() <= pValueIndex) throw Exception("JSON ERROR: value index " + std::to_string(pValueIndex) + " exceeds size " + std::to_string(pValue.size()), __FILE__, __FUNCTION__, __LINE__ ); + if(pValue[pValueIndex].isString() == false) throw Exception("JSON ERROR: value at index " + std::to_string(pValueIndex) + " is not a string", __FILE__, __FUNCTION__, __LINE__ ); + + return pValue[pValueIndex].asString(); +} + + +const Json::Value& +SerializeTools::getValue( const Json::Value& pValue, const std::string& pValueName, int pValueIndex ) throw (Exception) +{ + if(pValue.isMember(pValueName) == false) throw Exception("JSON ERROR: Value does not contain value name: " + pValueName, __FILE__, __FUNCTION__, __LINE__ ); + if(pValue[pValueName].size() <= pValueIndex) throw Exception("JSON ERROR: value index " + std::to_string(pValueIndex) + " exceeds size " + std::to_string(pValue[pValueName].size()) + " of value name: " + pValueName + " ", __FILE__, __FUNCTION__, __LINE__ ); + + return pValue[pValueName][pValueIndex]; +} + +int +SerializeTools::getInt( const Json::Value& pValue, const std::string& pValueName, unsigned int pValueIndex ) throw (Exception) +{ + if(pValue.isMember(pValueName) == false) throw Exception("JSON ERROR: Value does not contain value name: " + pValueName, __FILE__, __FUNCTION__, __LINE__ ); + if(pValue[pValueName].size() <= pValueIndex) throw Exception("JSON ERROR: value index " + std::to_string(pValueIndex) + " exceeds size " + std::to_string(pValue[pValueName].size()) + " of value name: " + pValueName + " ", __FILE__, __FUNCTION__, __LINE__ ); + if(pValue[pValueName][pValueIndex].isInt() == false) throw Exception("JSON ERROR: value name " + pValueName + " at index " + std::to_string(pValueIndex) + " is not an integer", __FILE__, __FUNCTION__, __LINE__ ); + + return pValue[pValueName][pValueIndex].asInt(); +} + +float +SerializeTools::getFloat( const Json::Value& pValue, const std::string& pValueName, unsigned int pValueIndex ) throw (Exception) +{ + if(pValue.isMember(pValueName) == false) throw Exception("JSON ERROR: Value does not contain value name: " + pValueName, __FILE__, __FUNCTION__, __LINE__ ); + if(pValue[pValueName].size() <= pValueIndex) throw Exception("JSON ERROR: value index " + std::to_string(pValueIndex) + " exceeds size " + std::to_string(pValue[pValueName].size()) + " of value name: " + pValueName + " ", __FILE__, __FUNCTION__, __LINE__ ); + if(pValue[pValueName][pValueIndex].isDouble() == false) throw Exception("JSON ERROR: value name " + pValueName + " at index " + std::to_string(pValueIndex) + " is not a float", __FILE__, __FUNCTION__, __LINE__ ); + + return pValue[pValueName][pValueIndex].asFloat(); +} + +std::string +SerializeTools::getString( const Json::Value& pValue, const std::string& pValueName, unsigned int pValueIndex ) throw (Exception) +{ + if(pValue.isMember(pValueName) == false) throw Exception("JSON ERROR: Value does not contain value name: " + pValueName, __FILE__, __FUNCTION__, __LINE__ ); + if(pValue[pValueName].size() <= pValueIndex) throw Exception("JSON ERROR: value index " + std::to_string(pValueIndex) + " exceeds size " + std::to_string(pValue[pValueName].size()) + " of value name: " + pValueName + " ", __FILE__, __FUNCTION__, __LINE__ ); + if(pValue[pValueName][pValueIndex].isString() == false) throw Exception("JSON ERROR: value name " + pValueName + " at index " + std::to_string(pValueIndex) + " is not a string", __FILE__, __FUNCTION__, __LINE__ ); + + return pValue[pValueName][pValueIndex].asString(); +} + +Json::Value +SerializeTools::addValues(const Eigen::VectorXf& pValues) +{ + Json::Value valueData; + + int valueDim = pValues.rows(); + for(int d=0; d& pValues ) throw (Exception) +{ + if( pData.isMember(pName) == false ) throw Exception("FLOCK ERROR: no data with name " + pName + " found", __FILE__, __FUNCTION__, __LINE__); + + const Json::Value& data = pData[pName]; + int dataDim = data.size(); + + if(dataDim != 2) throw Exception("FLOCK ERROR: data dimension " + std::to_string(dataDim) + " must equal 2", __FILE__, __FUNCTION__, __LINE__); + + for(int d=0; d& pValues ) throw (Exception) +{ + if( pData.isMember(pName) == false ) throw Exception("FLOCK ERROR: no data with name " + pName + " found", __FILE__, __FUNCTION__, __LINE__); + + const Json::Value& data = pData[pName]; + int dataDim = data.size(); + + if(dataDim != 4) throw Exception("FLOCK ERROR: data dimension " + std::to_string(dataDim) + " must equal 4", __FILE__, __FUNCTION__, __LINE__); + + for(int d=0; d +#include +#include +#include +#include "ofVectorMath.h" +#include "ofxJSON.h" +#include "dab_singleton.h" +#include "dab_exception.h" +#include "dab_array.h" + +namespace dab +{ + +namespace flock +{ + +class Behavior; +class SwarmBehavior; + +class SerializeTools : public Singleton +{ +public: + friend class Singleton; + + enum SerializeMode + { + ConfigMode, + ValuesMode, + AllMode + }; + + + void save( const std::string& pFileName, SerializeMode pMode = AllMode ) throw (Exception); + void restore( const std::string& pFileName, SerializeMode pMode = AllMode ) throw (Exception); + +protected: + std::map< std::string, Behavior* > mBehaviorMap; + std::map< std::string, SwarmBehavior* > mSwarmBehaviorMap; + + SerializeTools(); + ~SerializeTools(); + + void createBehaviorMap(); + void registerBehavior(Behavior* pBehavior); + + void saveConfig( Json::Value& pSerializeData ) throw (Exception); + void restoreConfig( const Json::Value& pSerializeData ) throw (Exception); + + void saveValues( Json::Value& pSerializeData ) throw (Exception); + void restoreValues( const Json::Value& pSerializeData ) throw (Exception); + + void serializeSim( Json::Value& pSerializeData ) throw (Exception); + void serializeCom( Json::Value& pSerializeData ) throw (Exception); + void serializeSpace( Json::Value& pSerializeData ) throw (Exception); + void serializeSwarms( Json::Value& pSerializeData ) throw (Exception); + void serializeVis( Json::Value& pSerializeData ) throw (Exception); + void serializeValues( Json::Value& pSerializeData ) throw (Exception); + + void deSerializeSim( const Json::Value& pSerializeData ) throw (Exception); + void deSerializeCom( const Json::Value& pSerializeData ) throw (Exception); + void deSerializeSpace( const Json::Value& pSerializeData ) throw (Exception); + void deSerializeSwarms( const Json::Value& pSerializeData ) throw (Exception); + void deSerializeVis( const Json::Value& pSerializeData ) throw (Exception); + void deSerializeValues( const Json::Value& pSerializeData ) throw (Exception); + + const Json::Value& getValue( const Json::Value& pValue, const std::string& pValueName ) throw (Exception); + int getInt( const Json::Value& pValue, const std::string& pValueName ) throw (dab::Exception); + float getFloat( const Json::Value& pValue, const std::string& pValueName ) throw (dab::Exception); + std::string getString( const Json::Value& pValue, const std::string& pValueName ) throw (dab::Exception); + + const Json::Value& getValue( const Json::Value& pValue, int pValueIndex ) throw (dab::Exception); + int getInt( const Json::Value& pValue, unsigned int pValueIndex ) throw (dab::Exception); + float getFloat( const Json::Value& pValue, unsigned int pValueIndex ) throw (dab::Exception); + std::string getString( const Json::Value& pValue, unsigned int pValueIndex ) throw (dab::Exception); + + const Json::Value& getValue( const Json::Value& pValue, const std::string& pValueName, int pValueIndex ) throw (dab::Exception); + int getInt( const Json::Value& pValue, const std::string& pValueName, unsigned int pValueIndex ) throw (dab::Exception); + float getFloat( const Json::Value& pValue, const std::string& pValueName, unsigned int pValueIndex ) throw (dab::Exception); + std::string getString( const Json::Value& pValue, const std::string& pValueName, unsigned int pValueIndex ) throw (dab::Exception); + + Json::Value addValues(const Eigen::VectorXf& pValues); + Json::Value addValues(const glm::vec3& pValues); + Json::Value addValues(const glm::quat& pValues); + template Json::Value addValues(const Array& pValues); + template Json::Value addValues(const std::array& pValues); + + void getValues(const Json::Value& pData, const std::string& pName, Eigen::VectorXf& pValues ) throw (Exception); + void getValues(const Json::Value& pData, const std::string& pName, std::array& pValues ) throw (Exception); + void getValues(const Json::Value& pData, const std::string& pName, std::array& pValues ) throw (Exception); + void getValues(const Json::Value& pData, const std::string& pName, glm::vec3& pValues ) throw (Exception); + void getValues(const Json::Value& pData, const std::string& pName, glm::quat& pValues ) throw (Exception); + template void getValues(const Json::Value& pData, const std::string& pName, dab::Array& pValues ) throw (Exception); +}; + +template +Json::Value +SerializeTools::addValues(const Array& pValues) +{ + Json::Value valueData; + + int valueDim = pValues.size(); + for(int d=0; d +Json::Value +SerializeTools::addValues(const std::array& pValues) +{ + Json::Value valueData; + + int valueDim = pValues.size(); + for(int d=0; d +void +SerializeTools::getValues(const Json::Value& pData, const std::string& pName, dab::Array& pValues ) throw (Exception) +{ + throw Exception("FLOCK ERROR: unsupported data type", __FILE__, __FUNCTION__, __LINE__); +} + +}; + +}; + +#endif diff --git a/src/dab_flock_set_parameter_event.cpp b/src/dab_flock_set_parameter_event.cpp new file mode 100644 index 0000000..18474ce --- /dev/null +++ b/src/dab_flock_set_parameter_event.cpp @@ -0,0 +1,359 @@ +/** \file dab_flock_set_parameter_event.cpp + */ + +#include "dab_flock_set_parameter_event.h" +#include "dab_flock_env.h" +#include "dab_math.h" + +using namespace dab; +using namespace dab::flock; + +SetParameterEvent::SetParameterEvent( const std::string& pSwarmName, const std::string& pParameterName, const Eigen::VectorXf& pParameterValues, double pDuration) +: event::Event(0.0, pDuration, event::RelativeTime) +, mSwarmName(pSwarmName) +, mParameterName(pParameterName) +, mAgentRangeStartIndex(-1) +, mAgentRangeEndIndex(-1) +, mParameterValues(pParameterValues) +, mParameterValues2(pParameterValues) +, mUpdatedParameterValues( mParameterValues.rows() ) +, mRandomize(false) +{} + +SetParameterEvent::SetParameterEvent(const std::string& pSwarmName, const std::string& pParameterName, int pAgentIndex, const Eigen::VectorXf& pParameterValues, double pDuration) +: event::Event(0.0, pDuration, event::RelativeTime) +, mSwarmName(pSwarmName) +, mParameterName(pParameterName) +, mAgentRangeStartIndex(pAgentIndex) +, mAgentRangeEndIndex(pAgentIndex) +, mParameterValues(pParameterValues) +, mParameterValues2(pParameterValues) +, mUpdatedParameterValues( mParameterValues.rows() ) +, mRandomize(false) +{} + +SetParameterEvent::SetParameterEvent( const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const Eigen::VectorXf& pParameterValues, double pDuration) +: event::Event(0.0, pDuration, event::RelativeTime) +, mSwarmName(pSwarmName) +, mParameterName(pParameterName) +, mAgentRangeStartIndex( pAgentRange[0] ) +, mAgentRangeEndIndex( pAgentRange[1] ) +, mParameterValues(pParameterValues) +, mParameterValues2(pParameterValues) +, mUpdatedParameterValues( mParameterValues.rows() ) +, mRandomize(false) +{} + +SetParameterEvent::SetParameterEvent(double pTime, const std::string& pSwarmName, const std::string& pParameterName, const Eigen::VectorXf& pParameterValues, double pDuration) +: event::Event(pTime, pDuration, event::RelativeTime) +, mSwarmName(pSwarmName) +, mParameterName(pParameterName) +, mAgentRangeStartIndex(-1) +, mAgentRangeEndIndex(-1) +, mParameterValues(pParameterValues) +, mParameterValues2(pParameterValues) +, mUpdatedParameterValues( mParameterValues.rows() ) +, mRandomize(false) +{} + +SetParameterEvent::SetParameterEvent(double pTime, const std::string& pSwarmName, const std::string& pParameterName, int pAgentIndex, const Eigen::VectorXf& pParameterValues, double pDuration) +: event::Event(pTime, pDuration, event::RelativeTime) +, mSwarmName(pSwarmName) +, mParameterName(pParameterName) +, mAgentRangeStartIndex(pAgentIndex) +, mAgentRangeEndIndex(pAgentIndex) +, mParameterValues(pParameterValues) +, mParameterValues2(pParameterValues) +, mUpdatedParameterValues( mParameterValues.rows() ) +, mRandomize(false) +{} + +SetParameterEvent::SetParameterEvent(double pTime, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const Eigen::VectorXf& pParameterValues, double pDuration) +: event::Event(pTime, pDuration, event::RelativeTime) +, mSwarmName(pSwarmName) +, mParameterName(pParameterName) +, mAgentRangeStartIndex( pAgentRange[0] ) +, mAgentRangeEndIndex( pAgentRange[1] ) +, mParameterValues(pParameterValues) +, mParameterValues2(pParameterValues) +, mUpdatedParameterValues( mParameterValues.rows() ) +, mRandomize(false) +{} + +SetParameterEvent::SetParameterEvent( const std::string& pSwarmName, const std::string& pParameterName, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mParameterName(pParameterName) +, mAgentRangeStartIndex(-1) +, mAgentRangeEndIndex(-1) +, mParameterValues(pMinParameterValues) +, mParameterValues2(pMaxParameterValues) +, mUpdatedParameterValues( mParameterValues.rows() ) +, mRandomize(true) +{} + +SetParameterEvent::SetParameterEvent( const std::string& pSwarmName, const std::string& pParameterName, int pAgentIndex, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mParameterName(pParameterName) +, mAgentRangeStartIndex(pAgentIndex) +, mAgentRangeEndIndex(pAgentIndex) +, mParameterValues(pMinParameterValues) +, mParameterValues2(pMaxParameterValues) +, mUpdatedParameterValues( mParameterValues.rows() ) +, mRandomize(true) +{} + +SetParameterEvent::SetParameterEvent(const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mParameterName(pParameterName) +, mAgentRangeStartIndex( pAgentRange[0] ) +, mAgentRangeEndIndex( pAgentRange[1] ) +, mParameterValues(pMinParameterValues) +, mParameterValues2(pMaxParameterValues) +, mUpdatedParameterValues( mParameterValues.rows() ) +, mRandomize(true) +{} + +SetParameterEvent::SetParameterEvent(double pTime, const std::string& pSwarmName, const std::string& pParameterName, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues) +: event::Event(pTime, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mParameterName(pParameterName) +, mAgentRangeStartIndex(-1) +, mAgentRangeEndIndex(-1) +, mParameterValues(pMinParameterValues) +, mParameterValues2(pMaxParameterValues) +, mUpdatedParameterValues( mParameterValues.rows() ) +, mRandomize(true) +{} + +SetParameterEvent::SetParameterEvent(double pTime, const std::string& pSwarmName, const std::string& pParameterName, int pAgentIndex, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues) +: event::Event(pTime, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mParameterName(pParameterName) +, mAgentRangeStartIndex(pAgentIndex) +, mAgentRangeEndIndex(pAgentIndex) +, mParameterValues(pMinParameterValues) +, mParameterValues2(pMaxParameterValues) +, mUpdatedParameterValues( mParameterValues.rows() ) +, mRandomize(true) +{} + +SetParameterEvent::SetParameterEvent(double pTime, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues) +: event::Event(pTime, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mParameterName(pParameterName) +, mAgentRangeStartIndex( pAgentRange[0] ) +, mAgentRangeEndIndex( pAgentRange[1] ) +, mParameterValues(pMinParameterValues) +, mParameterValues2(pMaxParameterValues) +, mUpdatedParameterValues( mParameterValues.rows() ) +, mRandomize(true) +{} + +SetParameterEvent::SetParameterEvent( const SetParameterEvent& pEvent ) +: event::Event( pEvent ) +, mSwarmName( pEvent.mSwarmName ) +, mParameterName( pEvent.mParameterName ) +, mAgentRangeStartIndex( pEvent.mAgentRangeStartIndex ) +, mAgentRangeEndIndex( pEvent.mAgentRangeEndIndex ) +, mParameterValues( pEvent.mParameterValues ) +, mParameterValues2( pEvent.mParameterValues2 ) +, mUpdatedParameterValues( mParameterValues.rows() ) +, mRandomize( pEvent.mRandomize ) +{} + +SetParameterEvent::SetParameterEvent( double pTime, const SetParameterEvent& pEvent ) +: event::Event( pTime, pEvent ) +, mSwarmName( pEvent.mSwarmName ) +, mParameterName( pEvent.mParameterName ) +, mAgentRangeStartIndex( pEvent.mAgentRangeStartIndex ) +, mAgentRangeEndIndex( pEvent.mAgentRangeEndIndex ) +, mParameterValues( pEvent.mParameterValues ) +, mParameterValues2( pEvent.mParameterValues2 ) +, mUpdatedParameterValues( mParameterValues.rows() ) +, mRandomize( pEvent.mRandomize ) +{} + +SetParameterEvent::~SetParameterEvent() +{} + +event::Event* +SetParameterEvent::copy() const +{ + return new SetParameterEvent( *this ); +} + +event::Event* +SetParameterEvent::copy( double pTime ) const +{ + return new SetParameterEvent( pTime, *this ); +} + +void +SetParameterEvent::execute() throw (Exception) +{ + //std::cout << "SetParameterEvent::execute()\n"; + + mFinished = false; + + try + { + if( mStarted == true && mRemainingDuration <= 0.0 && mFinished == true ) + { + return; + } + + mPreviousEventTime = mCurrentEventTime; + mCurrentEventTime = ofGetElapsedTimef(); + if( mStarted == true ) mEventInterval = mCurrentEventTime - mPreviousEventTime; + else mEventInterval = FLT_MIN; + + if( mStarted == false ) + { + mStartTime = mTime; + mStarted = true; + } + + double stepCount = 1.0; + double invStepCount = 1.0; + + mRemainingDuration = ( mStartTime + mDuration ) - mCurrentEventTime; + mRemainingDuration -= mEventInterval; // safety: be one step ahead so we rather finish an event with duration early than later + + if( mRemainingDuration > 0.0 ) + { + stepCount = mRemainingDuration / mEventInterval; + invStepCount = 1.0 / stepCount; + } + + // simple version of parameter set for env + if( Simulation::get().checkEnv(mSwarmName) == true ) + { + Env* env = Simulation::get().env( mSwarmName ); + env->set( mParameterName, mParameterValues ); + mFinished = true; + + return; + }; + // env done + + + Swarm* swarm = Simulation::get().swarm(mSwarmName); + std::vector& agents = swarm->agents(); + + /////////////////////////////// + // set swarm parameter value // + /////////////////////////////// + + if(mAgentRangeStartIndex == -1 && mAgentRangeEndIndex == -1) + { + if( mRemainingDuration > 0.0 ) + { + unsigned int valueDim = mParameterValues.rows(); + + Parameter* parameter = ( static_cast( swarm ) )->parameter(mParameterName); + Eigen::VectorXf& curParValues = parameter->values(); + + //std::cout << "curParValues " << curParValues << "\n"; + + for(int d=0; dsetValues(mUpdatedParameterValues); + } + else if( mRandomize == true ) + { + math::Math<>& math = math::Math<>::get(); + unsigned int valueDim = mParameterValues.rows(); + Eigen::VectorXf randomValues( valueDim ); + + for(int d=0; d( swarm ) )->parameter(mParameterName)->setValues(randomValues); + } + else + { + ( static_cast( swarm ) )->parameter(mParameterName)->setValues(mParameterValues); + } + } + + /////////////////////////////// + // set agent parameter value // + /////////////////////////////// + + if(agents.size() != 0) + { + unsigned int parameterIndex = agents[0]->parameterIndex(mParameterName); + int agentRangeStartIndex = mAgentRangeStartIndex; + int agentRangeEndIndex = mAgentRangeEndIndex; + + + if(agentRangeStartIndex == -1 || agentRangeStartIndex < 0) agentRangeStartIndex = 0; + if(agentRangeEndIndex == -1 || agentRangeEndIndex >= agents.size()) agentRangeEndIndex = agents.size() - 1; + + //std::cout << "set agent par from " << mAgentRangeStartIndex << " to " << mAgentRangeEndIndex << "\n"; + + if( mRemainingDuration > 0.0 ) + { + unsigned int valueDim = mParameterValues.rows(); + + for(int agentNr = agentRangeStartIndex; agentNr <= agentRangeEndIndex; ++agentNr) + { + Parameter* parameter = agents[agentNr]->parameter(parameterIndex); + Eigen::VectorXf& curParValues = parameter->values(); + + for(int d=0; dsetValues(mUpdatedParameterValues); + } + + //std::cout << "before: duration " << mDuration << " remainingDuration " << mRemainingDuration << "\n"; + //std::cout << "after: duration " << mDuration << " remainingDuration " << mRemainingDuration << "\n"; + } + else if( mRandomize == true ) + { + math::Math<>& math = math::Math<>::get(); + unsigned int valueDim = mParameterValues.rows(); + Eigen::VectorXf randomValues( valueDim ); + + for(int agentNr = agentRangeStartIndex; agentNr <= agentRangeEndIndex; ++agentNr) + { + for(int d=0; dparameter(parameterIndex)->setValues(randomValues); + + //std::cout << "set agent " << agents[agentNr]->name().toStdString() << " par " << agents[agentNr]->parameter(parameterIndex).name().toStdString() << " to " << randomValues << "\n"; + } + + mFinished = true; + } + else + { + for(int agentNr = agentRangeStartIndex; agentNr <= agentRangeEndIndex; ++agentNr) + { + agents[agentNr]->parameter(parameterIndex)->setValues(mParameterValues); + } + + mFinished = true; + + //std::cout << "planned finish time " << mStartTime + mDuration << " current finish time " << static_cast( base::Tools::get().time() ) * 0.001 << "\n"; + + } + } + } + catch(Exception& e) + { + Simulation::get().exceptionReport( e ); + + mStarted = false; + mFinished = true; + } +} \ No newline at end of file diff --git a/src/dab_flock_set_parameter_event.h b/src/dab_flock_set_parameter_event.h new file mode 100644 index 0000000..407ecd6 --- /dev/null +++ b/src/dab_flock_set_parameter_event.h @@ -0,0 +1,66 @@ +/** \file dab_flock_set_parameter_event.h + * + * Created by Daniel Bisig on 02/08/09. + * Ported to OpenFrameworks by Daniel Bisig on 11/10/2017. + */ + +#ifndef _dab_flock_set_parameter_event_h_ +#define _dab_flock_set_parameter_event_h_ + +#include +#include +#include "dab_flock_simulation.h" +#include "dab_flock_swarm.h" +#include "dab_event.h" + +namespace dab +{ + +namespace flock +{ + +class SetParameterEvent : public event::Event +{ +public: + SetParameterEvent( const std::string& pSwarmName, const std::string& pParameterName, const Eigen::VectorXf& pParameterValues, double pDuration = -1.0); + SetParameterEvent( const std::string& pSwarmName, const std::string& pParameterName, int pAgentIndex, const Eigen::VectorXf& pParameterValues, double pDuration = -1.0); + SetParameterEvent( const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const Eigen::VectorXf& pParameterValues, double pDuration = -1.0); + SetParameterEvent( double pTime, const std::string& pSwarmName, const std::string& pParameterName, const Eigen::VectorXf& pParameterValues, double pDuration = -1.0); + SetParameterEvent( double pTime, const std::string& pSwarmName, const std::string& pParameterName, int pAgentIndex, const Eigen::VectorXf& pParameterValues, double pDuration = -1.0); + SetParameterEvent( double pTime, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const Eigen::VectorXf& pParameterValues, double pDuration = -1.0); + SetParameterEvent( const std::string& pSwarmName, const std::string& pParameterName, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues); + SetParameterEvent( const std::string& pSwarmName, const std::string& pParameterName, int pAgentIndex, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues); + SetParameterEvent( const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues); + SetParameterEvent( double pTime, const std::string& pSwarmName, const std::string& pParameterName, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues); + SetParameterEvent( double pTime, const std::string& pSwarmName, const std::string& pParameterName, int pAgentIndex, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues); + SetParameterEvent( double pTime, const std::string& pSwarmName, const std::string& pParameterName, const std::array& pAgentRange, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues); + + SetParameterEvent( const SetParameterEvent& pEvent ); + SetParameterEvent( double pTime, const SetParameterEvent& pEvent ); + virtual ~SetParameterEvent(); + + event::Event* copy() const; + event::Event* copy( double pTime ) const; + void execute() throw (Exception); + +protected: + std::string mSwarmName; + std::string mParameterName; + int mAgentRangeStartIndex; + int mAgentRangeEndIndex; + Eigen::VectorXf mParameterValues; + Eigen::VectorXf mParameterValues2; + Eigen::VectorXf mUpdatedParameterValues; + float mStartTime; + float mRemainingDuration; + float mPreviousEventTime; + float mCurrentEventTime; + float mEventInterval; + bool mRandomize; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_set_simulation_rate_event.cpp b/src/dab_flock_set_simulation_rate_event.cpp new file mode 100644 index 0000000..5e713ff --- /dev/null +++ b/src/dab_flock_set_simulation_rate_event.cpp @@ -0,0 +1,62 @@ +/** \dab_flock_set_simulation_rate_event.cpp + */ + +#include "dab_flock_set_simulation_rate_event.h" +#include "dab_flock_simulation.h" + +using namespace dab; +using namespace dab::flock; + +SetSimulationRateEvent::SetSimulationRateEvent( float pSimulationRate ) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSimulationRate( pSimulationRate ) +{} + +SetSimulationRateEvent::SetSimulationRateEvent( double pTime, float pSimulationRate ) +: event::Event(pTime, -1.0, event::RelativeTime) +, mSimulationRate( pSimulationRate ) +{} + +SetSimulationRateEvent::SetSimulationRateEvent( const SetSimulationRateEvent& pEvent ) +: event::Event( pEvent ) +, mSimulationRate( pEvent.mSimulationRate ) +{} + +SetSimulationRateEvent::SetSimulationRateEvent( double pTime, const SetSimulationRateEvent& pEvent ) +: event::Event( pTime, pEvent ) +, mSimulationRate( pEvent.mSimulationRate ) +{} + +SetSimulationRateEvent::~SetSimulationRateEvent() +{} + +event::Event* +SetSimulationRateEvent::copy() const +{ + return new SetSimulationRateEvent( *this ); +} + +event::Event* +SetSimulationRateEvent::copy( double pTime ) const +{ + return new SetSimulationRateEvent( pTime, *this ); +} + +void +SetSimulationRateEvent::execute() throw (Exception) +{ + mStarted = true; + mFinished = false; + + try + { + Simulation::get().setUpdateInterval( mSimulationRate ); + } + catch( Exception& e ) + { + Simulation::get().exceptionReport( e ); + } + + mStarted = false; + mFinished = true; +} \ No newline at end of file diff --git a/src/dab_flock_set_simulation_rate_event.h b/src/dab_flock_set_simulation_rate_event.h new file mode 100644 index 0000000..f7d1a86 --- /dev/null +++ b/src/dab_flock_set_simulation_rate_event.h @@ -0,0 +1,40 @@ +/** dab_flock_set_simulation_rate_event.h + * + * Created by Daniel Bisig on 6/19/09. + * Ported to OpenFrameworks by Daniel Bisig on 24/10/2017. + * + */ + +#ifndef _dab_flock_set_simulation_rate_event_h_ +#define _dab_flock_set_simulation_rate_event_h_ + +#include "dab_event.h" + +namespace dab +{ + +namespace flock +{ + +class SetSimulationRateEvent : public event::Event +{ +public: + SetSimulationRateEvent( float pSimulationRate ); + SetSimulationRateEvent( double pTime, float pSimulationRate); + SetSimulationRateEvent( const SetSimulationRateEvent& pEvent ); + SetSimulationRateEvent( double pTime, const SetSimulationRateEvent& pEvent ); + virtual ~SetSimulationRateEvent(); + + event::Event* copy() const; + event::Event* copy( double pTime ) const; + void execute() throw (Exception); + +protected: + float mSimulationRate; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_simulation.cpp b/src/dab_flock_simulation.cpp new file mode 100644 index 0000000..c796b49 --- /dev/null +++ b/src/dab_flock_simulation.cpp @@ -0,0 +1,427 @@ +/** \file dab_flock_simulation.cpp + */ + +#include "dab_flock_simulation.h" +#include "dab_flock_behavior.h" +#include "dab_flock_agent.h" +#include "dab_flock_swarm.h" +#include "dab_flock_env.h" +#include +#include +#include + +using namespace dab; +using namespace dab::flock; + +void +Simulation::setUpdateInterval(float pUpdateInterval) +{ + mUpdateInterval = pUpdateInterval; +} + +Simulation::Simulation() +: mUpdateInterval(10000) // 100 times per second +, mSimulationStep( 0 ) +, mTerminated(false) +, mEventManager() +, mPaused(false) +, mFrozen(false) +{ + mTime = ofGetElapsedTimeMillis(); +} + +Simulation::~Simulation() +{} + +long +Simulation::simulationStep() const +{ + return mSimulationStep; +} + +float +Simulation::updateRate() const +{ + return mUpdateRate; +} + +float +Simulation::updateInterval() const +{ + return mUpdateInterval; +} + +event::EventManager& +Simulation::event() +{ + return mEventManager; +} + +space::SpaceManager& +Simulation::space() +{ + return space::SpaceManager::get(); +} + +FlockCom& +Simulation::com() +{ + return FlockCom::get(); +} + +FlockStats& +Simulation::stats() +{ + return FlockStats::Singleton::get(); +} + +unsigned int +Simulation::agentCount() const +{ + return mAgents.size(); +} + +std::vector& +Simulation::agents() +{ + return mAgents; +} + +Agent* +Simulation::agent(unsigned int pIndex) throw (Exception) +{ + if(pIndex >= mAgents.size()) throw Exception( "FLOCK ERROR: agent index " + std::to_string(pIndex) + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + return mAgents[pIndex]; +} + +Agent* +Simulation::agent(std::string& pName) throw (Exception) +{ + unsigned int agentCount = mAgents.size(); + for(unsigned int i=0; iname() == pName) return mAgents[i]; + } + + throw Exception( "FLOCK ERROR: agent " + pName + " not found", __FILE__, __FUNCTION__, __LINE__ ); +} + +void +Simulation::addAgent(Agent* pAgent) +{ + mAgents.push_back(pAgent); + + // register all parameter of agent as event targets in the event manager + // ??? + unsigned int parameterCount = pAgent->parameterCount(); + + for(unsigned int parameterIndex = 0; parameterIndex < parameterCount; ++parameterIndex) + { + Parameter* parameter = pAgent->parameter(parameterIndex); + } +} + +void +Simulation::removeAgent(Agent* pAgent) +{ + int agentCount = mAgents.size(); + for(int i=agentCount-1; i>=0; --i) + { + if( mAgents[i] == pAgent ) mAgents.erase(mAgents.begin() + i); + } +} + +bool +Simulation::checkSwarm( std::string pName ) +{ + unsigned int swarmCount = mSwarms.size(); + for(unsigned int i=0; iname() == pName) return true; + } + + return false; +} + +std::vector& +Simulation::swarms() +{ + return mSwarms; +} + +Swarm* +Simulation::swarm(unsigned int pIndex) throw (Exception) +{ + if(pIndex >= mSwarms.size()) throw Exception( "FLOCK ERROR: swarm index " + std::to_string(pIndex) + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + return mSwarms[pIndex]; +} + +Swarm* +Simulation::swarm(std::string pName) throw (Exception) +{ + unsigned int swarmCount = mSwarms.size(); + for(unsigned int i=0; iname() == pName) return mSwarms[i]; + } + + throw Exception( "FLOCK ERROR: swarm " + pName + " not found", __FILE__, __FUNCTION__, __LINE__ ); +} + +void +Simulation::addSwarm(Swarm* pSwarm) +{ + mSwarms.push_back(pSwarm); +} + +void +Simulation::removeSwarm(Swarm* pSwarm) +{ + int swarmCount = mSwarms.size(); + for(int i=swarmCount-1; i>=0; --i) + { + if( mSwarms[i] == pSwarm ) mSwarms.erase(mSwarms.begin() + i); + } +} + +bool +Simulation::checkEnv( std::string pName ) +{ + unsigned int envCount = mEnvs.size(); + for(unsigned int i=0; iname() == pName) return true; + } + + return false; +} + +std::vector& +Simulation::envs() +{ + return mEnvs; +} + +Env* +Simulation::env(unsigned int pIndex) throw (Exception) +{ + if(pIndex >= mEnvs.size()) throw Exception( "FLOCK ERROR: environment index " + std::to_string(pIndex) + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + return mEnvs[pIndex]; +} + +Env* +Simulation::env(std::string pName) throw (Exception) +{ + unsigned int envCount = mEnvs.size(); + for(unsigned int i=0; iname() == pName) return mEnvs[i]; + } + + throw Exception( "FLOCK ERROR: environment " + pName + " not found", __FILE__, __FUNCTION__, __LINE__ ); +} + +void +Simulation::addEnv(Env* pEnv) +{ + mEnvs.push_back(pEnv); +} + +void +Simulation::removeEnv(Env* pEnv) +{ + int envCount = mEnvs.size(); + for(int i=envCount-1; i>=0; --i) + { + if( mEnvs[i] == pEnv ) mEnvs.erase(mEnvs.begin() + i); + } +} + +void +Simulation::clear() +{ + //std::cout << "Simulation::clear() begin\n"; + + mPaused = true; + + // hide swarms + //GLWindow::get().panel().hideSwarms(); + + // hide spaces + //GLWindow::get().panel().hideSpaces(); + + // remove swarms + int swarmCount = mSwarms.size(); + for(int sI=0; sIclear(); + } + mSwarms.clear(); + + // remove envs + int envCount = mEnvs.size(); + for(int eI=0; eIact(); + for(unsigned int i=0; iact(); + + //for(unsigned int i=0; iflush(); + for(unsigned int i=0; iflush(); + + FlockStats::Singleton::get().update(); + + //for(unsigned int i=0; iname().toStdString() << "\n"; + //std::cout << "mass " << mAgents[0]->parameter("mass").values() << " prefVel " << mAgents[0]->parameter("damping_prefVelocity").values() << "\n"; + + mSimulationStep++; + } + + //std::cout << "Simulation::update() end\n"; +} + +void +Simulation::notifyListeners() +{ + UpdateNotifier::update(); + + int listenerCount = mListeners.size(); + + for(int lI=0; lInotifyUpdate(); + } +} + +void +Simulation::threadedFunction() +{ + while (isThreadRunning()) + { + if (mPaused == false) + { + double currentTime = ofGetElapsedTimeMillis(); + if (currentTime - mTime < mUpdateInterval) continue; + else mTime = currentTime; + + update(); + } + + std::this_thread::sleep_for(std::chrono::microseconds(10)); + } + + //while(mTerminated == false) + //{ + // if(mPaused == false) + // { + // double currentTime = ofGetElapsedTimeMillis(); + // if(currentTime - mTime < mUpdateInterval) continue; + // else mTime = currentTime; + // + // update(); + // } + // + // std::this_thread::sleep_for(std::chrono::microseconds(10)); + //} + // + //if( mTerminated == true ) mTerminated = false; +} + +bool +Simulation::paused() +{ + return mPaused; +} + +bool +Simulation::frozen() +{ + return mFrozen; +} + +void +Simulation::start() +{ + if (isThreadRunning() == false) startThread(); +} + +void +Simulation::stop() +{ + if (isThreadRunning() == true) stopThread(); + + //mTerminated = true; +} + +void +Simulation::switchPaused() +{ + mPaused = !mPaused; +} + +void +Simulation::switchFrozen() +{ + mFrozen = !mFrozen; +} + +void +Simulation::exceptionReport( const Exception& pException ) +{ + if( FlockCom::get().checkSender("OSCErrorSender") == true ) + { + std::shared_ptr errorMessage( new OscMessage("/FlockError") ); + + std::string exceptionString = pException; + errorMessage->add(exceptionString); + + try + { + FlockCom::get().OscMessenger::send("OSCErrorSender", errorMessage); + } + catch(Exception& e) + { + std::cout << e << "\n"; + } + } + + std::cout << pException << "\n"; +} diff --git a/src/dab_flock_simulation.h b/src/dab_flock_simulation.h new file mode 100644 index 0000000..5cba007 --- /dev/null +++ b/src/dab_flock_simulation.h @@ -0,0 +1,280 @@ +/** \file dab_flock_simulation.h + * + * Created by Daniel Bisig on 4/19/07. + * Ported to Open Frameworks by Daniel Bisig on 4/08/17. + */ + +#ifndef _dab_flock_simulation_h_ +#define _dab_flock_simulation_h_ + +#include "ofUtils.h" +#include "ofThread.h" +#include + +#include "dab_singleton.h" +#include "dab_exception.h" +#include "dab_listener.h" +#include "dab_event_manager.h" +#include "dab_flock_com.h" +#include "dab_flock_stats.h" +//#include +//#include +//#include +#include "dab_space_manager.h" + +namespace dab +{ + +namespace flock +{ + +class Agent; +class Swarm; +class Env; + +class Simulation : public Singleton, public UpdateNotifier, public ofThread +{ +friend class Singleton; + +public: + /** + \brief return simulation step + */ + long simulationStep() const; + + /** + \brief return simulation update rate + \return simulation update rate (simulation steps / sec) + */ + float updateRate() const; + + /** + \brief return update interval + \return update interval + */ + float updateInterval() const; + + /** + \brief set update interval + \param pUpdateInterval update interval in milisecs + */ + void setUpdateInterval(float pUpdateInterval); + + /** + \brief return event manager + \return event manager + */ + event::EventManager& event(); + + /** + \brief return space manager + \return space manager + */ + space::SpaceManager& space(); + + /** + \brief return communcation manager + */ + FlockCom& com(); + + /** + \brief return analyzer manager + */ + FlockStats& stats(); + + /** + \brief return agent count + \return agent count + */ + unsigned int agentCount() const; + + /** + \brief return agents + \return agents + */ + std::vector& agents(); + + /** + \brief return agent + \param pIndex agent index + \return agent + \exception Exception agent not found + */ + Agent* agent(unsigned int pIndex) throw (Exception); + + /** + \brief return agent + \param pName agent name + \return agent + \exception Exception agent not found + */ + Agent* agent(std::string& pName) throw (Exception); + + /** + \brief add agent to simulation + \param pAgent agent + */ + void addAgent(Agent* pAgent); + + /** + \brief remove agent from simulation + \param pAgent agent + */ + void removeAgent(Agent* pAgent); + + /** + \brief check swarm + \param pName swarm name + \return true if swarm exists, false otherwise + */ + bool checkSwarm( std::string pName ); + + /** + \brief return swarms + \return swarms + */ + std::vector& swarms(); + + /** + \brief return swarm + \param pIndex swarm index + \return swarm + \exception Exception swarm not found + */ + Swarm* swarm(unsigned int pIndex) throw (Exception); + + /** + \brief return swarm + \param pName swarm name + \return swarm + \exception FlockException swarm not found + */ + Swarm* swarm(std::string pName) throw (Exception); + + /** + \brief add swarm to simulation + \param pSwarm swarm + */ + void addSwarm(Swarm* pSwarm); + + /** + \brief remove swarm from simulation + \param pSwarm swarm + */ + void removeSwarm(Swarm* pSwarm); + + /** + \brief check environment + \param pName environment name + \return true if environment exists, false otherwise + */ + bool checkEnv( std::string pName ); + + /** + \brief return environments + \return environments + */ + std::vector& envs(); + + /** + \brief return environment + \param pIndex environment index + \return environment + \exception Exception environment not found + */ + Env* env(unsigned int pIndex) throw (Exception); + + /** + \brief return environment + \param pName environment name + \return environment + \exception Exception environment not found + */ + Env* env(std::string pName) throw (Exception); + + /** + \brief add environment to simulation + \param pEnv environment + */ + void addEnv(Env* pEnv); + + /** + \brief remove environment from simulation + \param pEnv environment + */ + void removeEnv(Env* pEnv); + + /** + \brief clear entire simulation + */ + void clear(); + + /** + \brief perform one simulation step + */ + void update(); + + void notifyListeners(); + + void start(); + void stop(); + + /** + \brief check whether simulation is paused or not + \return true, if simulation is paused, false otherwise + */ + bool paused(); + + /** + \brief check whether simulation is frozen or not + \return true, if simulation is frozen, false otherwise + */ + bool frozen(); + + /** + \brief switch simulation between paused and non-paused mode + */ + void switchPaused(); + + void switchFrozen(); + + /** + \brief report exception + \param pException exception + */ + void exceptionReport( const Exception& pException ); + +protected: + /** + \brief default contructor + */ + Simulation(); + + /** + \brief destructor + */ + ~Simulation(); + + void threadedFunction(); + + static Simulation* sSimulation; /// \brief singleton instance + + std::vector mAgents; /// \brief agents + std::vector mSwarms;/// \brief swarms + std::vector mEnvs; ///\brief environments + double mUpdateInterval; /// \brief simulation update interval (milliseconds) + float mUpdateRate; ///\brief simulation update rate + bool mTerminated; /// \brief simulation termination flag + double mTime; /// \brief simulation running time (milliseconds) + event::EventManager mEventManager; /// \brief event manager + long mSimulationStep; + + bool mPaused; + bool mFrozen; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_spiral_behavior.cpp b/src/dab_flock_spiral_behavior.cpp new file mode 100644 index 0000000..574b8e7 --- /dev/null +++ b/src/dab_flock_spiral_behavior.cpp @@ -0,0 +1,135 @@ +/** \file dab_flock_spiral_behavior.cpp + */ + +#include "dab_flock_spiral_behavior.h" +#include "dab_flock_parameter.h" +#include "dab_flock_agent.h" +#include "dab_space_neighbor_relation.h" + +using namespace dab; +using namespace dab::flock; + +SpiralBehavior::SpiralBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "SpiralBehavior"; +} + +SpiralBehavior::SpiralBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "SpiralBehavior"; + + if( mInputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters.size() < 1 ) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != 3 ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must be 3", __FILE__, __FUNCTION__, __LINE__ ); + if( mOutputParameters[0]->dim() != 3 ) throw Exception( "FLOCK EROR: output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()) + " must be 3", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputNeighborGroups.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputNeighborGroups.size()) + " neighbor groups supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mPositionPar = mInputParameters[0]; + + // output parameter + mForcePar = mOutputParameters[0]; + + // create internal parameters + mMinDistPar = createInternalParameter("minDist", { 0.0f } ); + mMaxDistPar = createInternalParameter("maxDist", { 0.5f } ); + mAmountPar = createInternalParameter("amount", { 0.1f } ); + + // input neighbor groups + mPositionNeighbors = mInputNeighborGroups[0]; +} + +SpiralBehavior::~SpiralBehavior() +{} + +Behavior* +SpiralBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new SpiralBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new SpiralBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +SpiralBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new SpiralBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +SpiralBehavior::act() +{ + //std::cout << "SpiralBehavior begin: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& position = mPositionPar->values(); + space::NeighborGroup& positionNeighbors = *mPositionNeighbors; + Eigen::VectorXf& force = mForcePar->backupValues(); + float& minDist = mMinDistPar->value(); + float& maxDist = mMaxDistPar->value(); + float& amount = mAmountPar->value(); + + Eigen::Vector3f& tmpForce = mTmpForce; + + tmpForce.setConstant(0.0); + unsigned int totalNeighborCount = positionNeighbors.neighborCount(); + unsigned int neighborCount = 0; + + if(totalNeighborCount == 0) return; + + space::SpaceNeighborRelation* neighborRelation1 = nullptr; + space::SpaceNeighborRelation* neighborRelation2 = nullptr; + float distance1, distance2; + float scale; + + for(unsigned int i=0; idirection(); + distance1 = neighborRelation1->distance(); + + neighborRelation2 = positionNeighbors.neighborRelation(i + 1); + mDirection2 = neighborRelation2->direction(); + distance2 = neighborRelation1->distance(); + + if(minDist > 0.0 && distance1 < minDist) continue; + if(maxDist > 0.0 && distance1 > maxDist) continue; + if(minDist > 0.0 && distance2 < minDist) continue; + if(maxDist > 0.0 && distance2 > maxDist) continue; + + scale = (maxDist - distance1) / maxDist * (maxDist - distance2) / maxDist; + + tmpForce += mDirection1.cross(mDirection2) * scale; + + neighborCount++; + + //std::cout << " neighbor agent " << positionPar.neighbor(i)->agent()->name().toStdString() << " pos " << positionPar.neighbor(i)->values() << " dir " << direction << "\n"; + } + + if(neighborCount == 0) return; + + tmpForce /= static_cast(neighborCount); + tmpForce *= -1.0 * amount; + + //std::cout << "force " << tmpForce << "\n"; + + force += tmpForce; + + //std::cout << "SpiralBehavior end: out values" << mOutputParameters[0]->values() << " bValues " << mOutputParameters[0]->backupValues() << "\n"; + //assert(std::isnan(force[0]) == false && "isNan"); +} diff --git a/src/dab_flock_spiral_behavior.h b/src/dab_flock_spiral_behavior.h new file mode 100644 index 0000000..3c41f16 --- /dev/null +++ b/src/dab_flock_spiral_behavior.h @@ -0,0 +1,99 @@ +/** \file dab_flock_spiral_behavior.h + * \class dab::flock::SpiralBehavior cause Agent to move in a spiral around center position of their neighbors + * \brief cause Agent to move in a spiral around center position of their neighbors + * + * The Behavior causes Agent to move in a spiral around center position of their neighbors\n + * Input Parameter:\n + * type: position dim: 3D neighbors: required\n + * \n + * Output Parameter:\n + * type: force dim: 3D write: add\n + * \n + * Internal Parameter:\n + * name: xxx_minDist dim: 1D defaultValue: 0.0\n + * name: xxx_maxDist dim: 1D defaultValue: 0.5\n + * name: xxx_amount dim: 1D defaultValue: 0.1\n + * name: xxx_active dim: 1D defaultValue: 1.0\n + * \n + * Created by Daniel Bisig on 4/24/07. + * Ported to OpenFrameworks by Daniel Bisig on 20/10/2017. + */ + +#ifndef _dab_flock_spiral_behavior_h_ +#define _dab_flock_spiral_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class SpiralBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + SpiralBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + SpiralBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~SpiralBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mPositionPar; /// \brief position parameter (input) + Parameter* mForcePar; /// \brief force parameter (output) + Parameter* mMinDistPar; /// \brief minimum distance parameter (internal) + Parameter* mMaxDistPar; /// \brief maximum distance parameter (internal) + Parameter* mAmountPar; /// \brief behavior amount parameter (internal) + space::NeighborGroup* mPositionNeighbors; /// \brief position neighbor group + + Eigen::Vector3f mTmpForce; /// \brief temporary force + Eigen::Vector3f mDirection1; /// \brief neighbor direction 1 + Eigen::Vector3f mDirection2; /// \brief neighbor direction 2 +}; + +}; + +}; + +#endif + diff --git a/src/dab_flock_stats.cpp b/src/dab_flock_stats.cpp new file mode 100644 index 0000000..53caf5d --- /dev/null +++ b/src/dab_flock_stats.cpp @@ -0,0 +1,73 @@ +/** \file iso_flock_stats.cpp + */ + +#include "dab_flock_stats.h" + +using namespace dab; +using namespace dab::flock; + +FlockStats::FlockStats() +{} + +FlockStats::~FlockStats() +{} + +void +FlockStats::registerParameter(const std::string& pAnalyzerName, const std::string& pGroupName, const Parameter& pParameter) throw (Exception) +{ + if( checkAnalyzer(pAnalyzerName) == false) throw Exception("FLOCK ERROR: analyzer " + pAnalyzerName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + + space::SpaceObjectsAnalyzer* analyzer = mAnalyzers[pAnalyzerName]; + + if( analyzer->checkObjectGroup(pGroupName) == false && analyzer->modifiable() == false ) throw Exception( "FLOCK ERROR: anaylzer " + pAnalyzerName + " does not contain data group " + pGroupName + " and cannot be extended", __FILE__, __FUNCTION__, __LINE__ ); + + if( analyzer->checkObjectGroup(pGroupName) == false ) analyzer->addObjectGroup( pGroupName ); + analyzer->addObject( pGroupName, &pParameter ); +} + +void +FlockStats::registerParameter(const std::string& pAnalyzerName, const std::string& pGroupName, const space::NeighborGroup& pNeighborGroup ) throw (Exception) +{ + if( checkAnalyzer(pAnalyzerName) == false) throw Exception( "FLOCK ERROR: analyzer " + pAnalyzerName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + space::SpaceObjectsAnalyzer* analyzer = mAnalyzers[pAnalyzerName]; + + if( analyzer->checkObjectGroup(pGroupName) == false && analyzer->modifiable() == false ) throw Exception( "FLOCK EXCEPTION: anaylzer " + pAnalyzerName + " does not contain data group " + pGroupName + " and cannot be extended", __FILE__, __FUNCTION__, __LINE__ ); + + if( analyzer->checkObjectGroup(pGroupName) == false ) analyzer->addObjectGroup( pGroupName ); + + try + { + analyzer->addObject( pGroupName, &pNeighborGroup ); + } + catch(Exception& e) + { + throw; + } +} + +void +FlockStats::deregisterParameter(const std::string& pAnalyzerName, const std::string& pGroupName, const Parameter& pParameter) throw (Exception) +{ + if( checkAnalyzer(pAnalyzerName) == false) throw Exception( "FLOCK ERROR: analyzer " + pAnalyzerName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + space::SpaceObjectsAnalyzer* analyzer = mAnalyzers[pAnalyzerName]; + + if( analyzer->checkObjectGroup(pAnalyzerName) == false ) throw Exception( "FLOCK ERROR: anaylzer " + pAnalyzerName + " does not contain object group " + pGroupName, __FILE__, __FUNCTION__, __LINE__ ); + + analyzer->removeObject( pGroupName, &pParameter ); +} + +void +FlockStats::deregisterParameter(const std::string& pAnalyzerName, const std::string& pGroupName, const space::NeighborGroup& pNeighborGroup) throw (Exception) +{ + + if( checkAnalyzer(pAnalyzerName) == false) throw Exception( "FLOCK ERROR: analyzer " + pAnalyzerName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + space::SpaceObjectsAnalyzer* analyzer = mAnalyzers[pAnalyzerName]; + + if( analyzer->checkObjectGroup(pGroupName) == false ) throw Exception( "FLOCK ERROR: anaylzer " + pAnalyzerName + " does not contain object group " + pGroupName, __FILE__, __FUNCTION__, __LINE__ ); + + analyzer->removeObject( pGroupName, &pNeighborGroup ); +} \ No newline at end of file diff --git a/src/dab_flock_stats.h b/src/dab_flock_stats.h new file mode 100644 index 0000000..caea78f --- /dev/null +++ b/src/dab_flock_stats.h @@ -0,0 +1,80 @@ +/** \file dab_flock_stats.h + * \class dab::flock::FlockStats flock analyzer and statistics manager + * \brief flock analyzer and statistics manager + * + * Created by Daniel Bisig on 6/5/08. + * Ported to OpenFrameworks by Daniel Bisig on 09/08/17. + */ + +#ifndef _dab_flock_stats_h_ +#define _dab_flock_stats_h_ + +#include "dab_singleton.h" +#include "dab_flock_parameter.h" +#include "dab_space_objects_analyze_manager.h" + +namespace dab +{ + +namespace flock +{ + +class FlockStats : public space::SpaceObjectsAnalyzeManager , public Singleton +{ + friend class Singleton; + +public: + /** + \brief register parameter for analysis + \param pAnalyzerName name of analyzer + \param pGroupName name of group + \param pParameter parameter + \exception Exception failed to add parameter + */ + void registerParameter(const std::string& pAnalyzerName, const std::string& pGroupName, const Parameter& pParameter) throw (Exception); + + /** + \brief register parameter neighbor group for analysis + \param pAnalyzerName name of analyzer + \param pGroupName name of group + \param pNeighborGroup parameter neighbor group + \exception Exception failed to add neighborgroup + */ + void registerParameter(const std::string& pAnalyzerName, const std::string& pGroupName, const space::NeighborGroup& pNeighborGroup ) throw (Exception); + + /** + \brief deregister parameter + \param pAnalyzerName name of analyzer + \param pGroupName name of group + \param pParameter parameter + \exception Exception failed to remove parameter + */ + void deregisterParameter(const std::string& pAnalyzerName, const std::string& pGroupName, const Parameter& pParameter) throw (Exception); + + /** + \brief deregister parameter neighborgroup + \param pAnalyzerName name of analyzer + \param pGroupName name of group + \param pNeighborGroup parameter neighbor group + \exception Exception failed to remove neighborgroup + */ + void deregisterParameter(const std::string& pAnalyzerName, const std::string& pGroupName, const space::NeighborGroup& pNeighborGroup ) throw (Exception); + + +protected: + /** + \brief default constructor + */ + FlockStats(); + + /** + \brief destructor + */ + ~FlockStats(); +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_swarm.cpp b/src/dab_flock_swarm.cpp new file mode 100644 index 0000000..eeb92f3 --- /dev/null +++ b/src/dab_flock_swarm.cpp @@ -0,0 +1,1995 @@ +/** \file dab_flock_swarm.cpp + */ + +#include "dab_math.h" +#include "dab_flock_swarm.h" +#include "dab_flock_agent.h" +#include "dab_flock_swarm_behavior.h" +#include "dab_flock_simulation.h" +#include "dab_flock_stats.h" + +using namespace dab; +using namespace dab::flock; + +unsigned int Swarm::sInstanceCount = 0; + +Swarm::Swarm() +: Agent() +, mAgentParameterList(mParameterList) +, mAgentBehaviorList(mBehaviorList) +, mSelf(this) +{ + assert("illegal constructor"); +} + +Swarm::Swarm(const std::string& pName) +: Agent(pName) +, mAgentParameterList(mParameterList) +, mAgentBehaviorList(mBehaviorList) +, mAgentCreationCount(0) +, mSelf(this) +{ + mIndex = sInstanceCount++; + + //std::cout << "swarm " << mName.toStdString() << " index " << mIndex << "\n"; + + addSwarmParameter( new Parameter( this, "active", {1.0} ) ); + + Simulation::get().addAgent(this); + Simulation::get().addSwarm(this); + Simulation::get().addListener(mSelf); +} + +Swarm::Swarm(const std::string& pName, const Swarm& pSwarm) +: Agent(pName, pSwarm) +, mAgentParameterList(mParameterList) +, mAgentBehaviorList(mBehaviorList) +, mAgentCreationCount(0) +, mSelf(this) +{ + mIndex = sInstanceCount++; + + // copy swarm parameters + unsigned int parCount = pSwarm.swarmParameterCount(); + for(unsigned int i=0; icreate( beh->name(), this ) ); + } + + Simulation::get().addAgent(this); + Simulation::get().addSwarm(this); + Simulation::get().addListener(mSelf); + + // add same number of agents + addAgents( pSwarm.mAgents.size() ); +} + +Swarm::~Swarm() +{ + std::cout << "destructor " << mName << "\n"; + +// Simulation::get().removeListener(mSelf); +// +// if(mSelf == nullptr) +// { +// std::cout << "mSelf null\n"; +// +// return; +// } +// +// std::cout << "destructor2 " << mName << "\n"; +// +// mSelf = std::shared_ptr(nullptr); + + removeAgents(); + + Simulation::get().removeAgent(this); + Simulation::get().removeSwarm(this); + + for(auto regIter = mAgentNeighborAssignRegistry.begin(); regIter != mAgentNeighborAssignRegistry.end(); ++regIter) + { + std::vector& infos = regIter->second; + int infoCount = infos.size(); + + for(int i=0; i& infos = regIter->second; + int infoCount = infos.size(); + + for(int i=0; i& +Swarm::agents() +{ + return mAgents; +} + +const std::vector& +Swarm::agents() const +{ + return mAgents; +} + +void +Swarm::addAgent() throw (Exception) +{ + // std::cout << "Swarm::addAgent() begin\n"; + + try + { + Agent* agent = new Agent( std::string( mName + "_" + std::to_string(mAgents.size()) ), *this ); + + // debug + //std::cout << "swarm " << mName<< " add agent " << agent->index() << "\n"; + + // std::cout << "create agent " << agent->name() << "\n"; + + ////////////////////////////////////////////// + // assign parameters to neighborhood spaces // + ////////////////////////////////////////////// + + NeighborAssignInfo* neighborAssignInfo; + + for(auto iter = mAgentNeighborAssignRegistry.begin(); iter != mAgentNeighborAssignRegistry.end(); ++iter) + { + const std::string& parameterName = iter->first; + Parameter* agentParameter = agent->parameter(parameterName); + + std::vector< NeighborAssignInfo* >& neighborAssigns = mAgentNeighborAssignRegistry[parameterName]; + unsigned int neighborAssignCount = neighborAssigns.size(); + + //std::cout << "parameterName " << parameterName << " neighborAssignCount " << neighborAssignCount << "\n"; + + for(unsigned int neighborAssignIndex=0; neighborAssignIndexmParameterName << " sName " << neighborAssignInfo->mSpaceName << "\n"; + + space::NeighborGroup* agentParameterNeighborGroup = agentParameter->neighborGroup(neighborAssignInfo->mSpaceName); + agentParameterNeighborGroup->setVisible( neighborAssignInfo->mVisible ); + if(neighborAssignInfo->mNeighborGroupAlg != nullptr) agentParameterNeighborGroup->setNeighborGroupAlg( new space::NeighborGroupAlg( *( neighborAssignInfo->mNeighborGroupAlg ) ) ); + } + + } + + ///////////////////////////// + // add agent to simulation // + ///////////////////////////// + + mAgents.push_back(agent); + Simulation::get().addAgent(agent); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to add agent to swarm", __FILE__, __FUNCTION__, __LINE__); + throw e; + } + + // std::cout << "Swarm::addAgent() done\n"; +} + +void +Swarm::addAgents(unsigned int pAgentCount) throw (Exception) +{ + try + { + for(unsigned int i=0; i mAgents.size() ) throw Exception( "FLOCK ERROR: Agent Nr " + std::to_string(pAgentIndex) + " Does Not Exist", __FILE__, __FUNCTION__, __LINE__ ); + + Agent* agent = mAgents[pAgentIndex]; + + try + { + mAgents.erase(mAgents.begin() + pAgentIndex); + + Simulation& simulation = Simulation::get(); + simulation.removeAgent(agent); + + delete agent; + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to remove agent " + agent->name() + " from swarm", __FILE__, __FUNCTION__, __LINE__); + throw; + } +} + +void +Swarm::removeAgents(unsigned int pAgentCount) throw (Exception) +{ + try + { + if( mAgents.size() == 0 ) return; + if(pAgentCount > mAgents.size() ) pAgentCount = mAgents.size(); + + for(unsigned int i=0; i mAgents.size() - pAgentIndex ) pAgentCount = mAgents.size() - pAgentIndex; + + //std::cout << "remove agent count " << pAgentCount << " agent size " << mAgents.size() << "\n"; + + for(unsigned int i=0; i= mAgents.size()) throw Exception( "FLOCK ERROR: Agent Nr " + std::to_string(pAgentIndex) + " Does Not Exist", __FILE__, __FUNCTION__, __LINE__ ); + try + { + return mAgents[pAgentIndex]->parameter(pParameterName); + } + catch(Exception& e) + { + throw; + } +} + +const Parameter* +Swarm::agentParameter(unsigned int pAgentIndex, const std::string& pParameterName) const throw (Exception) +{ + if(pAgentIndex >= mAgents.size()) throw Exception( "FLOCK ERROR: Agent Nr " + std::to_string(pAgentIndex) + " Does Not Exist", __FILE__, __FUNCTION__, __LINE__ ); + try + { + return mAgents[pAgentIndex]->parameter(pParameterName); + } + catch(Exception& e) + { + throw; + } +} + +Parameter* +Swarm::agentParameter(unsigned int pAgentIndex, unsigned int pParameterIndex) throw (Exception) +{ + if(pAgentIndex >= mAgents.size()) throw Exception( "FLOCK ERROR: Agent Nr " + std::to_string(pAgentIndex) + " Does Not Exist", __FILE__, __FUNCTION__, __LINE__ ); + + try + { + return mAgents[pAgentIndex]->parameter(pParameterIndex); + } + catch(Exception& e) + { + throw; + } +} + +const Parameter* +Swarm::agentParameter(unsigned int pAgentIndex, unsigned int pParameterIndex) const throw (Exception) +{ + if(pAgentIndex >= mAgents.size()) throw Exception( "FLOCK ERROR: Agent Nr " + std::to_string(pAgentIndex) + " Does Not Exist", __FILE__, __FUNCTION__, __LINE__ ); + + try + { + return mAgents[pAgentIndex]->parameter(pParameterIndex); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addParameter(Parameter* pParameter) throw (Exception) +{ + try + { + addAgentParameter(pParameter); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addAgentParameter(Parameter* pParameter) throw (Exception) +{ + try + { + Agent::addParameter(pParameter); + + unsigned int agentCount = mAgents.size(); + + for(unsigned int i=0; iaddParameter( new Parameter( mAgents[i], *pParameter ) ); + } + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to add agent patameter " + pParameter->name(), __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } +} + +void +Swarm::addSwarmParameter(Parameter* pParameter) throw (Exception) +{ + //std::cout << "Swarm " << mName << " addParameter(Parameter* " << pParameter->name() << " ) begin\n"; + + try + { + mSwarmParameterList.addParameter(pParameter); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to add swarm patameter " + pParameter->name(), __FILE__, __FUNCTION__, __LINE__ ); + throw e; + } + + //std::cout << "Swarm " << mName << " addParameter(Parameter* " << pParameter->name() << " ) end\n"; +} + +void +Swarm::addParameter(const std::string& pName, unsigned int pDim) throw (Exception) +{ + try + { + addAgentParameter( pName, pDim ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addAgentParameter(const std::string& pName, unsigned int pDim) throw (Exception) +{ + try + { + Agent::addParameter( pName, pDim ); + + unsigned int agentCount = mAgents.size(); + + for(unsigned int i=0; iaddParameter( pName, pDim ); + } + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addSwarmParameter(const std::string& pName, unsigned int pDim) throw (Exception) +{ + try + { + addSwarmParameter( new Parameter(this, pName, pDim) ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addParameter(const std::string& pName, unsigned int pDim, float pValue) throw (Exception) +{ + try + { + addAgentParameter(pName, { pValue } ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addAgentParameter(const std::string& pName, unsigned int pDim, float pValue) throw (Exception) +{ + try + { + Eigen::VectorXf parValue(pDim); + parValue.setConstant(pValue); + + addAgentParameter(pName, parValue ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addSwarmParameter(const std::string& pName, unsigned int pDim, float pValue) throw (Exception) +{ + try + { + Eigen::VectorXf parValue(pDim); + parValue.setConstant(pValue); + addSwarmParameter(pName, parValue ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addParameter(const std::string& pName, const std::initializer_list& pValues) throw (Exception) +{ + try + { + addAgentParameter( pName, pValues ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addParameter(const std::string& pName, const Eigen::VectorXf& pValues) throw (Exception) +{ + try + { + addAgentParameter( pName, pValues ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addAgentParameter(const std::string& pName, const std::initializer_list& pValues) throw (Exception) +{ + try + { + Agent::addParameter( pName, pValues ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addAgentParameter(const std::string& pName, const Eigen::VectorXf& pValues) throw (Exception) +{ + try + { + Agent::addParameter( pName, pValues ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addSwarmParameter(const std::string& pName, const std::initializer_list& pValues) throw (Exception) +{ + try + { + addSwarmParameter( new Parameter(this, pName, pValues) ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addSwarmParameter(const std::string& pName, const Eigen::VectorXf& pValues) throw (Exception) +{ + try + { + addSwarmParameter( new Parameter(this, pName, pValues) ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::removeParameter( const std::string pName ) throw (Exception) +{ + try + { + removeAgentParameter( pName ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::removeAgentParameter( const std::string pName ) throw (Exception) +{ + try + { + unsigned int agentCount = mAgents.size(); + for(unsigned int agentNr=0; agentNr < agentCount; ++agentNr) mAgents[agentNr]->removeParameter( pName ); + Agent::removeParameter( pName ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::removeSwarmParameter( const std::string pName ) throw (Exception) +{ + try + { + mSwarmParameterList.removeParameter(pName); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::set(const std::string& pParameterName, float pParameterValue) throw (Exception) +{ + try + { + bool parameterFound = false; + + // swarm parameter + if(mSwarmParameterList.contains(pParameterName)) + { + mSwarmParameterList.setValue(pParameterName, pParameterValue); + parameterFound = true; + } + + // agent parameters + if(mAgentParameterList.contains(pParameterName)) + { + unsigned int parIndex = parameterIndex(pParameterName); + Agent::parameter(parIndex)->setValue(pParameterValue); + + unsigned int agentCount = mAgents.size(); + + for(unsigned int i=0; iparameter(parIndex)->setValue(pParameterValue); + } + + parameterFound = true; + } + + if(parameterFound == false) throw Exception( "FLOCK ERROR: parameter " + pParameterName + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::set(unsigned int pAgentIndex, const std::string& pParameterName, float pParameterValue) throw (Exception) +{ + if( pAgentIndex >= mAgents.size() ) throw Exception( "FLOCK ERROR: agent index " + std::to_string(pAgentIndex) + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + + try + { + mAgents[pAgentIndex]->parameter( pParameterName )->setValue( pParameterValue ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::set(const std::string& pParameterName, const std::initializer_list& pParameterValues) throw (Exception) +{ + //std::cout << "swarm set " << pParameterName << " : " << pParameterValues << "\n"; + + try + { + int parDim = pParameterValues.size(); + Eigen::VectorXf parValues(parDim); + + auto iter = pParameterValues.begin(); + + for( int d=0; d < parDim; ++d, ++iter) + { + parValues[d] = *iter; + } + + set(pParameterName, parValues); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::set(const std::string& pParameterName, const Eigen::VectorXf& pParameterValues) throw (Exception) +{ + //std::cout << "swarm set " << pParameterName << " : " << pParameterValues << "\n"; + + try + { + bool parameterFound = false; + + // swarm parameter + if(mSwarmParameterList.contains(pParameterName)) + { + mSwarmParameterList.setValues(pParameterName, pParameterValues); + parameterFound = true; + } + + // agent parameters + if(mAgentParameterList.contains(pParameterName)) + { + unsigned int parIndex = parameterIndex(pParameterName); + Agent::parameter(parIndex)->setValues(pParameterValues); + + unsigned int agentCount = mAgents.size(); + + for(unsigned int i=0; iparameter( parIndex )->setValues( pParameterValues ); + } + + parameterFound = true; + } + + if(parameterFound == false) throw Exception("FLOCK ERROR: parameter " + pParameterName + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::set(unsigned int pAgentIndex, const std::string& pParameterName, const std::initializer_list& pParameterValues) throw (Exception) +{ + if( pAgentIndex >= mAgents.size() ) throw Exception( "FLOCK ERROR: agent index " + std::to_string(pAgentIndex) + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + + try + { + mAgents[pAgentIndex]->parameter( pParameterName )->setValues( pParameterValues ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::set(unsigned int pAgentIndex, const std::string& pParameterName, const Eigen::VectorXf& pParameterValues) throw (Exception) +{ + if( pAgentIndex >= mAgents.size() ) throw Exception( "FLOCK ERROR: agent index " + std::to_string(pAgentIndex) + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + + try + { + mAgents[pAgentIndex]->parameter( pParameterName )->setValues( pParameterValues ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::randomize(const std::string& pParameterName, float pMinParameterValue, float pMaxParameterValue) throw (Exception) +{ + math::Math<>& math = math::Math<>::get(); + + try + { + bool parameterFound = false; + + // swarm parameter + if(mSwarmParameterList.contains(pParameterName)) + { + mSwarmParameterList.setValue(pParameterName, math.random( pMinParameterValue, pMaxParameterValue )); + parameterFound = true; + } + + // agent parameters + if(mAgentParameterList.contains(pParameterName)) + { + //Agent::set( pParameterName, math.random( pMinParameterValue, pMaxParameterValue ) ); + + unsigned int parIndex = parameterIndex(pParameterName); + Agent::parameter(parIndex)->setValue( math.random( pMinParameterValue, pMaxParameterValue ) ); + + unsigned int agentCount = mAgents.size(); + + for(unsigned int i=0; iparameter(parIndex)->setValue( math.random( pMinParameterValue, pMaxParameterValue ) ); + } + + parameterFound = true; + } + + if(parameterFound == false) throw Exception( "FLOCK ERROR: parameter " + pParameterName + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::randomize(unsigned int pAgentIndex, const std::string& pParameterName, float pMinParameterValue, float pMaxParameterValue) throw (Exception) +{ + if( pAgentIndex >= mAgents.size() ) throw Exception( "FLOCK ERROR: agent index " + std::to_string(pAgentIndex) + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + + math::Math<>& math = math::Math<>::get(); + + try + { + mAgents[pAgentIndex]->parameter( pParameterName )->setValue( math.random( pMinParameterValue, pMaxParameterValue ) ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::randomize(const std::string& pParameterName, const std::initializer_list& pMinParameterValues, const std::initializer_list& pMaxParameterValues) throw (Exception) +{ + if(pMinParameterValues.size() != pMaxParameterValues.size() ) throw Exception("FLOCK ERROR: minim parameter dimension " + std::to_string(pMinParameterValues.size()) + " doesn't match maximum parameter size " + std::to_string(pMaxParameterValues.size()), __FILE__, __FUNCTION__, __LINE__); + + try + { + int parDim = pMinParameterValues.size(); + + Eigen::VectorXf minParValues(parDim); + + auto minIter = pMinParameterValues.begin(); + + for( int d=0; d < parDim; ++d, ++minIter) + { + minParValues[d] = *minIter; + } + + Eigen::VectorXf maxParValues(parDim); + + auto maxIter = pMaxParameterValues.begin(); + + for( int d=0; d < parDim; ++d, ++maxIter) + { + maxParValues[d] = *maxIter; + } + + randomize(pParameterName, minParValues, maxParValues); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::randomize(const std::string& pParameterName, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues) throw (Exception) +{ + if(pMinParameterValues.rows() != pMaxParameterValues.rows() ) throw Exception( "FLOCK ERROR: minimum parameter dim " + std::to_string(pMinParameterValues.rows()) + " doesn't match maximum parameter dim " + std::to_string(pMinParameterValues.rows()), __FILE__, __FUNCTION__, __LINE__ ); + + math::Math<>& math = math::Math<>::get(); + unsigned int parameterDim = pMinParameterValues.rows(); + Eigen::VectorXf randValue( parameterDim ); + + try + { + bool parameterFound = false; + + // swarm parameter + if(mSwarmParameterList.contains(pParameterName)) + { + for( unsigned int i=0; isetValues( randValue); + + //Agent::set( pParameterName, randValue ); + + unsigned int agentCount = mAgents.size(); + + for(unsigned int i=0; iparameter( pParameterName )->setValues( randValue ); + } + + parameterFound = true; + } + + if(parameterFound == false) throw Exception( "FLOCK ERROR: parameter " + pParameterName + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::randomize(unsigned int pAgentIndex, const std::string& pParameterName, const std::initializer_list& pMinParameterValues, const std::initializer_list& pMaxParameterValues) throw (Exception) +{ + if( pAgentIndex >= mAgents.size() ) throw Exception( "FLOCK ERROR: agent index " + std::to_string(pAgentIndex) + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + if(pMinParameterValues.size() != pMaxParameterValues.size() ) throw Exception( "FLOCK ERROR: minimum parameter dim " + std::to_string(pMinParameterValues.size()) + " doesn't match maximum parameter dim " + std::to_string(pMaxParameterValues.size()), __FILE__, __FUNCTION__, __LINE__ ); + + try + { + int parDim = pMinParameterValues.size(); + + Eigen::VectorXf minParValues(parDim); + + auto minIter = pMinParameterValues.begin(); + + for( int d=0; d < parDim; ++d, ++minIter) + { + minParValues[d] = *minIter; + } + + Eigen::VectorXf maxParValues(parDim); + + auto maxIter = pMaxParameterValues.begin(); + + for( int d=0; d < parDim; ++d, ++maxIter) + { + maxParValues[d] = *maxIter; + } + + randomize(pAgentIndex, pParameterName, minParValues, maxParValues); + } + catch(Exception& e) + { + throw; + } +} + + +void +Swarm::randomize(unsigned int pAgentIndex, const std::string& pParameterName, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues) throw (Exception) +{ + if( pAgentIndex >= mAgents.size() ) throw Exception( "FLOCK ERROR: agent index " + std::to_string(pAgentIndex) + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + if(pMinParameterValues.rows() != pMaxParameterValues.rows() ) throw Exception( "FLOCK ERROR: minimum parameter dim " + std::to_string(pMinParameterValues.rows()) + " doesn't match maximum parameter dim " + std::to_string(pMaxParameterValues.rows()), __FILE__, __FUNCTION__, __LINE__ ); + + math::Math<>& math = math::Math<>::get(); + unsigned int parameterDim = pMinParameterValues.rows(); + Eigen::VectorXf randValue( parameterDim ); + for( unsigned int i=0; iparameter(pParameterName)->setValues( randValue); + } + catch(Exception& e) + { + throw; + } +} + +std::vector< NeighborAssignInfo* > +Swarm::agentNeighborInfo( const std::string& pParameterName ) +{ + if( mAgentNeighborAssignRegistry.find( pParameterName ) != mAgentNeighborAssignRegistry.end() ) return mAgentNeighborAssignRegistry.at( pParameterName ); + else return std::vector< NeighborAssignInfo* >(); +} + +std::vector< NeighborAssignInfo* > +Swarm::swarmNeighborInfo( const std::string& pParameterName ) +{ + if( mSwarmNeighborAssignRegistry.find( pParameterName ) != mSwarmNeighborAssignRegistry.end() ) return mSwarmNeighborAssignRegistry.at( pParameterName ); + else return std::vector< NeighborAssignInfo* >(); +} + +void +Swarm::assignNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible, space::NeighborGroupAlg* pNeighborGroupAlg ) throw (Exception) +{ + try + { + bool parameterFound = false; + + if(mSwarmParameterList.contains(pParameterName)) + { + parameterFound = true; + assignSwarmNeighbors(pParameterName, pSpaceName, pVisible, pNeighborGroupAlg); + } + if(mAgentParameterList.contains(pParameterName)) + { + parameterFound = true; + assignAgentNeighbors(pParameterName, pSpaceName, pVisible, pNeighborGroupAlg); + } + + if(parameterFound == false) throw Exception( "FLOCK ERROR: parameter " + pParameterName + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::assignAgentNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible, space::NeighborGroupAlg* pNeighborGroupAlg ) throw (Exception) +{ + try + { + if(mAgentParameterList.contains(pParameterName)) + { + NeighborAssignInfo* neighborAssignInfo; + + // check if there is already a registry available for this neighbor assignment + bool spaceFound = false; + + if( mAgentNeighborAssignRegistry.find( pParameterName ) != mAgentNeighborAssignRegistry.end() ) + { + std::vector& neighborAssignInfos = mAgentNeighborAssignRegistry.at( pParameterName ); + int neighborAssignInfoCount = neighborAssignInfos.size(); + for( int nI=0; nImSpaceName == pSpaceName ) + { + spaceFound = true; + neighborAssignInfo->mVisible = pVisible; + if( neighborAssignInfo->mNeighborGroupAlg != nullptr ) delete neighborAssignInfo->mNeighborGroupAlg; + neighborAssignInfo->mNeighborGroupAlg = pNeighborGroupAlg; + } + } + } + + if( spaceFound == false ) // create new neighbor assign info + { + neighborAssignInfo = new NeighborAssignInfo(pParameterName, pSpaceName, pVisible, pNeighborGroupAlg ); + mAgentNeighborAssignRegistry[pParameterName].push_back(neighborAssignInfo); + } + + if(pNeighborGroupAlg != nullptr) Agent::assignNeighbors( pParameterName, pSpaceName, false, new space::NeighborGroupAlg( pNeighborGroupAlg->neighborRadius(), 0, pNeighborGroupAlg->replaceNeighborMode() ) ); + else Agent::assignNeighbors( pParameterName, pSpaceName, false, nullptr ); + + unsigned int agentCount = mAgents.size(); + + for(unsigned int i=0; iassignNeighbors( pParameterName, pSpaceName, pVisible, new space::NeighborGroupAlg( *pNeighborGroupAlg ) ); + else mAgents[i]->assignNeighbors( pParameterName, pSpaceName, pVisible, nullptr ); + } + } + else throw Exception( "FLOCK ERROR: parameter " + pParameterName + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::assignSwarmNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible, space::NeighborGroupAlg* pNeighborGroupAlg ) throw (Exception) +{ + try + { + if(mSwarmParameterList.contains(pParameterName)) + { + NeighborAssignInfo* neighborAssignInfo; + + // check if there is already a registry available for this neighbor assignment + bool spaceFound = false; + + if( mSwarmNeighborAssignRegistry.find( pParameterName ) != mSwarmNeighborAssignRegistry.end() ) + { + std::vector neighborAssignInfos = mSwarmNeighborAssignRegistry.at( pParameterName ); + int neighborAssignInfoCount = neighborAssignInfos.size(); + for( int nI=0; nImSpaceName == pSpaceName ) + { + spaceFound = true; + neighborAssignInfo->mVisible = pVisible; + if( neighborAssignInfo->mNeighborGroupAlg != NULL ) delete neighborAssignInfo->mNeighborGroupAlg; + neighborAssignInfo->mNeighborGroupAlg = pNeighborGroupAlg; + } + } + } + + if( spaceFound == false ) // create new neighbor assign info + { + neighborAssignInfo = new NeighborAssignInfo(pParameterName, pSpaceName, pVisible, pNeighborGroupAlg ); + mSwarmNeighborAssignRegistry[pParameterName].push_back(neighborAssignInfo); + } + + std::shared_ptr space = space::SpaceManager::get().space(pSpaceName); + Parameter* parameter = mSwarmParameterList.parameter(pParameterName); + + if( space->checkObject( parameter ) == true ) space->setObject( parameter, pVisible, pNeighborGroupAlg ); + else space->addObject( parameter, pVisible, pNeighborGroupAlg); + } + else throw Exception( "FLOCK ERROR: parameter " + pParameterName + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::assignNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible ) throw (Exception) +{ + try + { + assignNeighbors( pParameterName, pSpaceName, pVisible, nullptr ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::assignAgentNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible ) throw (Exception) +{ + try + { + assignAgentNeighbors( pParameterName, pSpaceName, pVisible, nullptr ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::assignSwarmNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible ) throw (Exception) +{ + try + { + assignSwarmNeighbors( pParameterName, pSpaceName, pVisible, nullptr ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::assignNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible, float pNeighborRadius, int pMaxNeighborCount, bool pReplaceNeighborMode ) throw (Exception) +{ + try + { + bool parameterFound = false; + + if(mSwarmParameterList.contains(pParameterName)) + { + parameterFound = true; + assignSwarmNeighbors(pParameterName, pSpaceName, pVisible, pNeighborRadius, pMaxNeighborCount, pReplaceNeighborMode); + } + if(mAgentParameterList.contains(pParameterName)) + { + parameterFound = true; + assignAgentNeighbors(pParameterName, pSpaceName, pVisible, pNeighborRadius, pMaxNeighborCount, pReplaceNeighborMode); + } + + if(parameterFound == false) throw Exception( "FLOCK ERROR: parameter " + pParameterName + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::assignAgentNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible, float pNeighborRadius, int pMaxNeighborCount, bool pReplaceNeighborMode ) throw (Exception) +{ + try + { + NeighborAssignInfo* neighborAssignInfo; + + // check if there is already a registry available for this neighbor assignment + bool spaceFound = false; + if( mAgentNeighborAssignRegistry.find( pParameterName ) != mAgentNeighborAssignRegistry.end()) + { + std::vector neighborAssignInfos = mAgentNeighborAssignRegistry.at( pParameterName ); + int neighborAssignInfoCount = neighborAssignInfos.size(); + for( int nI=0; nImSpaceName == pSpaceName ) + { + spaceFound = true; + neighborAssignInfo->mVisible = pVisible; + if( neighborAssignInfo->mNeighborGroupAlg != nullptr ) delete neighborAssignInfo->mNeighborGroupAlg; + neighborAssignInfo->mNeighborGroupAlg = new space::NeighborGroupAlg( pNeighborRadius, pMaxNeighborCount, pReplaceNeighborMode ); + } + } + } + + if( spaceFound == false ) // create new neighbor assign info + { + neighborAssignInfo = new NeighborAssignInfo(pParameterName, pSpaceName, pVisible, new space::NeighborGroupAlg( pNeighborRadius, pMaxNeighborCount, pReplaceNeighborMode ) ); + mAgentNeighborAssignRegistry[pParameterName].push_back(neighborAssignInfo); + } + + Agent::assignNeighbors( pParameterName, pSpaceName, false, new space::NeighborGroupAlg( pNeighborRadius, 0, pReplaceNeighborMode ) ); + + if(mAgentParameterList.contains(pParameterName)) + { + unsigned int agentCount = mAgents.size(); + + for(unsigned int i=0; iassignNeighbors( pParameterName, pSpaceName, pVisible, new space::NeighborGroupAlg( pNeighborRadius, pMaxNeighborCount, pReplaceNeighborMode ) ); + } + } + else throw Exception( "FLOCK ERROR: parameter " + pParameterName + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + + +void +Swarm::assignSwarmNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible, float pNeighborRadius, int pMaxNeighborCount, bool pReplaceNeighborMode ) throw (Exception) +{ + try + { + NeighborAssignInfo* neighborAssignInfo; + + // check if there is already a registry available for this neighbor assignment + bool spaceFound = false; + if( mSwarmNeighborAssignRegistry.find( pParameterName ) != mSwarmNeighborAssignRegistry.end() ) + { + std::vector neighborAssignInfos = mSwarmNeighborAssignRegistry.at( pParameterName ); + int neighborAssignInfoCount = neighborAssignInfos.size(); + for( int nI=0; nImSpaceName == pSpaceName ) + { + spaceFound = true; + neighborAssignInfo->mVisible = pVisible; + if( neighborAssignInfo->mNeighborGroupAlg != NULL ) delete neighborAssignInfo->mNeighborGroupAlg; + neighborAssignInfo->mNeighborGroupAlg = new space::NeighborGroupAlg( pNeighborRadius, pMaxNeighborCount, pReplaceNeighborMode ); + } + } + } + + if( spaceFound == false ) // create new neighbor assign info + { + neighborAssignInfo = new NeighborAssignInfo(pParameterName, pSpaceName, pVisible, new space::NeighborGroupAlg( pNeighborRadius, pMaxNeighborCount, pReplaceNeighborMode ) ); + mSwarmNeighborAssignRegistry[pParameterName].push_back(neighborAssignInfo); + } + + if(mSwarmParameterList.contains(pParameterName)) + { + std::shared_ptr space = space::SpaceManager::get().space(pSpaceName); + Parameter* parameter = mSwarmParameterList.parameter(pParameterName); + + if( space->checkObject( parameter ) == true ) space->setObject( parameter, pVisible, new space::NeighborGroupAlg( pNeighborRadius, pMaxNeighborCount, pReplaceNeighborMode ) ); + else space->addObject( parameter, pVisible, new space::NeighborGroupAlg( pNeighborRadius, pMaxNeighborCount, pReplaceNeighborMode ) ); + } + else throw Exception( "FLOCK ERROR: parameter " + pParameterName + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::removeNeighbors( const std::string& pParameterName, const std::string& pSpaceName ) throw (Exception) +{ + try + { + if( Simulation::get().space().checkSpace(pSpaceName) == false ) throw Exception( "FLOCK ERROR: space " + pSpaceName + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + + bool neighborsFound = false; + + if( mSwarmNeighborAssignRegistry.find( pParameterName ) != mSwarmNeighborAssignRegistry.end()) + { + neighborsFound = true; + removeSwarmNeighbors( pParameterName, pSpaceName ); + } + if( mAgentNeighborAssignRegistry.find( pParameterName ) != mAgentNeighborAssignRegistry.end() ) + { + neighborsFound = true; + removeAgentNeighbors( pParameterName, pSpaceName ); + } + + if(neighborsFound == false) throw Exception( "FLOCK ERROR: no neighbors assigned to parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__ ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::removeSwarmNeighbors( const std::string& pParameterName, const std::string& pSpaceName ) throw (Exception) +{ + try + { + if( mSwarmNeighborAssignRegistry.find( pParameterName ) == mSwarmNeighborAssignRegistry.end() ) throw Exception( "FLOCK ERROR: no neighbors assigned to parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__ ); + if( Simulation::get().space().checkSpace(pSpaceName) == false ) throw Exception( "FLOCK ERROR: space " + pSpaceName + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + + std::vector< NeighborAssignInfo* > neighborAssigns = mSwarmNeighborAssignRegistry.at( pParameterName ); + int neighborAssignCount = neighborAssigns.size(); + + for(int nI=neighborAssignCount - 1; nI>=0; --nI) + { + NeighborAssignInfo* neighborAssign = neighborAssigns[nI]; + + if(neighborAssign->mSpaceName == pSpaceName) + { + std::shared_ptr space = Simulation::get().space().space( pSpaceName ); + + if(mSwarmParameterList.contains(pParameterName)) + { + Parameter* parameter = mSwarmParameterList.parameter(pParameterName); + space->removeObject( parameter ); + } + + neighborAssigns.pop_back(); + delete neighborAssign; + } + } + + if(neighborAssigns.size() == 0) + { + mSwarmNeighborAssignRegistry.erase( pParameterName ); + } + + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::removeAgentNeighbors( const std::string& pParameterName, const std::string& pSpaceName ) throw (Exception) +{ + try + { + if( mAgentNeighborAssignRegistry.find( pParameterName ) == mAgentNeighborAssignRegistry.end() ) throw Exception( "FLOCK ERROR: no neighbors assigned to parameter " + pParameterName, __FILE__, __FUNCTION__, __LINE__ ); + if( Simulation::get().space().checkSpace(pSpaceName) == false ) throw Exception( "FLOCK ERROR: space " + pSpaceName + " does not exist", __FILE__, __FUNCTION__, __LINE__ ); + + std::vector< NeighborAssignInfo* > neighborAssigns = mAgentNeighborAssignRegistry.at( pParameterName ); + int neighborAssignCount = neighborAssigns.size(); + + for(int nI=neighborAssignCount - 1; nI>=0; --nI) + { + NeighborAssignInfo* neighborAssign = neighborAssigns[nI]; + + if(neighborAssign->mSpaceName == pSpaceName) + { + std::shared_ptr space = Simulation::get().space().space( pSpaceName ); + + if(mAgentParameterList.contains(pParameterName)) + { + // agent parameter (of swarm) + Parameter* parameter = mAgentParameterList.parameter(pParameterName); + space->removeObject( parameter ); + + // agent parameters (of agents) + unsigned int agentCount = mAgents.size(); + + for(unsigned int aI=0; aIparameter(pParameterName); + space->removeObject( parameter ); + } + } + + neighborAssigns.pop_back(); + delete neighborAssign; + } + } + + if(neighborAssigns.size() == 0) + { + mAgentNeighborAssignRegistry.erase( pParameterName ); + } + + } + catch(Exception& e) + { + throw; + } +} + + +unsigned int +Swarm::swarmBehaviorCount() const +{ + return mSwarmBehaviorList.behaviorCount(); +} + +bool +Swarm::checkSwarmBehavior(const std::string& pSwarmBehaviorName) const +{ + return mSwarmBehaviorList.contains(pSwarmBehaviorName); +} + +Behavior* +Swarm::swarmBehavior(const std::string& pBehaviorName) throw (Exception) +{ + try + { + return mSwarmBehaviorList.behavior(pBehaviorName); + } + catch(Exception& e) + { + throw; + } +} + +const Behavior* +Swarm::swarmBehavior(const std::string& pBehaviorName) const throw (Exception) +{ + try + { + return mSwarmBehaviorList.behavior(pBehaviorName); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +Swarm::swarmBehavior(unsigned int pBehaviorIndex) throw (Exception) +{ + try + { + return mSwarmBehaviorList.behavior(pBehaviorIndex); + } + catch(Exception& e) + { + throw; + } +} + +const Behavior* +Swarm::swarmBehavior(unsigned int pBehaviorIndex) const throw (Exception) +{ + try + { + return mSwarmBehaviorList.behavior(pBehaviorIndex); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addSwarmBehavior(Behavior* pBehavior) throw (Exception) +{ + try + { + mSwarmBehaviorList.addBehavior(pBehavior); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addBehavior(const std::string& pBehaviorName, const Behavior& pBehavior) throw (Exception) +{ + try + { + addAgentBehavior(pBehaviorName, pBehavior); + } + catch(Exception& e) + { + throw; + } +} + + +void +Swarm::addBehavior(const std::string& pBehaviorName, unsigned int pBehaviorPosition, const Behavior& pBehavior) throw (Exception) +{ + //std::cout << "Swarm::addBehavior( pBehaviorName " << pBehaviorName << ", pBehaviorPosition " << pBehaviorPosition << ", pBehavior " << pBehavior.className() << " ) begin\n"; + + try + { + addAgentBehavior(pBehaviorName, pBehaviorPosition, pBehavior); + } + catch(Exception& e) + { + throw; + } + + //std::cout << "Swarm::addBehavior( pBehaviorName " << pBehaviorName << ", pBehaviorPosition " << pBehaviorPosition << ", pBehavior " << pBehavior.className() << " ) end\n"; +} + +void +Swarm::addBehavior(const std::string& pBehaviorName, const std::string& pSuccessorBehaviorName, const Behavior& pBehavior) throw (Exception) +{ + //std::cout << "Swarm::addBehavior( pBehaviorName " << pBehaviorName << ", pSuccessorBehaviorName " << pSuccessorBehaviorName << ", pBehavior " << pBehavior.className() << " ) begin\n"; + + try + { + addAgentBehavior(pBehaviorName, pSuccessorBehaviorName, pBehavior); + } + catch(Exception& e) + { + throw; + } + + //std::cout << "Swarm::addBehavior( pBehaviorName " << pBehaviorName.toStdString() << ", pSuccessorBehaviorName " << pSuccessorBehaviorName.toStdString() << ", pBehavior " << pBehavior.className().toStdString() << " ) end\n"; + +} + +void +Swarm::moveBehavior(const std::string& pBehaviorName, unsigned int pBehaviorPosition) throw (Exception) +{ + try + { + moveAgentBehavior(pBehaviorName, pBehaviorPosition); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::moveBehavior(const std::string& pBehaviorName, const std::string& pSuccessorBehaviorName) throw (Exception) +{ + try + { + moveAgentBehavior(pBehaviorName, pSuccessorBehaviorName); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addAgentBehavior(const std::string& pBehaviorName, const Behavior& pBehavior) throw (Exception) +{ + try + { + Agent::addBehavior( pBehaviorName, pBehavior ); + + unsigned int agentCount = mAgents.size(); + + for(unsigned int i=0; iaddBehavior( pBehaviorName, pBehavior ); + } + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addAgentBehavior(const std::string& pBehaviorName, unsigned int pBehaviorPosition, const Behavior& pBehavior) throw (Exception) +{ + try + { + Agent::addBehavior( pBehaviorName, pBehaviorPosition, pBehavior ); + + unsigned int agentCount = mAgents.size(); + + for(unsigned int i=0; iaddBehavior( pBehaviorName, pBehaviorPosition, pBehavior ); + } + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addAgentBehavior(const std::string& pBehaviorName, const std::string& pSuccessorBehaviorName, const Behavior& pBehavior) throw (Exception) +{ + // std::cout << "Swarm::addAgentBehavior( pBehaviorName " << pBehaviorName << ", pSuccessorBehaviorName " << pSuccessorBehaviorName << ", pBehavior " << pBehavior.className()<< " ) begin\n"; + + try + { + //std::cout << "swarm agent\n"; + + Agent::addBehavior( pBehaviorName, pSuccessorBehaviorName, pBehavior ); + + unsigned int agentCount = mAgents.size(); + + for(unsigned int i=0; iaddBehavior( pBehaviorName, pSuccessorBehaviorName, pBehavior ); + } + } + catch(Exception& e) + { + throw; + } + + // std::cout << "Swarm::addAgentBehavior( pBehaviorName " << pBehaviorName.toStdString() << ", pSuccessorBehaviorName " << pSuccessorBehaviorName.toStdString() << ", pBehavior " << pBehavior.className().toStdString() << " ) end\n"; +} + +void +Swarm::moveAgentBehavior(const std::string& pBehaviorName, unsigned int pBehaviorPosition) throw (Exception) +{ + try + { + Agent::moveBehavior( pBehaviorName, pBehaviorPosition ); + + unsigned int agentCount = mAgents.size(); + + for(unsigned int i=0; imoveBehavior( pBehaviorName, pBehaviorPosition ); + } + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::moveAgentBehavior(const std::string& pBehaviorName, const std::string& pSuccessorBehaviorName) throw (Exception) +{ + try + { + Agent::moveBehavior( pBehaviorName, pSuccessorBehaviorName ); + + unsigned int agentCount = mAgents.size(); + + for(unsigned int i=0; imoveBehavior( pBehaviorName, pSuccessorBehaviorName ); + } + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::addSwarmBehavior(const std::string& pBehaviorName, const Behavior& pBehavior) throw (Exception) +{ + //std::cout << "Swarm::addSwarmBehavior(const base::String& pBehaviorName, const Behavior& pBehavior) begin\n"; + + if( mSwarmBehaviorList.contains(pBehaviorName) == true ) throw Exception( "FLOCK ERROR: swarm behavior name " + pBehaviorName + " already exists", __FILE__, __FUNCTION__, __LINE__ ); + + + Behavior* behavior; + + try + { + behavior = pBehavior.create(pBehaviorName, this); + mSwarmBehaviorList.addBehavior(behavior); + } + catch(Exception& e) + { + std::cout << e << "\n"; + + delete behavior; + throw; + } + + //std::cout << "Swarm::addSwarmBehavior(const base::String& pBehaviorName, const Behavior& pBehavior) end\n"; +} + +void +Swarm::addSwarmBehavior(const std::string& pBehaviorName, unsigned int pBehaviorPosition, const Behavior& pBehavior) throw (Exception) +{ + if( mSwarmBehaviorList.contains(pBehaviorName) == true ) throw Exception( "FLOCK ERROR: swarm behavior name " + pBehaviorName + " already exists", __FILE__, __FUNCTION__, __LINE__ ); + + Behavior* behavior; + + try + { + behavior = pBehavior.create(pBehaviorName, this); + mSwarmBehaviorList.addBehavior(behavior, pBehaviorPosition); + } + catch(Exception& e) + { + if(behavior != nullptr) delete behavior; + + throw; + } +} + +void +Swarm::addSwarmBehavior(const std::string& pBehaviorName, const std::string& pSuccessorBehaviorName, const Behavior& pBehavior) throw (Exception) +{ + try + { + int pSuccessorBehaviorPosition = mSwarmBehaviorList.behaviorIndex(pSuccessorBehaviorName); + addSwarmBehavior(pBehaviorName, pSuccessorBehaviorPosition, pBehavior); + } + catch (Exception& e) + { + throw; + } +} + +void +Swarm::moveSwarmBehavior(const std::string& pBehaviorName, unsigned int pBehaviorPosition) throw (Exception) +{ + try + { + int oldBehaviorPosition = mSwarmBehaviorList.behaviorIndex(pBehaviorName); + mSwarmBehaviorList.moveBehavior(oldBehaviorPosition, pBehaviorPosition); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::moveSwarmBehavior(const std::string& pBehaviorName, const std::string& pSuccessorBehaviorName) throw (Exception) +{ + try + { + int oldBehaviorPosition = mSwarmBehaviorList.behaviorIndex(pBehaviorName); + int newBehaviorPosition = mSwarmBehaviorList.behaviorIndex(pBehaviorName); + + if( oldBehaviorPosition == newBehaviorPosition ) return; + else if( oldBehaviorPosition < newBehaviorPosition ) mSwarmBehaviorList.moveBehavior(oldBehaviorPosition, newBehaviorPosition - 1 ); + else mSwarmBehaviorList.moveBehavior(oldBehaviorPosition, newBehaviorPosition ); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::removeBehavior(const std::string& pBehaviorName) throw (Exception) +{ + try + { + removeAgentBehavior(pBehaviorName); + } + catch(Exception& e) + { + throw; + } +} + + +void +Swarm::removeAgentBehavior(const std::string& pBehaviorName) throw (Exception) +{ + //std::cout << "remove behavior " << pBehaviorName.toStdString() << " begin\n"; + + try + { + // remove behaviors + unsigned int agentCount = mAgents.size(); + for(unsigned int agentNr=0; agentNr < agentCount; ++agentNr) mAgents[agentNr]->removeBehavior( pBehaviorName ); + Agent::removeBehavior( pBehaviorName ); + } + catch(Exception& e) + { + throw; + } + + //std::cout << "remove behavior " << pBehaviorName.toStdString() << " end\n"; +} + +void +Swarm::removeSwarmBehavior(const std::string& pBehaviorName) throw (Exception) +{ + try + { + mBehaviorList.removeBehavior(pBehaviorName); + } + catch(Exception& e) + { + throw; + } +} + +void +Swarm::act() +{ + // perform agent behaviors + Agent::act(); + + //std::cout << "agent " << mName.toStdString() << " act\n"; + + if( mSwarmParameterList.parameter(0)->value() == 0.0 ) return; + + // update agent parameter indices of the behaviors before performing swarm behaviors + SwarmBehavior* swarmBehavior; + unsigned int bC = mSwarmBehaviorList.behaviorCount(); + for(unsigned bI=0; bI < bC; ++bI) + { + swarmBehavior = dynamic_cast( mSwarmBehaviorList.behavior(bI) ); + if(swarmBehavior != nullptr) swarmBehavior->createAgentParameterIndices(); + } + + // perform swarm behaviors + mSwarmBehaviorList.act(); +} + +void +Swarm::flush() +{ + mSwarmParameterList.flush(); + + unsigned int aC = mAgents.size(); + for(unsigned int aI=0; aIflush(); +} + +void +Swarm::notify() +{} + +Swarm::operator std::string() const +{ + return info(); +} + +std::string +Swarm::info(int pPropagationLevel) const +{ + std::stringstream ss; + + ss << mName << "\n"; + ss << " agentCount: " << mAgents.size() << "\n"; + + if(pPropagationLevel != 0) + { + ss << Agent::info(pPropagationLevel - 1); + } + + if(pPropagationLevel < 0 || pPropagationLevel >= 2) + { + for( unsigned int i=0; iinfo(pPropagationLevel - 2); + } + + return ss.str(); +} + diff --git a/src/dab_flock_swarm.h b/src/dab_flock_swarm.h new file mode 100644 index 0000000..dd4191e --- /dev/null +++ b/src/dab_flock_swarm.h @@ -0,0 +1,897 @@ +/** \file dab_flock_swarm.h + * + * Created by Daniel Bisig on 10/9/07. + * Ported to OpenFrameworks by Daniel Bisig on 10/8/17. + */ + +#ifndef _dab_flock_swarm_h_ +#define _dab_flock_swarm_h_ + +#include "dab_listener.h" +#include "dab_flock_agent.h" +#include "dab_flock_parameter.h" +#include "dab_flock_behavior.h" +#include "dab_space_neighbor_group_alg.h" +#include + +namespace dab +{ + +namespace flock +{ + +class NeighborAssignInfo +{ +public: + + std::string mParameterName; + std::string mSpaceName; + bool mVisible; + space::NeighborGroupAlg* mNeighborGroupAlg; + + NeighborAssignInfo( std::string pParameterName, std::string pSpaceName, bool pVisible, space::NeighborGroupAlg* pNeighborGroupAlg ) + : mParameterName( pParameterName ) + , mSpaceName( pSpaceName ) + , mVisible( pVisible ) + , mNeighborGroupAlg( pNeighborGroupAlg ) + {}; + + ~NeighborAssignInfo() + { + if(mNeighborGroupAlg != nullptr) delete mNeighborGroupAlg; + }; +}; + +class Swarm : public Agent, public UpdateListener +{ +public: + /** + \brief create swarm + \param pName swarm name + */ + Swarm(const std::string& pName); + + /** + \brief copy constructor + \param pName swarm name + \param pSwarm swarm to copy from + */ + Swarm(const std::string& pName, const Swarm& pSwarm); + + /** + \brief destructor + */ + ~Swarm(); + + // TODO: figure out to properly deal with the combination of smart and simple pointers + + /** + \brief clear swarm + \remark triggers destructor + */ + void clear(); + + /** + \brief return number of agents + \return number of agents + */ + unsigned int agentCount() const; + + /** + \brief return agents + \return agents + */ + std::vector& agents(); + + /** + \brief return agents + \return agents + */ + const std::vector& agents() const; + + /** + \brief add single agent to swarm + \exception Exception failed to add agent + */ + void addAgent() throw (Exception); + + /** + \brief add a number of agents to swarm + \param pAgentCount number of agents to add + \exception Exception failed to add agents + */ + void addAgents(unsigned int pAgentCount) throw (Exception); + + /** + \brief remove last agent from swarm + \exception Exception failed to remove agent + */ + void removeAgent() throw (Exception); + + /** + \brief remove particular agent from swarm + \exception Exception failed to remove agent + */ + void removeAgent(unsigned int pAgentIndex) throw (Exception); + + /** + \brief remove the last n agents from swarm + \param pAgentCount number of agents to remove + \exception Exception failed to remove agents + */ + void removeAgents(unsigned int pAgentCount) throw (Exception); + + /** + \brief remove agents starting from an agent index + \brief pAgentIndex start agent from where agents will be removed + \param pAgentCount number of agents to remove + \exception Exception failed to remove agents + */ + void removeAgents(unsigned int pAgentIndex, unsigned int pAgentCount) throw (Exception); + + /** + \brief remove all agents from swarm + \exception Exception failed to remove agents + */ + void removeAgents() throw (Exception); + + /** + \brief return number of swarm parameters the swarm contains + \return number of swarm parameters the swarm contains + */ + unsigned int swarmParameterCount() const; + + /** + \brief check if swarm has swarm parameter + \param pSwarmParameterName swarm parameter name + \return true if swarm possesses a particular swarm parameter + */ + bool checkSwarmParameter(const std::string& pSwarmParameterName) const; + + /** + \brief get swarm parameter + \param pParameterName swarm parameter name + \return parameter + \exception Exception swarm parameter does not exist + */ + Parameter* swarmParameter(const std::string& pParameterName) throw (Exception); + + /** + \brief get swarm parameter + \param pParameterName swarm parameter name + \return parameter + \exception Exception swarm parameter does not exist + */ + const Parameter* swarmParameter(const std::string& pParameterName) const throw (Exception); + + /** + \brief get swarm parameter + \param pParameterIndex swarm parameter index + \return parameter + \exception Exception swarm parameter does not exist + */ + Parameter* swarmParameter(unsigned int pParameterIndex) throw (Exception); + + /** + \brief get swarm parameter + \param pParameterIndex swarm parameter index + \return parameter + \exception Exception swarm parameter does not exist + */ + const Parameter* swarmParameter(unsigned int pParameterIndex) const throw (Exception); + + /** + \brief get agent parameter + \param pAgentIndex agent index + \param pParameterName agent parameter name + \return parameter + \exception Exception agent does not exist or agent parameter does not exist + */ + Parameter* parameter(unsigned int pAgentIndex, const std::string& pParameterName) throw (Exception); + + /** + \brief get agent parameter + \param pAgentIndex agent index + \param pParameterName agent parameter name + \return parameter + \exception Exception agent does not exist or agent parameter does not exist + */ + const Parameter* parameter(unsigned int pAgentIndex, const std::string& pParameterName) const throw (Exception); + + /** + \brief get agent parameter + \param pAgentIndex agent index + \param pParameterIndex agent parameter index + \return parameter + \exception Exception agent does not exist or agent parameter does not exist + */ + Parameter* parameter(unsigned int pAgentIndex, unsigned int pParameterIndex) throw (Exception); + + /** + \brief get agent parameter + \param pAgentIndex agent index + \param pParameterIndex agent parameter index + \return parameter + \exception Exception agent does not exist or agent parameter does not exist + */ + const Parameter* parameter(unsigned int pAgentIndex, unsigned int pParameterIndex) const throw (Exception); + + /** + \brief get agent parameter + \param pAgentIndex agent index + \param pParameterName agent parameter name + \return parameter + \exception Exception agent does not exist or agent parameter does not exist + */ + Parameter* agentParameter(unsigned int pAgentIndex, const std::string& pParameterName) throw (Exception); + + /** + \brief get agent parameter + \param pAgentIndex agent index + \param pParameterName agent parameter name + \return parameter + \exception Exception agent does not exist or agent parameter does not exist + */ + const Parameter* agentParameter(unsigned int pAgentIndex, const std::string& pParameterName) const throw (Exception); + + /** + \brief get agent parameter + \param pAgentIndex agent index + \param pParameterIndex agent parameter index + \return parameter + \exception Exception agent does not exist or agent parameter does not exist + */ + Parameter* agentParameter(unsigned int pAgentIndex, unsigned int pParameterIndex) throw (Exception); + + /** + \brief get agent parameter + \param pAgentIndex agent index + \param pParameterIndex agent parameter index + \return parameter + \exception Exception agent does not exist or agent parameter does not exist + */ + const Parameter* agentParameter(unsigned int pAgentIndex, unsigned int pParameterIndex) const throw (Exception); + + /** + \brief add agent parameter + \param pParameter agent parameter + \exception Exception agent parameter name already exists + */ + void addParameter(Parameter* pParameter) throw (Exception); + + /** + \brief add agent parameter + \param pParameter agent parameter + \exception Exception agent parameter name already exists + */ + void addAgentParameter(Parameter* pParameter) throw (Exception); + + /** + \brief add swarm parameter + \param pParameter swarm parameter + \exception Exception swarm parameter name already exists + */ + void addSwarmParameter(Parameter* pParameter) throw (Exception); + + /** + \brief create agent parameter + \param pName agent parameter name + \param pDim dimension of agent parameter (> 0) + \exception Exception agent parameter name already exists + */ + void addParameter(const std::string& pName, unsigned int pDim) throw (Exception); + + /** + \brief create agent parameter + \param pName agent parameter name + \param pDim dimension of agent parameter (> 0) + \exception Exception agent parameter name already exists + */ + void addAgentParameter(const std::string& pName, unsigned int pDim) throw (Exception); + + /** + \brief create swarm parameter + \param pName swarm parameter name + \param pDim dimension of swarm parameter (> 0) + \exception Exception swarm parameter name already exists + */ + void addSwarmParameter(const std::string& pName, unsigned int pDim) throw (Exception); + + /** + \brief create agent parameter + \param pName agent parameter name + \param pDim dimension of agent parameter (> 0) + \param pValue uniform agent parameter value + \exception Exception agent parameter name already exists + */ + void addParameter(const std::string& pName, unsigned int pDim, float pValue) throw (Exception); + + /** + \brief create agent parameter + \param pName agent parameter name + \param pDim dimension of agent parameter (> 0) + \param pValue uniform agent parameter value + \exception Exception agent parameter name already exists + */ + void addAgentParameter(const std::string& pName, unsigned int pDim, float pValue) throw (Exception); + + /** + \brief create swarm parameter + \param pName swarm parameter name + \param pDim dimension of swarm parameter (> 0) + \param pValue uniform swarm parameter value + \exception Exception swarm parameter name already exists + */ + void addSwarmParameter(const std::string& pName, unsigned int pDim, float pValue) throw (Exception); + + /** + \brief create agent parameter + \param pName agent parameter name + \param pValues agent parameter values + \exception Exception agent parameter name already exists + */ + void addParameter(const std::string& pName, const std::initializer_list& pValues) throw (Exception); + + /** + \brief create agent parameter + \param pName agent parameter name + \param pValues agent parameter values + \exception Exception agent parameter name already exists + */ + void addParameter(const std::string& pName, const Eigen::VectorXf& pValues) throw (Exception); + + /** + \brief create agent parameter + \param pName agent parameter name + \param pValues agent parameter values + \exception Exception agent parameter name already exists + */ + void addAgentParameter(const std::string& pName, const std::initializer_list& pValues) throw (Exception); + + /** + \brief create agent parameter + \param pName agent parameter name + \param pValues agent parameter values + \exception Exception agent parameter name already exists + */ + void addAgentParameter(const std::string& pName, const Eigen::VectorXf& pValues) throw (Exception); + + /** + \brief create swarm parameter + \param pName swarm parameter name + \param pValues swarm parameter values + \exception Exception swarm parameter name already exists + */ + void addSwarmParameter(const std::string& pName, const std::initializer_list& pValues) throw (Exception); + + /** + \brief create swarm parameter + \param pName swarm parameter name + \param pValues swarm parameter values + \exception Exception swarm parameter name already exists + */ + void addSwarmParameter(const std::string& pName, const Eigen::VectorXf& pValues) throw (Exception); + + /** + \brief remove agent parameter + \param pName agent parameter + \exception Exception failed to remove agent parameter + */ + void removeParameter( const std::string pName ) throw (Exception); + + /** + \brief remove agent parameter + \param pName agent parameter + \exception Exception failed to remove agent parameter + */ + void removeAgentParameter( const std::string pName ) throw (Exception); + + /** + \brief remove agent parameter + \param pName agent parameter + \exception Exception failed to remove agent parameter + */ + void removeSwarmParameter( const std::string pName ) throw (Exception); + + /** + \brief set parameter values + \param pParameterName parameter name + \param pParameterValue parameter value + \exception Exception parameter name is not found + */ + void set(const std::string& pParameterName, float pParameterValue) throw (Exception); + + /** + \brief set parameter values + \param pAgentIndex agent index + \param pParameterName parameter name + \param pParameterValue parameter value + \exception Exception agent index out of bounds or parameter name is not found + */ + void set(unsigned int pAgentIndex, const std::string& pParameterName, float pParameterValue) throw (Exception); + + /** + \brief set parameter values + \param pParameterName parameter name + \param pParameterValues parameter values + \exception Exception parameter name is not found or parameter values has wrong dimension + */ + void set(const std::string& pParameterName, const std::initializer_list& pParameterValues) throw (Exception); + + /** + \brief set parameter values + \param pParameterName parameter name + \param pParameterValues parameter values + \exception Exception parameter name is not found or parameter values has wrong dimension + */ + void set(const std::string& pParameterName, const Eigen::VectorXf& pParameterValues) throw (Exception); + + /** + \brief set parameter values + \param pAgentIndex agent index + \param pParameterName parameter name + \param pParameterValues parameter values + \exception Exception agent index out of bounds or parameter name is not found + */ + void set(unsigned int pAgentIndex, const std::string& pParameterName, const std::initializer_list& pParameterValues) throw (Exception); + + /** + \brief set parameter values + \param pAgentIndex agent index + \param pParameterName parameter name + \param pParameterValues parameter values + \exception Exception agent index out of bounds or parameter name is not found + */ + void set(unsigned int pAgentIndex, const std::string& pParameterName, const Eigen::VectorXf& pParameterValues) throw (Exception); + + /** + \brief randomize parameter value + \param pParameterName parameter name + \param pMinParameterValue minimum parameter value + \param pMaxParameterValue maximum parameter value + \exception Exception parameter name not found + */ + void randomize(const std::string& pParameterName, float pMinParameterValue, float pMaxParameterValue) throw (Exception); + + /** + \brief randomize parameter value + \param pAgentIndex agent index + \param pParameterName parameter name + \param pMinParameterValue minimum parameter value + \param pMaxParameterValue maximum parameter value + \exception Exception agent index out of bounds or parameter name is not found + */ + void randomize(unsigned int pAgentIndex, const std::string& pParameterName, float pMinParameterValue, float pMaxParameterValue) throw (Exception); + + /** + \brief randomize parameter values + \param pParameterName parameter name + \param pMinParameterValues minimum parameter values + \param pMaxParameterValues maximum parameter values + \exception Exception parameter name not found or parameter values has wrong dimension + */ + void randomize(const std::string& pParameterName, const std::initializer_list& pMinParameterValues, const std::initializer_list& pMaxParameterValues) throw (Exception); + + /** + \brief randomize parameter values + \param pParameterName parameter name + \param pMinParameterValues minimum parameter values + \param pMaxParameterValues maximum parameter values + \exception Exception parameter name not found or parameter values has wrong dimension + */ + void randomize(const std::string& pParameterName, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues) throw (Exception); + + /** + \brief randomize parameter values + \param pAgentIndex agent index + \param pParameterName parameter name + \param pMinParameterValues minimum parameter values + \param pMaxParameterValues maximum parameter values + \exception Exception agent index out of bounds, parameter name not found or parameter values has wrong dimension + */ + void randomize(unsigned int pAgentIndex, const std::string& pParameterName, const std::initializer_list& pMinParameterValues, const std::initializer_list& pMaxParameterValues) throw (Exception); + + /** + \brief randomize parameter values + \param pAgentIndex agent index + \param pParameterName parameter name + \param pMinParameterValues minimum parameter values + \param pMaxParameterValues maximum parameter values + \exception Exception agent index out of bounds, parameter name not found or parameter values has wrong dimension + */ + void randomize(unsigned int pAgentIndex, const std::string& pParameterName, const Eigen::VectorXf& pMinParameterValues, const Eigen::VectorXf& pMaxParameterValues) throw (Exception); + + std::vector< NeighborAssignInfo* > agentNeighborInfo( const std::string& pParameterName ); + std::vector< NeighborAssignInfo* > swarmNeighborInfo( const std::string& pParameterName ); + + /** + \brief assign neighbors for an agent and/or swarm parameter + \param pParameterName parameter name + \param pSpaceName name of neighbor space + \param pVisible whether parameter is visible + \param pNeighborGroupAlg neighbor group algorithm + \exception Exception parameter not found, space not found, parameter and space dimension mismatch + */ + void assignNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible, space::NeighborGroupAlg* pNeighborGroupAlg ) throw (Exception); + + /** + \brief assign neighbors for a agent parameter + \param pParameterName agent parameter name + \param pSpaceName name of neighbor space + \param pVisible whether parameter is visible + \param pNeighborGroupAlg neighbor group algorithm + \exception Exception parameter not found, space not found, parameter and space dimension mismatch + */ + void assignAgentNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible, space::NeighborGroupAlg* pNeighborGroupAlg ) throw (Exception); + + /** + \brief assign neighbors for a swarm parameter + \param pParameterName swarm parameter name + \param pSpaceName name of neighbor space + \param pVisible whether parameter is visible + \param pNeighborGroupAlg neighbor group algorithm + \exception Exception parameter not found, space not found, parameter and space dimension mismatch + */ + void assignSwarmNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible, space::NeighborGroupAlg* pNeighborGroupAlg ) throw (Exception); + + /** + \brief assign neighbors for an agent parameter + \param pParameterName parameter name + \param pSpaceName name of neighbor space + \param pVisible whether parameter is visible + \exception Exception parameter not found, space not found, parameter and space dimension mismatch + + simpified assignNeighbors method that passes nullptr for NeighborGroupAlg + */ + void assignNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible ) throw (Exception); + + /** + \brief assign neighbors for an agent parameter + \param pParameterName parameter name + \param pSpaceName name of neighbor space + \param pVisible whether parameter is visible + \exception Exception parameter not found, space not found, parameter and space dimension mismatch + + simpified assignNeighbors method that passes nullptr for NeighborGroupAlg + */ + void assignAgentNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible ) throw (Exception); + + /** + \brief assign neighbors for a swarm parameter + \param pParameterName parameter name + \param pSpaceName name of neighbor space + \param pVisible whether parameter is visible + \exception Exception parameter not found, space not found, parameter and space dimension mismatch + + simpified assignNeighbors method that passes nullptr for NeighborGroupAlg + */ + void assignSwarmNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible ) throw (Exception); + + /** + \brief assign neighbors for an agent parameter + \param pParameterName parameter name + \param pSpaceName name of neighbor space + \param pVisible whether parameter is visible + \param pNeighborRadius radius within which neighbors are searched + \param pMaxNeighborCount maximum number of neighbors in neighbor list if >= 0 (-1: no limit) + \param pReplaceNeighborMode replace more distant neighbors with closer neighbors if true + \exception Exception parameter not found, space not found, parameter and space dimension mismatch + + simpified assignNeighbors method that automaticall creates a NeighborGroupAlg. + */ + void assignNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible, float pNeighborRadius, int pMaxNeighborCount, bool pReplaceNeighborMode ) throw (Exception); + + /** + \brief assign neighbors for an agent parameter + \param pParameterName parameter name + \param pSpaceName name of neighbor space + \param pVisible whether parameter is visible + \param pNeighborRadius radius within which neighbors are searched + \param pMaxNeighborCount maximum number of neighbors in neighbor list if >= 0 (-1: no limit) + \param pReplaceNeighborMode replace more distant neighbors with closer neighbors if true + \exception Exception parameter not found, space not found, parameter and space dimension mismatch + + simpified assignNeighbors method that automaticall creates a NeighborGroupAlg. + */ + void assignAgentNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible, float pNeighborRadius, int pMaxNeighborCount, bool pReplaceNeighborMode ) throw (Exception); + + /** + \brief assign neighbors for a swarm parameter + \param pParameterName parameter name + \param pSpaceName name of neighbor space + \param pVisible whether parameter is visible + \param pNeighborRadius radius within which neighbors are searched + \param pMaxNeighborCount maximum number of neighbors in neighbor list if >= 0 (-1: no limit) + \param pReplaceNeighborMode replace more distant neighbors with closer neighbors if true + \exception Exception parameter not found, space not found, parameter and space dimension mismatch + + simpified assignNeighbors method that automaticall creates a NeighborGroupAlg. + */ + void assignSwarmNeighbors( const std::string& pParameterName, const std::string& pSpaceName, bool pVisible, float pNeighborRadius, int pMaxNeighborCount, bool pReplaceNeighborMode ) throw (Exception); + + /** + \brief remove neighbors for an agent parameter + \param pParameterName parameter name + \param pSpaceName name of neighbor space + \exception Exception parameter not found, space not found + */ + void removeNeighbors( const std::string& pParameterName, const std::string& pSpaceName ) throw (Exception); + + /** + \brief remove neighbors for an agent parameter + \param pParameterName parameter name + \param pSpaceName name of neighbor space + \exception Exception parameter not found, space not found + */ + void removeAgentNeighbors( const std::string& pParameterName, const std::string& pSpaceName ) throw (Exception); + + /** + \brief remove neighbors for a swarm parameter + \param pParameterName parameter name + \param pSpaceName name of neighbor space + \exception Exception parameter not found, space not found + */ + void removeSwarmNeighbors( const std::string& pParameterName, const std::string& pSpaceName ) throw (Exception); + + /** + \brief return number of swarm behaviors the swarm contains + \return number of swarm behaviors the swarm contains + */ + unsigned int swarmBehaviorCount() const; + + /** + \brief check if swarm has swarm behavior + \param pSwarmBehaviorName swarm behavior name + \return true if swarm possesses a particular swarm behavior + */ + bool checkSwarmBehavior(const std::string& pSwarmBehaviorName) const; + + /** + \brief get swarm behavior + \param pBehaviorName swarm behavior name + \return swarm behavior + \exception FlockException swarm behavior does not exist + */ + Behavior* swarmBehavior(const std::string& pBehaviorName) throw (Exception); + + /** + \brief get swarm behavior + \param pBehaviorName swarm behavior name + \return swarm behavior + \exception FlockException swarm behavior does not exist + */ + const Behavior* swarmBehavior(const std::string& pBehaviorName) const throw (Exception); + + /** + \brief get swarm behavior + \param pBehaviorIndex swarm behavior index + \return swarm behavior + \exception FlockException swarm behavior does not exist + */ + Behavior* swarmBehavior(unsigned int pBehaviorIndex) throw (Exception); + + /** + \brief get swarm behavior + \param pBehaviorIndex swarm behavior index + \return swarm behavior + \exception FlockException swarm behavior does not exist + */ + const Behavior* swarmBehavior(unsigned int pBehaviorIndex) const throw (Exception); + + /** + \brief add swarm behavior + \param pBehavior swarm behavior + \exception Exception swarm behavior already exists + */ + void addSwarmBehavior(Behavior* pBehavior) throw (Exception); + + /** + \brief add agent behavior + \param pBehaviorName behavior name + \param pBehavior behavior + \exception Exception behavior already exists or Illegal Behavior Parameters + */ + void addBehavior(const std::string& pBehaviorName, const Behavior& pBehavior) throw (Exception); + + /** + \brief add agent behavior + \param pBehaviorName behavior name + \param pBehaviorPosition behavior position + \param pBehavior behavior + \exception Exception behavior already exists or Illegal Behavior Parameters + */ + void addBehavior(const std::string& pBehaviorName, unsigned int pBehaviorPosition, const Behavior& pBehavior) throw (Exception); + + /** + \brief add agent behavior + \param pBehaviorName behavior name + \param pSuccessorBehaviorName name of behavior in front of which the new behavior is inserted + \param pBehavior behavior + \exception Exception behavior already exists or Illegal Behavior Parameters + */ + void addBehavior(const std::string& pBehaviorName, const std::string& pSuccessorBehaviorName, const Behavior& pBehavior) throw (Exception); + + /** + \brief move agent behavior + \param pBehaviorName behavior name + \param pBehaviorPosition behavior position + \exception FlockException behavior not found + */ + void moveBehavior(const std::string& pBehaviorName, unsigned int pBehaviorPosition) throw (Exception); + + /** + \brief move agent behavior + \param pBehaviorName behavior name + \param pSuccessorBehaviorName name of behavior in front of which the new behavior is inserted + \exception Exception behavior not found + */ + void moveBehavior(const std::string& pBehaviorName, const std::string& pSuccessorBehaviorName) throw (Exception); + + /** + \brief add agent behavior + \param pBehaviorName agent behavior name + \param pBehavior agent behavior + \exception Exception agent behavior already exists or Illegal Behavior Parameters + */ + void addAgentBehavior(const std::string& pBehaviorName, const Behavior& pBehavior) throw (Exception); + + /** + \brief add agent behavior + \param pBehaviorName behavior name + \param pBehaviorPosition behavior position + \param pBehavior behavior + \exception Exception behavior already exists or Illegal Behavior Parameters + */ + void addAgentBehavior(const std::string& pBehaviorName, unsigned int pBehaviorPosition, const Behavior& pBehavior) throw (Exception); + + /** + \brief add agent behavior + \param pBehaviorName behavior name + \param pSuccessorBehaviorName name of behavior in front of which the new behavior is inserted + \param pBehavior behavior + \exception Exception behavior already exists or Illegal Behavior Parameters + */ + void addAgentBehavior(const std::string& pBehaviorName, const std::string& pSuccessorBehaviorName, const Behavior& pBehavior) throw (Exception); + + /** + \brief move agent behavior + \param pBehaviorName behavior name + \param pBehaviorPosition behavior position + \exception Exception behavior not found + */ + void moveAgentBehavior(const std::string& pBehaviorName, unsigned int pBehaviorPosition) throw (Exception); + + /** + \brief move agent behavior + \param pBehaviorName behavior name + \param pSuccessorBehaviorName name of behavior in front of which the new behavior is inserted + \exception Exception behavior not found + */ + void moveAgentBehavior(const std::string& pBehaviorName, const std::string& pSuccessorBehaviorName) throw (Exception); + + /** + \brief add swarm behavior + \param pBehaviorName swarm behavior name + \param pBehavior swarm behavior + \exception Exception swarm behavior already exists or Illegal Behavior Parameters + */ + void addSwarmBehavior(const std::string& pBehaviorName, const Behavior& pBehavior) throw (Exception); + + /** + \brief add swarm behavior + \param pBehaviorName behavior name + \param pBehaviorPosition behavior position + \param pBehavior behavior + \exception Exception behavior already exists or Illegal Behavior Parameters + */ + void addSwarmBehavior(const std::string& pBehaviorName, unsigned int pBehaviorPosition, const Behavior& pBehavior) throw (Exception); + + /** + \brief add swarm behavior + \param pBehaviorName behavior name + \param pSuccessorBehaviorName name of behavior in front of which the new behavior is inserted + \param pBehavior behavior + \exception Exception behavior already exists or Illegal Behavior Parameters + */ + void addSwarmBehavior(const std::string& pBehaviorName, const std::string& pSuccessorBehaviorName, const Behavior& pBehavior) throw (Exception); + + /** + \brief move swarm behavior + \param pBehaviorName behavior name + \param pBehaviorPosition behavior position + \exception Exception behavior not found + */ + void moveSwarmBehavior(const std::string& pBehaviorName, unsigned int pBehaviorPosition) throw (Exception); + + /** + \brief move swarm behavior + \param pBehaviorName behavior name + \param pSuccessorBehaviorName name of behavior in front of which the new behavior is inserted + \exception Exception behavior not found + */ + void moveSwarmBehavior(const std::string& pBehaviorName, const std::string& pSuccessorBehaviorName) throw (Exception); + + /** + \brief remove agent behavior + \param pBehaviorName agent behavior name + \exception Exception failed to remove agent behavior + */ + void removeBehavior(const std::string& pBehaviorName) throw (Exception); + + /** + \brief remove agent behavior + \param pBehaviorName agent behavior name + \exception Exception failed to remove agent behavior + */ + void removeAgentBehavior(const std::string& pBehaviorName) throw (Exception); + + /** + \brief remove swarm behavior + \param pBehaviorName swarm behavior name + \exception Exception failed to remove swarm behavior + */ + void removeSwarmBehavior(const std::string& pBehaviorName) throw (Exception); + + /** + \brief perform behaviors + */ + virtual void act(); + + /** + \brief update parameters + */ + virtual void flush(); + + /** + \brief notify swarm whenever the simulation progresses a step + */ + void notify(); + + /** + \brief print swarm information + */ + virtual operator std::string() const; + + /** + \brief print swarm information + \param pPropagationLevel how far the propagation method proceeds through composite classes (-1: unlimited, 0: no proceeding, >0: limited proceeding) + */ + virtual std::string info(int pPropagationLevel = 0) const; + + /** + \brief print swarm information + */ + friend std::ostream& operator<< (std::ostream& pOstream, const Swarm& pSwarm) + { + pOstream << pSwarm.info(); + + return pOstream; + }; + + static unsigned int sInstanceCount; /// \brief total number of swarm instances ever created + +protected: + /** + \brief default constructor + */ + Swarm(); + + std::shared_ptr mSelf; + + ParameterList& mAgentParameterList; /// \brief list of agent parameters + BehaviorList& mAgentBehaviorList; /// \brief list of agent behaviors + ParameterList mSwarmParameterList; /// \brief swarm exclusive list of parameters + BehaviorList mSwarmBehaviorList; /// \brief swarm exclusive list of behaviors + std::vector mAgents; /// \brief swarm agents + + unsigned int mAgentCreationCount; /// \brief numbers of agents ever created for this swarm + + std::map< std::string, std::vector > mAgentNeighborAssignRegistry; /// \brief registry for all agent parameters that are assigned to some neighbor space + std::map< std::string, std::vector > mSwarmNeighborAssignRegistry; /// \brief registry for all swarm parameters that are assigned to some neighbor space +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_swarm_behavior.cpp b/src/dab_flock_swarm_behavior.cpp new file mode 100644 index 0000000..d3976ce --- /dev/null +++ b/src/dab_flock_swarm_behavior.cpp @@ -0,0 +1,344 @@ +/** \file iso_flock_swarm_behavior.cpp + */ + + +#include "dab_flock_swarm_behavior.h" +#include "dab_flock_swarm.h" +#include "dab_tokenizer.h" + +using namespace dab; +using namespace dab::flock; + +SwarmBehavior::SwarmBehavior() +: Behavior() +, mSwarm(nullptr) +, mInputAgentParameters(mInputParameters) +, mInputAgentNeighborGroups(mInputNeighborGroups) +, mOutputAgentParameters(mOutputParameters) +, mOutputAgentNeighborGroups(mOutputNeighborGroups) +, mInternalAgentParameters(mInternalParameters) +{ + mClassName = "SwarmBehavior"; +} + +SwarmBehavior::SwarmBehavior(const std::string& pInputSwarmParameterString, const std::string& pInputAgentParameterString, const std::string& pOutputSwarmParameterString, const std::string& pOutputAgentParameterString) +: Behavior(pInputAgentParameterString, pOutputAgentParameterString) +, mSwarm(nullptr) +, mInputSwarmParameterString(pInputSwarmParameterString) +, mOutputSwarmParameterString(pOutputSwarmParameterString) +, mInputAgentParameters(mInputParameters) +, mInputAgentNeighborGroups(mInputNeighborGroups) +, mOutputAgentParameters(mOutputParameters) +, mOutputAgentNeighborGroups(mOutputNeighborGroups) +, mInternalAgentParameters(mInternalParameters) +{ + mClassName = "SwarmBehavior"; +} + +SwarmBehavior::SwarmBehavior(Swarm* pSwarm, const std::string& pSwarmBehaviorName, const std::string& pInputSwarmParameterString, const std::string& pInputAgentParameterString, const std::string& pOutputSwarmParameterString, const std::string& pOutputAgentParameterString) +: Behavior(pInputAgentParameterString, pOutputAgentParameterString) +, mSwarm(pSwarm) +, mInputSwarmParameterString(pInputSwarmParameterString) +, mOutputSwarmParameterString(pOutputSwarmParameterString) +, mInputAgentParameters(mInputParameters) +, mInputAgentNeighborGroups(mInputNeighborGroups) +, mOutputAgentParameters(mOutputParameters) +, mOutputAgentNeighborGroups(mOutputNeighborGroups) +, mInternalAgentParameters(mInternalParameters) +{ + mAgent = pSwarm; + mName = pSwarmBehaviorName; + mClassName = "SwarmBehavior"; + + try + { + createInputParameters(); + createOutputParameters(); + createInputSwarmParameters(); + createOutputSwarmParameters(); + createAgentParameterIndices(); + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to create behavior " + pSwarmBehaviorName + " for swarm " + pSwarm->name(), __FILE__, __FUNCTION__, __LINE__); + std::cout << e << "\n"; + } +} + +Behavior* +SwarmBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + return create("", pInputParameterString, "", pOutputParameterString); +} + +SwarmBehavior::~SwarmBehavior() +{ + mInputSwarmParameters.clear(); + mInputSwarmNeighborGroups.clear(); + mOutputSwarmParameters.clear(); + + unsigned int internalSwarmParameterCount = mInternalSwarmParameters.size(); + for(unsigned int i=0; iparameterIndex( mInputAgentParameters[parNr]->name() ) ); + for(unsigned int parNr=0; parNrparameterIndex( mOutputAgentParameters[parNr]->name() ) ); + for(unsigned int parNr=0; parNrparameterIndex( mInternalAgentParameters[parNr]->name() ) ); + for(unsigned int neighborNr=0; neighborNrspaceObject(); + mInputAgentNeighborGroupIndices.push_back( spaceObject->neighborGroupIndex(neighborGroup->name()) ); + } + for(unsigned int neighborNr=0; neighborNrspaceObject(); + mOutputAgentNeighborGroupIndices.push_back( spaceObject->neighborGroupIndex(neighborGroup->name()) ); + } + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to create Agent Parameter Indices for swarm " + mSwarm->name() + " behaviour " + mName, __FILE__, __FUNCTION__, __LINE__); + std::cout << e << "\n"; + } +} + +void +SwarmBehavior::createInputSwarmParameters() throw (Exception) +{ + try + { + Tokenizer& tokenizer = Tokenizer::get(); + std::vector inputSwarmParameterNames; + tokenizer.split(mInputSwarmParameterString, inputSwarmParameterNames, ' '); + unsigned int inputSwarmParameterCount = inputSwarmParameterNames.size(); + + + for(unsigned int i=0; icheckSwarmParameter( parameterName ) ) parameter = mSwarm->swarmParameter( parameterName ); + else throw Exception( "FLOCK ERROR: swarm parameter " + parameterName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + mInputSwarmParameters.push_back(parameter); + } + else // parameter_name @ space_name + { + std::string parameterName; + std::string spaceName; + std::string neighborParName; + Parameter* parameter; + + std::vector parSpacePairNames; + tokenizer.split(inputSwarmParameterNames[i], parSpacePairNames, '@'); + + parameterName = parSpacePairNames[0]; + + if( mSwarm->checkSwarmParameter( parameterName ) ) parameter = mSwarm->swarmParameter( parameterName ); + else throw Exception( "FLOCK ERROR: swarm parameter " + parameterName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + mInputSwarmParameters.push_back(parameter); + + if(parSpacePairNames.size() > 1) // neighbors requested + { + for(unsigned int j=1; j spaceNeighborParPairNames; + tokenizer.split(parSpacePairNames[j], spaceNeighborParPairNames, ':'); + spaceName = spaceNeighborParPairNames[0]; + neighborParName = spaceNeighborParPairNames[1]; + } + else + { + spaceName = parSpacePairNames[j]; + neighborParName = ""; + } + + + if( parameter->checkNeighborGroup( spaceName ) == false ) throw Exception( "FLOCK ERROR: Parameter does not contain neighbor group " + spaceName, __FILE__, __FUNCTION__, __LINE__ ); + space::NeighborGroup* neighborGroup = parameter->neighborGroup(spaceName); + mInputSwarmNeighborGroups.push_back( neighborGroup ); + } + } + } + } + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to create input swarm parameters", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +void +SwarmBehavior::createOutputSwarmParameters() throw (Exception) +{ + try + { + Tokenizer& tokenizer = Tokenizer::get(); + std::vector outputSwarmParameterNames; + tokenizer.split(mOutputSwarmParameterString, outputSwarmParameterNames, ' '); + unsigned int outputSwarmParameterCount = outputSwarmParameterNames.size(); + + for(unsigned int i=0; icheckSwarmParameter( parameterName ) ) parameter = mSwarm->swarmParameter(parameterName); + else throw Exception( "FLOCK ERROR: swarm parameter " + parameterName + " not found", __FILE__, __FUNCTION__, __LINE__ ); + + mOutputSwarmParameters.push_back(parameter); + } + } + catch(Exception& e) + { + e += Exception("FLOCK ERROR: failed to create output parameters", __FILE__, __FUNCTION__, __LINE__); + throw e; + } +} + +Parameter* +SwarmBehavior::createInternalSwarmParameter(const std::string& pSwarmParameterName, const std::initializer_list& pValues) throw (Exception) +{ + std::string fullSwarmParameterName( mName + "_" + pSwarmParameterName); + Parameter* internalSwarmParameter; + + // create internal swarm parameter only if it doesn't exist already + if( mSwarm->checkSwarmParameter(fullSwarmParameterName) == true ) internalSwarmParameter = mSwarm->swarmParameter(fullSwarmParameterName); + else + { + internalSwarmParameter = new Parameter(mSwarm, fullSwarmParameterName, pValues); + mInternalSwarmParameters.push_back(internalSwarmParameter); + mSwarm->addSwarmParameter(internalSwarmParameter); + } + + return internalSwarmParameter; +} + +const std::string& +SwarmBehavior::inputSwarmParameterString() const +{ + return mInputSwarmParameterString; +} + +const std::string& +SwarmBehavior::outputSwarmParameterString() const +{ + return mOutputSwarmParameterString; +} + +const std::string& +SwarmBehavior::inputAgentParameterString() const +{ + return mInputParameterString; +} + +const std::string& +SwarmBehavior::outputAgentParameterString() const +{ + return mOutputParameterString; +} + +SwarmBehavior::operator std::string() const +{ + return info(); +} + +std::string +SwarmBehavior::info(int pPropagationLevel) const +{ + std::stringstream ss; + + ss << mName << ": "; + + unsigned int inputSwarmParameterCount = mInputSwarmParameters.size(); + if(inputSwarmParameterCount > 0) + { + ss << "Input Swarm: [ "; + for(unsigned int i=0; iname() << " "; + ss << "] "; + } + + unsigned int inputAgentParameterCount = mInputAgentParameters.size(); + if(inputAgentParameterCount > 0) + { + ss << "Input Agent: [ "; + for(unsigned int i=0; iname() << " "; + ss << "] "; + } + + unsigned int outputSwarmParameterCount = mOutputSwarmParameters.size(); + if(outputSwarmParameterCount > 0) + { + ss << "Output Swarm: [ "; + for(unsigned int i=0; iname() << " "; + ss << "] "; + } + + unsigned int outputAgentParameterCount = mOutputAgentParameters.size(); + if(outputAgentParameterCount > 0) + { + ss << "Output Agent: [ "; + for(unsigned int i=0; iname() << " "; + ss << "] "; + } + + unsigned int internalSwarmParameterCount = mInternalSwarmParameters.size(); + if(internalSwarmParameterCount > 0) + { + ss << "Internal Swarm: [ "; + for(unsigned int i=0; iname() << "\n"; + ss << "] "; + } + + unsigned int internalAgentParameterCount = mInternalAgentParameters.size(); + if(internalAgentParameterCount > 0) + { + ss << "Internal Agent: [ "; + for(unsigned int i=0; iname() << " "; + ss << "] "; + } + + unsigned int inputSwarmNeighborGroupCount = mInputSwarmNeighborGroups.size(); + if(inputSwarmNeighborGroupCount > 0) + { + ss << "NeighborGroup Swarm: [ "; + for(unsigned int i=0; iname() << " "; + ss << "] "; + } + + unsigned int inputAgentNeighborGroupCount = mInputAgentNeighborGroups.size(); + if(inputAgentNeighborGroupCount > 0) + { + ss << "NeighborGroup Agent: [ "; + for(unsigned int i=0; iname() << " "; + ss << "] "; + } + + return ss.str(); +} \ No newline at end of file diff --git a/src/dab_flock_swarm_behavior.h b/src/dab_flock_swarm_behavior.h new file mode 100644 index 0000000..095edb9 --- /dev/null +++ b/src/dab_flock_swarm_behavior.h @@ -0,0 +1,182 @@ +/** \file dab_flock_swarm_behavior.h + * \class dab::flock::SwarmBehavior swarm behavior + * \brief swarm behavior + * + * Created by Daniel Bisig on 8/1/08. + * Ported to OpenFrameworks by Daniel Bisig on 12/10/08. + * + */ + +#ifndef _dab_flock_swarm_behavior_h_ +#define _dab_flock_swarm_behavior_h_ + +#include "dab_flock_behavior.h" + +namespace dab +{ + +namespace flock +{ + +class Swarm; + +class SwarmBehavior : public Behavior +{ +public: + /** + \brief create swarm behavior + \param pInputSwarmParameterString input swarm parameter string (parameters are space separated) + \param pInputAgentParameterString input agent parameter string (parameters are space separated) + \param pOutputSwarmParameterString output swarm parameter string (paramaters are space separated) + \param pOutputAgentParameterString output agent parameter string (paramaters are space separated) + */ + SwarmBehavior(const std::string& pInputSwarmParameterString, const std::string& pInputAgentParameterString, const std::string& pOutputSwarmParameterString, const std::string& pOutputAgentParameterString); + + /** + \brief create swarm behavior + \param pSwarm reference to swarm to which this behavior is added + \param pSwarmBehaviorName swarm behavior name + \param pInputSwarmParameterString input swarm parameter string (parameters are space separated) + \param pInputAgentParameterString input agent parameter string (parameters are space separated) + \param pOutputSwarmParameterString output swarm parameter string (parameters are space separated) + \param pOutputAgentParameterString output agent parameter string (parameters are space separated) + */ + SwarmBehavior(Swarm* pSwarm, const std::string& pSwarmBehaviorName, const std::string& pInputSwarmParameterString, const std::string& pInputAgentParameterString, const std::string& pOutputSwarmParameterString, const std::string& pOutputAgentParameterString); + + /** + \brief destructor + */ + virtual ~SwarmBehavior(); + + /** + \brief create copy of behavior + \param pSwarm swarm this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pSwarm) const = 0; + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputSwarmParameterString, const std::string& pInputAgentParameterString, const std::string& pOutputSwarmParameterString, const std::string& pOutputAgentParameterString) const = 0; + + /** + \brief create agent parameter indices + */ + void createAgentParameterIndices() throw (Exception); + + /** + \brief return input swarm parameter string + \return input swarm parameter string + */ + const std::string& inputSwarmParameterString() const; + + /** + \brief return output swarm parameter string + \return output swarm parameter string + */ + const std::string& outputSwarmParameterString() const; + + /** + \brief return input agent parameter string + \return input agent parameter string + */ + const std::string& inputAgentParameterString() const; + + /** + \brief return output agent parameter string + \return output agent parameter string + */ + const std::string& outputAgentParameterString() const; + + /** + \brief print behavior information + */ + virtual operator std::string() const; + + /** + \brief print behavior information + \param pPropagationLevel how far the propagation method proceeds through composite classes (-1: unlimited, 0: no proceeding, >0: limited proceeding) + */ + virtual std::string info(int pPropagationLevel = 0) const; + + /** + \brief retrieve textual behavior info + \param pOstream output text stream + \param pBehavior behavior + */ + friend std::ostream& operator << ( std::ostream& pOstream, const SwarmBehavior& pBehavior ) + { + pOstream << pBehavior.info(); + + return pOstream; + }; + +protected: + /** + \brief default constructor + */ + SwarmBehavior(); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief create swarm input behavior parameters + \exception Exception failed to create swarm input parameters + */ + void createInputSwarmParameters() throw (Exception); + + /** + \brief create swarm output behavior parameters + \exception Exception failed to create swarm output parameters + */ + void createOutputSwarmParameters() throw (Exception); + + /** + \brief create internal swarm behavior parameter + \param pSwarmParameterName name of swarm parameter + \param pValues values of swarm parameter + \exception Exception failed to create swarm internal parameters + \return swarm parameter + + creates an internal swarm behavior parameter which is visible at the level of the swarm (i.e. other swarm behaviors can access it).\n + the name of the swarm parameter is constructed as follows: behaviorName_parameterName.\n + */ + Parameter* createInternalSwarmParameter(const std::string& pSwarmParameterName, const std::initializer_list& pValues) throw (Exception); + + Swarm* mSwarm; /// \brief swarm this behavior belongs to + std::string mInputSwarmParameterString; /// \brief unparsed string containing all swarm input parameter names + std::string mOutputSwarmParameterString; /// \brief unparsed string containing all swarm output parameter names + std::vector mInputSwarmParameters; /// \brief input swarm parameters (behavior reads from them) + std::vector mInputSwarmNeighborGroups; /// \brief input swarm neighbor groups (behavior reads from them) + std::vector mOutputSwarmParameters; /// \brief output swarm parameters (behavior writes to them) + std::vector mInternalSwarmParameters; /// \brief internal swarm parameters (including scales) + + std::vector& mInputAgentParameters; /// \brief input agent parameters (behavior reads from them) + std::vector& mInputAgentNeighborGroups; /// \brief input agent neighbor groups (behavior reads from them) + std::vector& mOutputAgentParameters; /// \brief output agent parameters (behavior writes to them) + std::vector& mOutputAgentNeighborGroups; /// \brief output agent neighbor groups (behavior writes to them) + std::vector& mInternalAgentParameters; /// \brief internal agent parameters (including scales) + + std::vector mInputAgentParameterIndices; /// \brief input agent parameter indices + std::vector mInputAgentNeighborGroupIndices; /// \brief input agent neighbor group indices + std::vector mOutputAgentParameterIndices; /// \brief output agent parameter indices + std::vector mOutputAgentNeighborGroupIndices; /// \brief output agent neighbor group indices + std::vector mInternalAgentParameterIndices; /// \brief internal agent parameter indices +}; + +}; + +}; + +#endif diff --git a/src/dab_flock_target_parameter_behavior.cpp b/src/dab_flock_target_parameter_behavior.cpp new file mode 100644 index 0000000..509505b --- /dev/null +++ b/src/dab_flock_target_parameter_behavior.cpp @@ -0,0 +1,115 @@ +/** \file dab_flock_target_parameter_behavior.cpp + */ + +#include "dab_flock_target_parameter_behavior.h" +#include "dab_flock_parameter.h" +#include "dab_flock_agent.h" + +using namespace dab; +using namespace dab::flock; + +TargetParameterBehavior::TargetParameterBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString) +: Behavior(pInputParameterString, pOutputParameterString) +{ + mClassName = "TargetParameterBehavior"; +} + +TargetParameterBehavior::TargetParameterBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception) +: Behavior(pAgent, pBehaviorName, pInputParameterString, pOutputParameterString) +{ + mClassName = "TargetParameterBehavior"; + + if(mInputParameters.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mInputParameters.size()) + " input parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if(mOutputParameters.size() < 1) throw Exception( "FLOCK ERROR: " + std::to_string(mOutputParameters.size()) + " output parameters supplied, " + std::to_string(1) + " needed", __FILE__, __FUNCTION__, __LINE__ ); + if( mInputParameters[0]->dim() != mOutputParameters[0]->dim() ) throw Exception( "FLOCK ERROR: input parameter " + mInputParameters[0]->name() + " dim " + std::to_string(mInputParameters[0]->dim()) + " must match output parameter " + mOutputParameters[0]->name() + " dim " + std::to_string(mOutputParameters[0]->dim()), __FILE__, __FUNCTION__, __LINE__ ); + + // input parameter + mInputPar = mInputParameters[0]; + + // output parameter + mOutputPar = mOutputParameters[0]; + + // create internal parameters + mTargetPar = createInternalParameter("target", std::vector(mInputParameters[0]->dim(), 0.0)); + mAdaptPar = createInternalParameter("adapt", std::vector(mInputParameters[0]->dim(), 1.0)); + mAmountPar = createInternalParameter("amount", { 0.1f } ); + mAbsPar = createInternalParameter("absolute", { 0.0f } ); + mDiffValues.resize(mInputParameters[0]->dim()); +} + +TargetParameterBehavior::~TargetParameterBehavior() +{} + +Behavior* +TargetParameterBehavior::create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception) +{ + try + { + if(pAgent != NULL) return new TargetParameterBehavior(pAgent, pBehaviorName, mInputParameterString, mOutputParameterString); + else return new TargetParameterBehavior(mInputParameterString, mOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +Behavior* +TargetParameterBehavior::create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const +{ + try + { + return new TargetParameterBehavior(pInputParameterString, pOutputParameterString); + } + catch(Exception& e) + { + throw; + } +} + +void +TargetParameterBehavior::act() +{ + if(mActivePar->value() <= 0.0) return; + + Eigen::VectorXf& inputValues = mInputPar->values(); + Eigen::VectorXf& outputValues = mOutputPar->backupValues(); + Eigen::VectorXf& targetValues = mTargetPar->values(); + Eigen::VectorXf& adaptValues = mAdaptPar->values(); + + Eigen::VectorXf& diffValues = mDiffValues; + float& amount = mAmountPar->value(); + float& absMode = mAbsPar->value(); + + unsigned int dim = inputValues.rows(); + + if(absMode == 0.0) + { + for(unsigned int d=0; d 0.0 ) + { + diffValues[d] = targetValues[d] - inputValues[d]; + diffValues[d] *= adaptValues[d] * amount; + outputValues[d] += diffValues[d]; + } + else diffValues[d] = 0.0; + } + } + else + { + for(unsigned int d=0; d 0.0 & inputValues[d] != 0.0) + { + diffValues[d] = ( fabs ( targetValues[d] ) - fabs( inputValues[d] ) ) * inputValues[d] / fabs( inputValues[d] ); + diffValues[d] *= adaptValues[d] * amount; + outputValues[d] += diffValues[d]; + + } + else diffValues[d] = 0.0; + } + } + + //std::cout << "in " << inputValues << " target " << targetValues << " out " << outputValues << "\n"; +} \ No newline at end of file diff --git a/src/dab_flock_target_parameter_behavior.h b/src/dab_flock_target_parameter_behavior.h new file mode 100644 index 0000000..d989ac9 --- /dev/null +++ b/src/dab_flock_target_parameter_behavior.h @@ -0,0 +1,104 @@ +/** \file dab_flock_target_parameter_behavior.h + * \class dab::flock::TargetParameterBehavior shift the values of an input parameter towards those of a target parameter + * \brief shift the values of an input parameter towards those of a target parameter + * + * This behavior shifts the values of an input parameter towards those of a target parameter\n + * The internal adapt parameter controls for each dimension how far the values are shifted: 0: no shift at all, 1: full shift\n + * The internal amount parameter controls for all dimensions how far the values are shifted: 0: no shift at all, 1: full shift\n + * The effect of the amount and adapt parameters is combined\n + * The internal absolute parameter controls if the shifting happens towards absolute or non absolute values\n + * \n + * Input Parameter:\n + * type: InputParameter dim: nD neighbors: ignore\n + * \n + * Output Parameter:\n + * type: OutputParameter dim: nD neighbors: ignore\n + * \n + * Internal Parameter:\n + * name: xxx_target dim: nD defaultValue: 0.0\n + * name: xxx_adapt dim: nD defaultValue: 1.0\n + * name: xxx_amount dim: 1D defaultValue: 0.1\n + * name: xxx_absolute dim: 1D defaultValue: 0.0\n + * \n + * Created by Daniel Bisig on 4/21/07. + * Ported to OpenFrameworks by Daniel Bisig on 20/10/2017. + */ + +#ifndef _dab_flock_target_parameter_behavior_h_ +#define _dab_flock_target_parameter_behavior_h_ + +#include "dab_flock_behavior.h" +#include + +namespace dab +{ + +namespace flock +{ + +class Agent; + +class TargetParameterBehavior : public Behavior +{ +public: + /** + \brief create behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + */ + TargetParameterBehavior(const std::string& pInputParameterString, const std::string& pOutputParameterString); + + /** + \brief create behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \param pInputParameterString input parameter string (parameters are space separated) + \param pOutputParameterString output paramaters are space separated) + \exception Exception wrong number of type of parameters + */ + TargetParameterBehavior(Agent* pAgent, const std::string& pBehaviorName, const std::string& pInputParameterString, const std::string& pOutputParameterString) throw (Exception); + + /** + \brief destructor + */ + ~TargetParameterBehavior(); + + /** + \brief create copy of behavior + \param pAgent agent this behavior belongs to + \param pBehaviorName name of behavior + \return new behavior + \exception Exception wrong number of type of parameters + */ + virtual Behavior* create(const std::string& pBehaviorName, Agent* pAgent) const throw (Exception); + + /** + \brief create copy of behavior + \param pInputParameterString input parameter string + \param pOutputParameterString output parameter string + \return new behavior + */ + virtual Behavior* create(const std::string& pInputParameterString, const std::string& pOutputParameterString) const; + + /** + \brief perform behavior + */ + void act(); + +protected: + Parameter* mInputPar; ///\brief input parameter + Parameter* mOutputPar; ///\brief output parameter + Parameter* mTargetPar; ///\brief target parameter + Parameter* mAdaptPar; ///\brief adapt parameter + Parameter* mAmountPar; ///\brief behavior amount parameter + Parameter* mAbsPar; ///\brief treat differences as absolute values + + + Eigen::VectorXf mDiffValues; /// \brief difference values +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_text_tools.cpp b/src/dab_flock_text_tools.cpp new file mode 100644 index 0000000..5f35e56 --- /dev/null +++ b/src/dab_flock_text_tools.cpp @@ -0,0 +1,189 @@ +/** \file dab_flock_text_tools.cpp */ + +#include "dab_flock_text_tools.h" +#include "dab_space_manager.h" +#include "dab_geom_line.h" +#include "dab_geom_geometry_group.h" +#include "dab_space_shape.h" +#include "ofTrueTypeFont.h" + +using namespace dab; +using namespace dab::flock; + +float TextTools::sInternalFontSize = 1000.0; + +TextTools::TextTools() +{} + +TextTools::~TextTools() +{ + int fontCount = mFonts.size(); + for(int fI=0; fIload(pFontFile, sInternalFontSize, false, true, true, mContourSimplifyAmount); // buggy, neither vertical flipping nor simplify seem to have any effect on the contours generated + + _font->setLetterSpacing(_font->getLetterSpacing() * pLetterSpacingScale); + _font->setSpaceSize(_font->getLetterSpacing() * pWhiteSpacingScale); + _font->setLineHeight(_font->getLineHeight() * pLineSpacingScale); + + if(success == false) + { + delete _font; + throw Exception("FLOCK ERROR: failed to load file " + pFontFile + " for fond " + pFontName + " has already been created", __FILE__, __FUNCTION__, __LINE__); + } + + mFonts.insert(pFontName, _font); +} + +void +TextTools::createText( const std::string& pTextName, const std::string& pText, const std::string& pFontName ) throw (Exception) +{ + if( mTextShapes.contains(pTextName) == true ) throw Exception("FLOCK ERROR: text " + pTextName + " already exists", __FILE__, __FUNCTION__, __LINE__ ); + if( mFonts.contains(pFontName) == false ) throw Exception("FLOCK ERROR: font " + pFontName + " does not exists", __FILE__, __FUNCTION__, __LINE__); + + ofTrueTypeFont* font = mFonts[ pFontName ]; + + std::vector textChars = font->getStringAsPoints(pText, false, false); + int charCount = textChars.size(); + + if(charCount == 0) return; + + space::SpaceShape* textShape; + std::shared_ptr textGroup; + geom::GeometryGroup* charGroup; + geom::GeometryGroup* outlineGroup; + + textGroup = std::shared_ptr(new geom::GeometryGroup()); + + for(int cI=0; cI pathCommands = textChar.getCommands(); + std::cout << "pathCommands " << pathCommands.size() << "\n"; + + textChar.setMode(ofPath::POLYLINES); + const std::vector& charOutlines = textChar.getOutline(); + + int outlineCount = charOutlines.size(); + + std::cout << "cI " << cI << " outlineCount " << outlineCount << "\n"; + + // check for white space + if(outlineCount == 0 || (outlineCount == 1 && charOutlines[0].size() == 0 ) ) continue; + + charGroup = new geom::GeometryGroup(); + + for(int oI=0; oIaddGeometry(new geom::Line( point1, point2 )); + + //std::cout << "line p1 " << pI << " : " << point1[0] << " " << point1[1] << " " << point1[2] << " -> " << " p2 " << (pI+1) << " :" << point2[0] << " " << point2[1] << " " << point2[2] << "\n"; + + //std::cout << point1[0] << "\t" << point1[1] << "\n"; + //std::cout << point2[0] << "\t" << point2[1] << "\n"; + + } + + ofPoint point1 = charOutline[pointCount-1]; + ofPoint point2 = charOutline[0]; + + point1 *= 1.0 / sInternalFontSize; + point2 *= 1.0 / sInternalFontSize; + + outlineGroup->addGeometry(new geom::Line( point1, point2 )); + + //std::cout << "outlineGroup " << outlineGroup << " lineCount " << outlineGroup->geometryCount() << "\n"; + + charGroup->addGeometry(outlineGroup); + + //std::cout << point1[0] << "\t" << point1[1] << "\n"; + //std::cout << point2[0] << "\t" << point2[1] << "\n"; + + //std::cout << "line p1 " << (pointCount-1) << " : " << point1[0] << " " << point1[1] << " " << point1[2] << " -> " << " p2 " << 0 << " :" << point2[0] << " " << point2[1] << " " << point2[2] << "\n"; + + //charGroup->addGeometry(outlineGroup); + + //textGroup->addGeometry(outlineGroup); + } + + textGroup->addGeometry(charGroup); + } + + std::cout << "geometryCount " << textGroup->geometryCount() << "\n"; + + if(textGroup->geometryCount() == 0) + { + return; + } + + textGroup->calcMinMaxPos(); + + std::cout << "textGroup min " << textGroup->minPos() << " max " << textGroup->maxPos() << "\n"; + + textShape = new space::SpaceShape(textGroup); + mTextShapes.insert(pTextName, textShape); +} diff --git a/src/dab_flock_text_tools.h b/src/dab_flock_text_tools.h new file mode 100644 index 0000000..f77ede2 --- /dev/null +++ b/src/dab_flock_text_tools.h @@ -0,0 +1,48 @@ +/** \file dab_flock_text_tools.h + */ + +#ifndef _dab_flock_text_tools_h_ +#define _dab_flock_text_tools_h_ + +#include +#include "dab_singleton.h" +#include "dab_exception.h" +#include "dab_index_map.h" +#include "dab_space_shape.h" +#include "ofVec3f.h" +#include "ofTrueTypeFont.h" + + +namespace dab +{ + +namespace flock +{ + +class TextTools : public Singleton< TextTools > +{ +public: + TextTools(); + ~TextTools(); + + bool checkFont( const std::string& pFontName ); + bool checkText( const std::string& pTextName ); + space::SpaceShape* text( const std::string& pTextName ) throw (Exception); + + + void createFont( const std::string& pFontName, const std::string& pFontFile, float pSimplifyAmount = 0.01, float pLetterSpacingScale = 1.0, float pWhiteSpacingScale = 1.0, float pLineSpacingScale = 1.0 ) throw (Exception); + void createText( const std::string& pTextName, const std::string& pText, const std::string& pFontName ) throw (Exception); + +protected: + static float sInternalFontSize; + float mContourSimplifyAmount; + + IndexMap< std::string, ofTrueTypeFont* > mFonts; + IndexMap< std::string, space::SpaceShape* > mTextShapes; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_visual.cpp b/src/dab_flock_visual.cpp new file mode 100644 index 0000000..06d7e31 --- /dev/null +++ b/src/dab_flock_visual.cpp @@ -0,0 +1,739 @@ +/* \file dab_flock_visual.cpp +*/ + +#include "dab_flock_visual.h" +#include "dab_geom_poly_line.h" +#include "dab_flock_simulation.h" +#include "dab_flock_swarm.h" +#include "dab_flock_agent.h" +#include "dab_flock_visual_swarm.h" +#include "dab_flock_visual_agent_shape.h" +#include "dab_flock_visual_agent_trail.h" +#include "dab_flock_visual_neighbor_space.h" +#include "dab_flock_visual_grid_space.h" + +using namespace dab; +using namespace dab::flock; + +unsigned int FlockVisuals::sMaxTrailLength = 200; +std::shared_ptr FlockVisuals::sAgentPyramidGeom( nullptr ); +std::shared_ptr FlockVisuals::sAgentSphereGeom( nullptr ); +std::string FlockVisuals::sAgentVertexShaderFileName("shaders/agent_shader.vert"); +std::string FlockVisuals::sAgentFragmentShaderFileName("shaders/agent_shader.frag"); +std::string FlockVisuals::sTrailVertexShaderFileName("shaders/trail_shader.vert"); +std::string FlockVisuals::sTrailFragmentShaderFileName("shaders/trail_shader.frag"); +std::string FlockVisuals::sGridVertexShaderFileName("shaders/grid_shader.vert"); +std::string FlockVisuals::sGridFragmentShaderFileName("shaders/grid_shader.frag"); +std::string FlockVisuals::sNeighborVertexShaderFileName("shaders/neighbor_shader.vert"); +std::string FlockVisuals::sNeighborFragmentShaderFileName("shaders/neighbor_shader.frag"); + +FlockVisuals::FlockVisuals() +: mBackgroundColor( {1.0, 1.0, 1.0, 1.0} ) +, mViewSize(7.0, 7.0, 7.0) +, mViewResetPos(0.0, 0.0, -15.0) +, mViewPos(0.0, 0.0, -15.0) +, mRotQuat(1.0, 0.0, 0.0, 0.0) +, mZoomVal(50.0) // 0.5 +, mExportImage(false) +, mSimDispLock( false ) +, mToggleFullScreen( false ) +, mWindowSettings( nullptr ) +, mInitialised(false) +, mSimUpdated(false) +, mLock(false) +{ + // create default agent geometry + if(sAgentPyramidGeom == nullptr) + { + sAgentPyramidGeom = std::shared_ptr(new geom::GeometryGroup()); + geom::PolyLine* polyLine = new geom::PolyLine(); + polyLine->append( ofVec3f(0.0, -1.0, 1.0) ); + polyLine->append( ofVec3f(0.0, -1.0, -1.0) ); + polyLine->append( ofVec3f(0.0, 1.0, -1.0) ); + polyLine->append( ofVec3f(0.0, 1.0, 1.0) ); + polyLine->append( ofVec3f(0.0, -1.0, 1.0) ); + polyLine->append( ofVec3f(2.0, 0.0, 0.0) ); + polyLine->append( ofVec3f(0.0, -1.0, -1.0) ); + polyLine->append( ofVec3f(2.0, 0.0, 0.0) ); + polyLine->append( ofVec3f(0.0, 1.0, -1.0) ); + polyLine->append( ofVec3f(2.0, 0.0, 0.0) ); + polyLine->append( ofVec3f(0.0, 1.0, 1.0) ); + polyLine->append( ofVec3f(2.0, 0.0, 0.0) ); + + sAgentPyramidGeom->addGeometry(polyLine); + } + + if(sAgentSphereGeom == nullptr) + { + sAgentSphereGeom = std::shared_ptr(new geom::GeometryGroup()); + + int vertexCount = 10; + + geom::PolyLine* polyLine1 = new geom::PolyLine(); + geom::PolyLine* polyLine2 = new geom::PolyLine(); + geom::PolyLine* polyLine3 = new geom::PolyLine(); + + for(int vI=0; vI(vertexCount - 1) * static_cast(vI); + polyLine1->append(ofVec3f(cos(angle), sin(angle), 0.0)); + polyLine2->append(ofVec3f(cos(angle), 0.0, sin(angle))); + polyLine3->append(ofVec3f(0.0, cos(angle), sin(angle))); + } + + sAgentSphereGeom->addGeometry(polyLine1); + sAgentSphereGeom->addGeometry(polyLine2); + sAgentSphereGeom->addGeometry(polyLine3); + } + + mSelf = std::shared_ptr(this); +} + +FlockVisuals::~FlockVisuals() +{ + // TODO +} + +void +FlockVisuals::clear() +{ + Simulation::get().removeListener(mSelf); + mSelf.reset(); +} + +event::EventManager& +FlockVisuals::event() +{ + return mEventManager; +} + +const std::vector< VisSwarm* >& +FlockVisuals::visualSwarms() const +{ + return mVisualSwarms; +} + +const std::vector< VisNeighborSpace* >& +FlockVisuals::visualNeighbors() const +{ + return mVisualNeighborSpaces; +} + +const std::vector< VisGridSpace* >& +FlockVisuals::visualGrids() const +{ + return mVisualGridSpaces; +} + +const ofVec3f& +FlockVisuals::displayPosition() const +{ + return mViewPos; +} + +const ofQuaternion& +FlockVisuals::displayOrientation() const +{ + return mRotQuat; +} + +const ofQuaternion& +FlockVisuals::displayOrientationChange() const +{ + return mRotQuat2; +} + +float +FlockVisuals::displayZoom() const +{ + return mZoomVal; +} + +const std::array& +FlockVisuals::displayColor() const +{ + return mBackgroundColor; +} + +void +FlockVisuals::setDisplayPosition(const ofVec3f& pPosition) +{ + mViewPos = pPosition; +} + +void +FlockVisuals::setDisplayOrientation(const ofQuaternion& pOrientation) +{ + mRotQuat = pOrientation; +} + +void +FlockVisuals::setDisplayOrientationChange(const ofQuaternion& pOrientationChange) +{ + mRotQuat2 = pOrientationChange; +} + +void +FlockVisuals::setDisplayZoom(float pZoom) +{ + mZoomVal = pZoom; +} + +void +FlockVisuals::setDisplayColor(const std::array& pColor) +{ + mBackgroundColor = pColor; +} + +VisSwarm* +FlockVisuals::visualSwarm( const std::string& pSwarmName ) +{ + int visSwarmCount = mVisualSwarms.size(); + for(int sI=0; sIswarmName() == pSwarmName) return mVisualSwarms[sI]; + } + return nullptr; +} + +void +FlockVisuals::showSwarm( const std::string& pSwarmName, const std::string& pPosParName, const std::string& pVelParName ) +{ + showSwarm(pSwarmName, pPosParName, pVelParName, sMaxTrailLength); +} + +void +FlockVisuals::showSwarm( const std::string& pSwarmName, const std::string& pPosParName, const std::string& pVelParName, unsigned int pMaxTrailLength ) +{ + if(pVelParName.empty() == true) + { + showSwarm(pSwarmName, pPosParName, pVelParName, sAgentSphereGeom, { false, false, false }, pMaxTrailLength); + } + else + { + showSwarm(pSwarmName, pPosParName, pVelParName, sAgentPyramidGeom, { false }, pMaxTrailLength); + } +} + +void +FlockVisuals::showSwarm( const std::string& pSwarmName, const std::string& pPosParName, const std::string& pVelParName, std::shared_ptr pAgentShape, const std::vector& pAgentFilled, unsigned int pMaxTrailLength ) +{ + while(mLock == true) std::this_thread::sleep_for(std::chrono::microseconds(10)); + mLock = true; + + VisSwarm* _visSwarm = visualSwarm(pSwarmName); + + if(_visSwarm == nullptr) + { + _visSwarm = new VisSwarm(pSwarmName, pPosParName, pVelParName); + _visSwarm->createAgentShape(pAgentShape, pAgentFilled); + _visSwarm->createAgentTrail(pMaxTrailLength); + + mVisualSwarms.push_back(_visSwarm); + } + + mLock = false; +} + +void +FlockVisuals::hideSwarm( const std::string& pSwarmName ) +{ + while(mLock == true) std::this_thread::sleep_for(std::chrono::microseconds(10)); + mLock = true; + + VisSwarm* visSwarm; + int visSwarmCount = mVisualSwarms.size(); + + Simulation& simulation = Simulation::get(); + + for(int sI = visSwarmCount - 1; sI >= 0; --sI) + { + visSwarm = mVisualSwarms[sI]; + + if( visSwarm->swarmName() == pSwarmName ) + { + mVisualSwarms.erase( mVisualSwarms.begin() + sI ); + delete visSwarm; + mLock = false; + return; + } + } + + mLock = false; +} + +void +FlockVisuals::hideSwarms() +{ + while(mLock == true) std::this_thread::sleep_for(std::chrono::microseconds(10)); + mLock = true; + + VisSwarm* visSwarm; + int visSwarmCount = mVisualSwarms.size(); + + Simulation& simulation = Simulation::get(); + + for(int sI = visSwarmCount - 1; sI >= 0; --sI) + { + visSwarm = mVisualSwarms[sI]; + mVisualSwarms.erase( mVisualSwarms.begin() + sI ); + delete visSwarm; + } + + mLock = false; +} + +void +FlockVisuals::setAgentColor( const std::string& pSwarmName, const std::array& pAgentColor ) +{ + VisSwarm* _visSwarm = visualSwarm(pSwarmName); + + if(_visSwarm == nullptr) return; + + _visSwarm->setAgentColor(pAgentColor); +} + +void +FlockVisuals::setAgentScale( const std::string& pSwarmName, float pScale ) +{ + VisSwarm* _visSwarm = visualSwarm(pSwarmName); + + if(_visSwarm == nullptr) return; + + _visSwarm->setAgentScale(ofVec3f(pScale,pScale,pScale)); +} + +void +FlockVisuals::setAgentScale( const std::string& pSwarmName, const ofVec3f& pAgentScale ) +{ + VisSwarm* _visSwarm = visualSwarm(pSwarmName); + + if(_visSwarm == nullptr) return; + + _visSwarm->setAgentScale(pAgentScale); +} + +void +FlockVisuals::setAgentLineWidth( const std::string& pSwarmName, float pLineWidth ) +{ + VisSwarm* _visSwarm = visualSwarm(pSwarmName); + + if(_visSwarm == nullptr) return; + + _visSwarm->setAgentLineWidth(pLineWidth); +} + +VisGridSpace* +FlockVisuals::visualGridSpace( const std::string& pSpaceName ) +{ + int visGridSpaceCount = mVisualGridSpaces.size(); + for(int vgI=0; vgIspaceName() == pSpaceName) return mVisualGridSpaces[vgI]; + } + + return nullptr; +} + +VisNeighborSpace* +FlockVisuals::visualNeighborSpace( const std::string& pSpaceName ) +{ + int visNeighborSpaceCount = mVisualNeighborSpaces.size(); + for(int vnI=0; vnIspaceName() == pSpaceName) return mVisualNeighborSpaces[vnI]; + } + + return nullptr; +} + +void +FlockVisuals::showSpace( const std::string& pSpaceName ) +{ + while(mLock == true) std::this_thread::sleep_for(std::chrono::microseconds(10)); + mLock = true; + + // test if space is already registered + if( visualNeighborSpace(pSpaceName) != nullptr || visualGridSpace(pSpaceName) != nullptr ) return; + + // register space + if( Simulation::get().space().checkSpace(pSpaceName) ) + { + space::SpaceAlg* spaceAlg = Simulation::get().space().space(pSpaceName)->spaceAlg(); + + if(dynamic_cast(spaceAlg) != nullptr) // register as grid space + { + VisGridSpace* visualSpace = new VisGridSpace(pSpaceName); + mVisualGridSpaces.push_back( visualSpace ); + } + else // register as neighbor space + { + VisNeighborSpace* visualSpace = new VisNeighborSpace(pSpaceName); + mVisualNeighborSpaces.push_back( visualSpace ); + } + } + + mLock = false; +} + +void +FlockVisuals::showSpace( const std::string& pSpaceName, const std::array& pSpaceColor, float pValueScale ) +{ + // TODO +} + +void +FlockVisuals::hideSpace( const std::string& pSpaceName ) +{ + // TODO +} + +void +FlockVisuals::hideSpaces() +{ + // TODO +} + +void +FlockVisuals::setSpaceColor( const std::string& pSpaceName, const std::array& pSpaceColor ) +{ + VisNeighborSpace* _visNeighborSpace = visualNeighborSpace(pSpaceName); + VisGridSpace* _visGridSpace = visualGridSpace(pSpaceName); + + if(_visNeighborSpace != nullptr) + { + _visNeighborSpace->setColor(pSpaceColor); + } + + if(_visGridSpace != nullptr) + { + _visGridSpace->setColor(pSpaceColor); + } +} + +void +FlockVisuals::setSpaceLineWidth( const std::string& pSpaceName, float pLineWidth ) +{ + VisNeighborSpace* _visNeighborSpace = visualNeighborSpace(pSpaceName); + VisGridSpace* _visGridSpace = visualGridSpace(pSpaceName); + + if(_visNeighborSpace != nullptr) + { + _visNeighborSpace->setLineWidth(pLineWidth); + } + + if(_visGridSpace != nullptr) + { + _visGridSpace->setLineWidth(pLineWidth); + } +} + +void +FlockVisuals::setSpaceValueScale( const std::string& pSpaceName, float pValueScale ) +{ + VisGridSpace* _visGridSpace = visualGridSpace(pSpaceName); + + if(_visGridSpace != nullptr) + { + _visGridSpace->setValueScale(pValueScale); + } +} + +void +FlockVisuals::notifyUpdate() +{ + mSimUpdated = true; +} + +void +FlockVisuals::init() +{ + glDisable(GL_DEPTH_TEST); + glEnable(GL_LINE_SMOOTH); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + // create projection matrices + ofPoint screenSize = ofGetMainLoop()->getCurrentWindow()->getWindowSize(); + mProjectionMatrix.makePerspectiveMatrix(mZoomVal * 80, mViewSize.x / mViewSize.y, 1.0, 5000.0); + //mProjectionMatrix.makeOrthoMatrix(-1.0, 1.0, -1.0, 1.0, 0.0, 1000.0); + + mViewMatrix.makeIdentityMatrix(); + mViewMatrix.rotate(mRotQuat); + mViewMatrix.translate(mViewPos); + + mModelMatrix.makeIdentityMatrix(); + + // create shaders + bool success = mAgentShader.load(sAgentVertexShaderFileName, sAgentFragmentShaderFileName); + if(success == false) + { + std::cout << "failed to load agent shader\n"; + std::exit(1); + } + + success = mTrailShader.load(sTrailVertexShaderFileName, sTrailFragmentShaderFileName); + if(success == false) + { + std::cout << "failed to load trail shader\n"; + std::exit(1); + } + + success = mGridShader.load(sGridVertexShaderFileName, sGridFragmentShaderFileName); + if(success == false) + { + std::cout << "failed to load grid shader\n"; + std::exit(1); + } + + success = mNeighborShader.load(sNeighborVertexShaderFileName, sNeighborFragmentShaderFileName); + if(success == false) + { + std::cout << "failed to load neighbor shader\n"; + std::exit(1); + } + + mAgentShader.begin(); + mAgentShader.setUniformMatrix4f("ProjectionMatrix", mProjectionMatrix); + mAgentShader.setUniformMatrix4f("ViewMatrix", mViewMatrix); + mAgentShader.end(); + + mTrailShader.begin(); + mTrailShader.setUniformMatrix4f("ProjectionMatrix", mProjectionMatrix); + mTrailShader.setUniformMatrix4f("ViewMatrix", mViewMatrix); + mTrailShader.end(); + + mGridShader.begin(); + mGridShader.setUniformMatrix4f("ProjectionMatrix", mProjectionMatrix); + mGridShader.setUniformMatrix4f("ViewMatrix", mViewMatrix); + mGridShader.end(); + + mNeighborShader.begin(); + mNeighborShader.setUniformMatrix4f("ProjectionMatrix", mProjectionMatrix); + mNeighborShader.setUniformMatrix4f("ViewMatrix", mViewMatrix); + mNeighborShader.end(); + + glEnable(GL_DEPTH_TEST); + + Simulation::get().addListener(mSelf); +} + +void +FlockVisuals::resize(int pWidth, int pHeight) +{ + mViewSize.x = pWidth; + mViewSize.y = pHeight; + + mProjectionMatrix.makePerspectiveMatrix(mZoomVal * 80, mViewSize.x / mViewSize.y, 1.0, 5000.0); +} + +void +FlockVisuals::update() +{ + Simulation& simulation = Simulation::get(); + + if(mSimUpdated == true) + { + if( simulation.paused() == false ) simulation.switchPaused(); + + mEventManager.update(); + + removeVisSwarms(); + updateVisSwarms(); + + removeVisSpaces(); + updateVisSpaces(); + + if( simulation.paused() == true ) simulation.switchPaused(); + + mSimUpdated = false; + } + + if(simulation.paused() == false) + { + mRotQuat = mRotQuat2 * mRotQuat; + mRotQuat.normalize(); + } + + display(); +} + +void +FlockVisuals::display() +{ + if(mInitialised == false) init(); + + glClearColor(mBackgroundColor[0], mBackgroundColor[1], mBackgroundColor[2], mBackgroundColor[3]); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + displayAgents(); + displaySpaces(); +} + +void +FlockVisuals::removeVisSwarms() +{ + VisSwarm* visSwarm; + int visSwarmCount = mVisualSwarms.size(); + + Simulation& simulation = Simulation::get(); + + for(int sI = visSwarmCount - 1; sI >= 0; --sI) + { + visSwarm = mVisualSwarms[sI]; + + if( simulation.checkSwarm( visSwarm->swarmName() ) == false ) + { + mVisualSwarms.erase( mVisualSwarms.begin() + sI ); + delete visSwarm; + } + } +} + +void +FlockVisuals::updateVisSwarms() +{ + int visSwarmCount = mVisualSwarms.size(); + + for(int sI = visSwarmCount - 1; sI >= 0; --sI) + { + mVisualSwarms[sI]->update(); + } +} + +void +FlockVisuals::removeVisSpaces() +{ + removeVisNeighborSpaces(); + removeVisGridSpaces(); +} + +void +FlockVisuals::updateVisSpaces() +{ + updateVisNeighborSpaces(); +} + +void +FlockVisuals::removeVisNeighborSpaces() +{ + VisNeighborSpace* visualNeighborSpace; + int visNeighborSpaceCount = mVisualNeighborSpaces.size(); + + for(int sI = visNeighborSpaceCount - 1; sI >= 0; --sI) + { + visualNeighborSpace = mVisualNeighborSpaces[sI]; + + if( Simulation::get().space().checkSpace( visualNeighborSpace->spaceName() ) == false ) + { + mVisualNeighborSpaces.erase( mVisualNeighborSpaces.begin() + sI ); + delete visualNeighborSpace; + } + } +} + +void +FlockVisuals::removeVisGridSpaces() +{ + VisGridSpace* visualGridSpace; + int visGridSpaceCount = mVisualGridSpaces.size(); + + for(int sI = visGridSpaceCount - 1; sI >= 0; --sI) + { + visualGridSpace = mVisualGridSpaces[sI]; + + if( Simulation::get().space().checkSpace( visualGridSpace->spaceName() ) == false ) + { + mVisualGridSpaces.erase( mVisualGridSpaces.begin() + sI ); + delete visualGridSpace; + } + } +} + +void +FlockVisuals::updateVisNeighborSpaces() +{ + VisNeighborSpace* visualNeighborSpace; + int visNeighborSpaceCount = mVisualNeighborSpaces.size(); + + for(int sI = 0; sI < visNeighborSpaceCount; ++sI) + { + visualNeighborSpace = mVisualNeighborSpaces[sI]; + visualNeighborSpace->create(); + } + +} + +void +FlockVisuals::displayAgents() +{ + displayAgentShapes(); + displayAgentTrails(); +} + +void +FlockVisuals::displayAgentShapes() +{ + int visSwarmCount = mVisualSwarms.size(); + + mAgentShader.begin(); + + for(int vsI=0; vsIdisplayAgents(mAgentShader); + } + + mAgentShader.end(); +} + +void +FlockVisuals::displayAgentTrails() +{ + int visSwarmCount = mVisualSwarms.size(); + + mTrailShader.begin(); + + for(int vsI=0; vsIdisplayTrails(mTrailShader); + } + + mTrailShader.end(); +} + +void +FlockVisuals::displaySpaces() +{ + displaySpaceNeighbors(); + displaySpaceGrids(); +} + +void +FlockVisuals::displaySpaceNeighbors() +{ + int visNeighborCount = mVisualNeighborSpaces.size(); + + mNeighborShader.begin(); + + for(int vnI=0; vnIdisplay(mNeighborShader); + } + + mNeighborShader.end(); +} + +void +FlockVisuals::displaySpaceGrids() +{ + int visGridCount = mVisualGridSpaces.size(); + + mGridShader.begin(); + + for(int vgI=0; vgIdisplay(mGridShader); + } + + mGridShader.end(); +} diff --git a/src/dab_flock_visual.h b/src/dab_flock_visual.h new file mode 100644 index 0000000..b2311d0 --- /dev/null +++ b/src/dab_flock_visual.h @@ -0,0 +1,159 @@ +/* \file dab_flock_visual.cpp + */ + +#ifndef _dab_flock_visual_h_ +#define _dab_flock_visual_h_ + +#include +#include +#include "ofShader.h" +#include "ofVbo.h" +#include "ofAppBaseWindow.h" +#include "dab_geom_geometry_group.h" +#include "dab_flock_visual.h" +#include "dab_listener.h" +#include "dab_singleton.h" +#include "dab_event_manager.h" + +namespace dab +{ + +namespace flock +{ + +class VisSwarm; +class VisAgentShape; +class VisAgentTrail; +class VisNeighborSpace; +class VisGridSpace; + +class FlockVisuals : public Singleton, public UpdateListener +{ +public: + FlockVisuals(); + ~FlockVisuals(); + + void clear(); + + event::EventManager& event(); + + const std::vector< VisSwarm* >& visualSwarms() const; + const std::vector< VisNeighborSpace* >& visualNeighbors() const; + const std::vector< VisGridSpace* >& visualGrids() const; + const ofVec3f& displayPosition() const; + const ofQuaternion& displayOrientation() const; + const ofQuaternion& displayOrientationChange() const; + float displayZoom() const; + const std::array& displayColor() const; + + void setDisplayPosition(const ofVec3f& pPosition); + void setDisplayOrientation(const ofQuaternion& pOrientation); + void setDisplayOrientationChange(const ofQuaternion& pOrientationChange); + void setDisplayZoom(float pZoom); + void setDisplayColor(const std::array& pColor); + + VisSwarm* visualSwarm( const std::string& pSwarmName ); + + void showSwarm( const std::string& pSwarmName, const std::string& pPosParName, const std::string& pVelParName ); + void showSwarm( const std::string& pSwarmName, const std::string& pPosParName, const std::string& pVelParName, unsigned int pMaxTrailLength ); + void showSwarm( const std::string& pSwarmName, const std::string& pPosParName, const std::string& pVelParName, std::shared_ptr pAgentShape, const std::vector& pAgentFilled, unsigned int pMaxTrailLength ); + void hideSwarm( const std::string& pSwarmName ); + void hideSwarms(); + + void setAgentColor( const std::string& pSwarmName, const std::array& pAgentColor ); + void setAgentScale( const std::string& pSwarmName, float pScale ); + void setAgentScale( const std::string& pSwarmName, const ofVec3f& pAgentScale ); + void setAgentLineWidth( const std::string& pSwarmName, float pLineWidth ); + + VisGridSpace* visualGridSpace( const std::string& pSpaceName ); + VisNeighborSpace* visualNeighborSpace( const std::string& pSpaceName ); + + void showSpace( const std::string& pSpaceName ); + void showSpace( const std::string& pSpaceName, const std::array& pSpaceColor, float pValueScale = 1.0 ); + void hideSpace( const std::string& pSpaceName ); + void hideSpaces(); + + void setSpaceColor( const std::string& pSpaceName, const std::array& pSpaceColor ); + void setSpaceLineWidth( const std::string& pSpaceName, float pLineWidth ); + void setSpaceValueScale( const std::string& pSpaceName, float pValueScale ); + + virtual void init(); + virtual void resize(int pWidth, int pHeight); + virtual void update(); + virtual void notifyUpdate(); + virtual void display(); + +protected: + static unsigned int sMaxTrailLength; + static std::shared_ptr sAgentPyramidGeom; + static std::shared_ptr sAgentSphereGeom; + static std::string sAgentVertexShaderFileName; + static std::string sAgentFragmentShaderFileName; + static std::string sTrailVertexShaderFileName; + static std::string sTrailFragmentShaderFileName; + static std::string sGridVertexShaderFileName; + static std::string sGridFragmentShaderFileName; + static std::string sNeighborVertexShaderFileName; + static std::string sNeighborFragmentShaderFileName; + + ofShader mAgentShader; + ofShader mTrailShader; + ofShader mGridShader; + ofShader mNeighborShader; + + std::array mBackgroundColor; + ofVec3f mViewSize; + ofVec3f mViewPos; + ofVec3f mViewResetPos; + float mZoomVal; + ofQuaternion mRotQuat; + ofQuaternion mRotQuat2; + + ofMatrix4x4 mProjectionMatrix; + ofMatrix4x4 mViewMatrix; + ofMatrix4x4 mModelMatrix; + + std::vector< VisSwarm* > mVisualSwarms; + std::vector< VisNeighborSpace* > mVisualNeighborSpaces; + std::vector< VisGridSpace* > mVisualGridSpaces; + + ofGLWindowSettings* mWindowSettings; + + event::EventManager mEventManager; /// \brief event manager + + bool mInitialised; + bool mSimUpdated; + bool mLock; + bool mToggleFullScreen; + bool mSimDispLock; + bool mExportImage; + int mExportImageCount; + int mCurrentExportImageCount; + int mImageFileIndex; + std::string mImageFileName; + + std::shared_ptr mSelf; + + void removeVisSwarms(); + void updateVisSwarms(); + + void removeVisSpaces(); + void updateVisSpaces(); + + void removeVisNeighborSpaces(); + void removeVisGridSpaces(); + void updateVisNeighborSpaces(); + + virtual void displayAgents(); + virtual void displayAgentShapes(); + virtual void displayAgentTrails(); + virtual void displaySpaces(); + virtual void displaySpaceNeighbors(); + virtual void displaySpaceGrids(); +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_visual_agent_shape.cpp b/src/dab_flock_visual_agent_shape.cpp new file mode 100644 index 0000000..2d158b5 --- /dev/null +++ b/src/dab_flock_visual_agent_shape.cpp @@ -0,0 +1,166 @@ +/** \file dab_flock_visual_agent_shape.cpp + */ + +#include "dab_flock_visual_agent_shape.h" +#include "ofVectorMath.h" +#include "dab_math_vec.h" +#include + +using namespace dab; +using namespace dab::flock; + +glm::vec3 VisAgentShape::sRefVelocity(1.0, 0.0, 0.0); +std::array VisAgentShape::sColor = {0.0, 0.0, 0.0, 1.0}; +float VisAgentShape::sLineWidth(1.0); + +VisAgentShape::VisAgentShape( std::shared_ptr pGeometry, bool pFilled ) +: mColor(sColor) +, mLineWidth( sLineWidth ) +{ + create( pGeometry, pFilled ); +} + +VisAgentShape::VisAgentShape( std::shared_ptr pGeometryGroup, const std::vector< bool >& pFilled ) +: mColor(sColor) +, mLineWidth( sLineWidth ) +{ + create( pGeometryGroup, pFilled ); +} + +VisAgentShape::~VisAgentShape() +{} + +void +VisAgentShape::create( std::shared_ptr pGeometry, bool pFilled ) +{ + mClosed.push_back(pFilled); + mVbos.resize(1); + + unsigned int vertexCount = pGeometry->vertexCount(); + if(vertexCount == 0) return; + + std::vector& vertices = pGeometry->vertices(); + mVbos[0].setVertexData(vertices.data(), vertexCount, GL_STATIC_DRAW); + + std::vector indices(vertexCount); + for(int vI=0; vI pGeometryGroup, const std::vector< bool >& pFilled ) throw (Exception) +{ + int geometryCount = pGeometryGroup->geometryCount(); + + if(geometryCount != pFilled.size()) throw Exception("FLOCK ERROR: size of Geometry Group " + std::to_string(geometryCount) + " doesn't match size of bool array " + std::to_string(pFilled.size()), __FILE__, __FUNCTION__, __LINE__ ); + + mClosed = pFilled; + mVbos.resize(geometryCount); + + std::vector& geometries = pGeometryGroup->geometries(); + + geom::PolyLine* polyLine; + + for( int gI=0; gI( geometries[gI] ); + bool filled = pFilled[gI]; + + if( polyLine == NULL ) continue; + + unsigned int vertexCount = polyLine->vertexCount(); + + if(vertexCount == 0) continue; + + std::vector& vertices = polyLine->vertices(); + mVbos[gI].setVertexData(vertices.data(), vertexCount, GL_STATIC_DRAW); + + std::vector indices(vertexCount); + for(int vI=0; vI& +VisAgentShape::color() const +{ + return mColor; +} + +float +VisAgentShape::lineWidth() const +{ + return mLineWidth; +} + +const glm::vec3& +VisAgentShape::scale() const +{ + return mScale; +} + +void +VisAgentShape::setColor( const std::array& pColor ) +{ + mColor = pColor; +} + +void +VisAgentShape::setPosition(const glm::vec3& pPosition) +{ + mPosition = pPosition; +} + +void +VisAgentShape::setOrientation(const glm::vec3& pVelocity) +{ + //std::cout << "VisAgentShape::setOrientation " << pVelocity[0] << " " << pVelocity[1] << " " << pVelocity[2] << "\n"; + + mVelocity = glm::normalize(pVelocity); + mOrientation = dab::math::VectorMath::get().makeQuaternion(sRefVelocity, pVelocity); +} + +void +VisAgentShape::setOrientation(const glm::quat& pOrientation) +{ + mOrientation = pOrientation; +} + +void +VisAgentShape::setScale(const glm::vec3& pScale) +{ + mScale = pScale; +} + +void +VisAgentShape::setLineWidth( float pLineWidth ) +{ + mLineWidth = pLineWidth; +} + +void +VisAgentShape::display(const ofShader& pShader) +{ + // TODO: test if this works + mModelMatrix = glm::mat4(1.0f); + mModelMatrix *= glm::translate(mPosition); + mModelMatrix *= glm::toMat4(mOrientation); + mModelMatrix *= glm::scale(mScale); + + pShader.setUniform4f("Color", mColor[0], mColor[1], mColor[2], mColor[3]); + pShader.setUniformMatrix4f("ModelMatrix", mModelMatrix); + + int vboCount = mVbos.size(); + + for(int vboI=0; vboI +#include "ofVectorMath.h" +#include "ofShader.h" +#include "dab_geom_includes.h" +#include "dab_space_includes.h" + +namespace dab +{ + +namespace flock +{ + +class VisAgentShape +{ +public: + VisAgentShape( std::shared_ptr pGeometry, bool pFilled = false ); + VisAgentShape( std::shared_ptr pGeometryGroup, const std::vector< bool >& pFilled ); + ~VisAgentShape(); + + const std::array& color() const; + float lineWidth() const; + const glm::vec3& scale() const; + + void setColor( const std::array& pColor ); + void setPosition(const glm::vec3& pPosition); + void setOrientation(const glm::vec3& pVelocity); + void setOrientation(const glm::quat& pOrientation); + void setScale(const glm::vec3& pScale); + void setLineWidth( float pLineWidth ); + + void display(const ofShader& pShader); + +protected: + static glm::vec3 sRefVelocity; + static std::array sColor; + static float sLineWidth; + + //std::shared_ptr mShape; + + std::vector mClosed; + std::vector mVbos; + + std::array mColor; + float mLineWidth; + //Eigen::Vector3f mVelocity; + //Eigen::Quaternionf mOrientation; + + glm::vec3 mPosition; + glm::vec3 mVelocity; + glm::quat mOrientation; + glm::vec3 mScale; + glm::mat4x4 mModelMatrix; + + void create( std::shared_ptr pGeometry, bool pFilled ); + void create( std::shared_ptr pGeometryGroup, const std::vector< bool >& pFilled ) throw (Exception); +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_visual_agent_trail.cpp b/src/dab_flock_visual_agent_trail.cpp new file mode 100644 index 0000000..69c7cc8 --- /dev/null +++ b/src/dab_flock_visual_agent_trail.cpp @@ -0,0 +1,151 @@ +/** \file dab_flock_visual_agent_trail.cpp + */ + +#include "dab_flock_visual_agent_trail.h" + +using namespace dab; +using namespace dab::flock; + +VisAgentTrail::VisAgentTrail(unsigned int pMaxLength) +: mPositions(pMaxLength) +, mIndices(pMaxLength) +, mAlphaValues(pMaxLength) +, mDecay(0.99) +, mLineWidth(1.0) +, mColor({0.0, 0.0, 0.0, 1.0}) +, mLength(pMaxLength) +, mMaxLength(pMaxLength) +, mCurrentPositionIndex(0) +{} + +VisAgentTrail::~VisAgentTrail() +{} + +void +VisAgentTrail::create() +{ + mVbo.setVertexData(mPositions.data(), mMaxLength, GL_STATIC_DRAW); + mVbo.setIndexData(mIndices.data(), mMaxLength, GL_STATIC_DRAW); +} + +float +VisAgentTrail::decay() const +{ + return mDecay; +} + +float +VisAgentTrail::lineWidth() const +{ + return mLineWidth; +} + +unsigned int +VisAgentTrail::length() const +{ + return mLength; +} + +unsigned int +VisAgentTrail::maxLength() const +{ + return mMaxLength; +} + +const std::array& +VisAgentTrail::color() const +{ + return mColor; +} + +const std::vector< glm::vec3 >& +VisAgentTrail::positions() const +{ + return mPositions; +} + +void +VisAgentTrail::setDecay(float pDecay) +{ + //std::cout << "VisAgentTrail " << this << " set decay " << pDecay << "\n"; + + mDecay = pDecay; +} + +void +VisAgentTrail::setLineWidth(float pLineWidth) +{ + mLineWidth = pLineWidth; +} + +void +VisAgentTrail::setLength(unsigned int pLength) +{ + if(pLength <= mPositions.size() ) mLength = pLength; +} + +void +VisAgentTrail::setColor(const std::array& pColor) +{ + mColor = pColor; + + for(unsigned int i=0; i<4; ++i) + { + if( mColor[i] < 0.0 ) mColor[i] = 0.0; + else if( mColor[i] > 1.0 ) mColor[i] = 1.0; + } +} + +void +VisAgentTrail::update(const glm::vec3& pPosition) +{ + //std::cout << "VisAgentTrail::update: decay " << mDecay << "\n"; + + //std::cout << "VisAgentTrail " << this << " update decay " << mDecay << "\n"; + + mCurrentPositionIndex += 1; + if(mCurrentPositionIndex >= mLength) mCurrentPositionIndex = 0; + + mPositions[mCurrentPositionIndex] = pPosition; + + // update indices and alpha values + // TODO: figure out if there is a more efficient method that rewriting the entire alpha and index buffers + float alphaValue = 1.0; + int index = 0; + for(int i=mCurrentPositionIndex; i>=0; --i) + { + mIndices[index] = i; + mAlphaValues[i] = alphaValue; + + index++; + alphaValue *= mDecay; + } + for(int i=mLength-1; i>mCurrentPositionIndex; --i) + { + mIndices[index] = i; + mAlphaValues[i] = alphaValue; + + index++; + alphaValue *= mDecay; + } + + mVbo.setVertexData(mPositions.data(), mLength, GL_STATIC_DRAW); + mVbo.setIndexData(mIndices.data(), mLength, GL_STATIC_DRAW); +} + +void +VisAgentTrail::display(const ofShader& pShader) +{ + mModelMatrix = glm::mat4(1.0f); + + pShader.setUniform4f("Color", mColor[0], mColor[1], mColor[2], mColor[3]); + pShader.setUniformMatrix4f("ModelMatrix", mModelMatrix); + + int attrLoc = pShader.getAttributeLocation("alpha"); + //mVbo.setAttributeData(attrLoc, mAlphaValues.data(), 1, mMaxLength, GL_STATIC_DRAW); + mVbo.setAttributeData(attrLoc, mAlphaValues.data(), 1, mLength, GL_STATIC_DRAW); + + mVbo.bind(); + mVbo.drawElements(GL_LINE_STRIP, mVbo.getNumIndices()); + mVbo.unbind(); +} \ No newline at end of file diff --git a/src/dab_flock_visual_agent_trail.h b/src/dab_flock_visual_agent_trail.h new file mode 100644 index 0000000..237c42e --- /dev/null +++ b/src/dab_flock_visual_agent_trail.h @@ -0,0 +1,65 @@ +/** dab_flock_visual_agent_trail.h +*/ + +#ifndef _dab_flock_visual_agent_trail_h_ +#define _dab_flock_visual_agent_trail_h_ + +#include +#include +#include +#include "ofShader.h" +#include "ofVbo.h" +#include "ofVectorMath.h" +#include "dab_ringbuffer.h" + +namespace dab +{ + +namespace flock +{ + +class VisAgentTrail +{ +public: + VisAgentTrail(unsigned int pMaxLength); + ~VisAgentTrail(); + + float decay() const; + float lineWidth() const; + unsigned int length() const; + unsigned int maxLength() const; + const std::array& color() const; + const std::vector< glm::vec3 >& positions() const; + + void setDecay(float pDecay); + void setLineWidth(float pLineWidth); + void setLength( unsigned int pLength ); + void setColor(const std::array& pColor); + void update(const glm::vec3& pPosition); + + void display(const ofShader& pShader); + +protected: + std::vector< glm::vec3 > mPositions; + std::vector< ofIndexType > mIndices; + std::vector< float > mAlphaValues; + std::array mColor; + float mDecay; + float mLineWidth; + unsigned int mLength; + unsigned int mMaxLength; + unsigned int mMaxTrailSegLength; + + int mCurrentPositionIndex; + glm::mat4x4 mModelMatrix; + ofVbo mVbo; + + void create(); +}; + +}; + +}; + + +#endif diff --git a/src/dab_flock_visual_event_includes.h b/src/dab_flock_visual_event_includes.h new file mode 100644 index 0000000..7d71c94 --- /dev/null +++ b/src/dab_flock_visual_event_includes.h @@ -0,0 +1,16 @@ +/** \file dab_flock_visual_event_includes.h + * + * Created by Daniel Bisig on 6/10/09. + * Ported to OpenFrameworks by Daniel Bisig on 04/11/2017. + */ + +#ifndef _dab_flock_visual_event_includes_h_ +#define _dab_flock_visual_event_includes_h_ + +#include "dab_flock_visual_show_swarm_event.h" +#include "dab_flock_visual_hide_swarm_event.h" +#include "dab_flock_visual_show_space_event.h" +#include "dab_flock_visual_hide_space_event.h" +//#include "iso_flock_visual_window_settings_event.h" + +#endif \ No newline at end of file diff --git a/src/dab_flock_visual_grid_space.cpp b/src/dab_flock_visual_grid_space.cpp new file mode 100644 index 0000000..76aa7cf --- /dev/null +++ b/src/dab_flock_visual_grid_space.cpp @@ -0,0 +1,170 @@ +/** \file dab_flock_visual_grid_space.cpp +*/ + +#include "dab_flock_visual_grid_space.h" +#include "dab_flock_simulation.h" +#include "dab_space_manager.h" +#include "dab_space.h" +#include "dab_space_grid.h" +#include "dab_space_alg_grid.h" + +using namespace dab; +using namespace dab::flock; + +std::array VisGridSpace::sColor = { 0.0, 0.0, 0.0, 1.0 }; +float VisGridSpace:: sLineWidth = 1.0; +float VisGridSpace::sValueScale = 1.0; + +VisGridSpace::VisGridSpace(const std::string& pSpaceName) +: mSpaceName(pSpaceName) +, mColor(sColor) +, mLineWidth(sLineWidth) +, mValueScale(sValueScale) +{ + try + { + create(); + } + catch (Exception& e) + { + std::cout << e << "\n"; + } +} + +VisGridSpace::~VisGridSpace() +{} + +const std::string& +VisGridSpace::spaceName() const +{ + return mSpaceName; +} + +const std::array& +VisGridSpace::color() const +{ + return mColor; +} + +float +VisGridSpace::lineWidth() const +{ + return mLineWidth; +} + +float +VisGridSpace::valueScale() const +{ + return mValueScale; +} + +void +VisGridSpace::setColor(const std::array& pColor) +{ + mColor = pColor; +} + +void +VisGridSpace::setLineWidth(float pLineWidth) +{ + mLineWidth = pLineWidth; +} + +void +VisGridSpace::setValueScale(float pValueScale) +{ + mValueScale = pValueScale; + + int vectorCount = mGridVectors.size(); + int vertexCount = mVertices.size(); + for(int gI=0, vI=0; vI space = Simulation::get().space().space(mSpaceName); + space::GridAlg* gridAlg = dynamic_cast< space::GridAlg* >( space->spaceAlg() ); + + if( gridAlg == nullptr ) throw Exception("FLOCK ERROR: provided space " + mSpaceName + " is not of type grid space", __FILE__, __FUNCTION__, __LINE__); + + space::SpaceGrid& spaceGrid = gridAlg->grid(); + + int valueDim = spaceGrid.valueDim(); + int valueDimLim = std::min(valueDim, 3); + int gridDim = spaceGrid.gridDim(); + int gridDimLim = std::min(gridDim, 3); + const dab::Array& gridSubdivisonCount = spaceGrid.subdivisionCount(); + + int gridPosCount = 1; + for(int d=0; d indices(indexCount); + for(int i=0; i +#include +#include "ofVectorMath.h" +#include "ofShader.h" +#include "ofVbo.h" +#include "dab_exception.h" + +namespace dab +{ + +namespace flock +{ + +class VisGridSpace +{ +public: + VisGridSpace(const std::string& pSpaceName); + ~VisGridSpace(); + + const std::string& spaceName() const; + const std::array& color() const; + float lineWidth() const; + float valueScale() const; + + void setColor(const std::array& pColor); + void setLineWidth(float pLineWidth); + void setValueScale(float pValueScale); + + void display(const ofShader& pShader); + +protected: + static std::array sColor; + static float sLineWidth; + static float sValueScale; + + std::string mSpaceName; + std::array mColor; + float mLineWidth; + float mValueScale; + + std::vector mGridVectors; + std::vector mGridValues; + std::vector mVertices; + + ofVbo mVbo; + glm::mat4x4 mModelMatrix; + + void create() throw (Exception); + +}; + +}; + +}; + +#endif diff --git a/src/dab_flock_visual_hide_space_event.cpp b/src/dab_flock_visual_hide_space_event.cpp new file mode 100644 index 0000000..4449ec0 --- /dev/null +++ b/src/dab_flock_visual_hide_space_event.cpp @@ -0,0 +1,49 @@ +/** \file dab_flock_visual_hide_space_event.cpp + */ + +#include "dab_flock_visual_hide_space_event.h" +#include "dab_flock_visual.h" + +using namespace dab; +using namespace dab::flock; + +HideSpaceEvent::HideSpaceEvent() +: event::Event() +{} + +HideSpaceEvent::HideSpaceEvent(const std::string& pSpaceName ) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSpaceName(pSpaceName) +{} + +HideSpaceEvent::HideSpaceEvent( const HideSpaceEvent& pEvent ) +: event::Event(pEvent) +, mSpaceName(pEvent.mSpaceName) +{} + +HideSpaceEvent::~HideSpaceEvent() +{} + +event::Event* +HideSpaceEvent::copy() const +{ + return new HideSpaceEvent( *this ); +} + +event::Event* +HideSpaceEvent::copy( double pTime ) const +{ + return new HideSpaceEvent( *this ); +} + +void +HideSpaceEvent::execute() throw (Exception) +{ + mStarted = true; + mFinished = false; + + FlockVisuals::get().hideSpace(mSpaceName); + + mStarted = false; + mFinished = true; +} \ No newline at end of file diff --git a/src/dab_flock_visual_hide_space_event.h b/src/dab_flock_visual_hide_space_event.h new file mode 100644 index 0000000..04b8d53 --- /dev/null +++ b/src/dab_flock_visual_hide_space_event.h @@ -0,0 +1,42 @@ +/** \file dab_flock_visual_hide_space_event.h + * + * Created by Daniel Bisig on 6/19/09. + * Ported to OpenFrameworks by Daniel Bisig on 04/11/2017. + * + */ + +#ifndef _dab_flock_visual_hide_space_event_h_ +#define _dab_flock_visual_hide_space_event_h_ + +#include "dab_flock_simulation.h" +#include "dab_flock_swarm.h" +#include "dab_event.h" + +namespace dab +{ + +namespace flock +{ + +class HideSpaceEvent : public event::Event +{ +public: + HideSpaceEvent( const std::string& pSpaceName ); + HideSpaceEvent( const HideSpaceEvent& pEvent ); + virtual ~HideSpaceEvent(); + + event::Event* copy() const; + event::Event* copy( double pTime ) const; + void execute() throw (Exception); + +protected: + HideSpaceEvent(); + + std::string mSpaceName; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_visual_hide_swarm_event.cpp b/src/dab_flock_visual_hide_swarm_event.cpp new file mode 100644 index 0000000..917080d --- /dev/null +++ b/src/dab_flock_visual_hide_swarm_event.cpp @@ -0,0 +1,49 @@ +/** \file dab_flock_hide_swarm_event.cpp + */ + +#include "dab_flock_visual_hide_swarm_event.h" +#include "dab_flock_visual.h" + +using namespace dab; +using namespace dab::flock; + +HideSwarmEvent::HideSwarmEvent() +: event::Event() +{} + +HideSwarmEvent::HideSwarmEvent(const std::string& pSwarmName ) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +{} + +HideSwarmEvent::HideSwarmEvent( const HideSwarmEvent& pEvent ) +: event::Event(pEvent) +, mSwarmName(pEvent.mSwarmName) +{} + +HideSwarmEvent::~HideSwarmEvent() +{} + +event::Event* +HideSwarmEvent::copy() const +{ + return new HideSwarmEvent( *this ); +} + +event::Event* +HideSwarmEvent::copy( double pTime ) const +{ + return new HideSwarmEvent( *this ); +} + +void +HideSwarmEvent::execute() throw (Exception) +{ + mStarted = true; + mFinished = false; + + FlockVisuals::get().hideSwarm(mSwarmName); + + mStarted = false; + mFinished = true; +} \ No newline at end of file diff --git a/src/dab_flock_visual_hide_swarm_event.h b/src/dab_flock_visual_hide_swarm_event.h new file mode 100644 index 0000000..cab3f70 --- /dev/null +++ b/src/dab_flock_visual_hide_swarm_event.h @@ -0,0 +1,42 @@ +/** \file dab_flock_hide_swarm_event.h + * + * Created by Daniel Bisig on 6/18/09. + * Ported to OpenFrameworks by Daniel Bisig on 04/11/2017. + * + */ + +#ifndef _dab_flock_visual_hide_swarm_event_h_ +#define _dab_flock_visual_hide_swarm_event_h_ + +#include "dab_flock_simulation.h" +#include "dab_flock_swarm.h" +#include "dab_event.h" + +namespace dab +{ + +namespace flock +{ + +class HideSwarmEvent : public event::Event +{ +public: + HideSwarmEvent( const std::string& pSwarmName ); + HideSwarmEvent( const HideSwarmEvent& pEvent ); + virtual ~HideSwarmEvent(); + + event::Event* copy() const; + event::Event* copy( double pTime ) const; + void execute() throw (Exception); + +protected: + HideSwarmEvent(); + + std::string mSwarmName; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_visual_neighbor_space.cpp b/src/dab_flock_visual_neighbor_space.cpp new file mode 100644 index 0000000..a1e9b29 --- /dev/null +++ b/src/dab_flock_visual_neighbor_space.cpp @@ -0,0 +1,144 @@ +/** \file dab_flock_visual_neighbor_space.cpp + */ + +#include "dab_flock_visual_neighbor_space.h" +#include "dab_flock_simulation.h" +#include "dab_space_manager.h" +#include "dab_space.h" +#include "ofVectorMath.h" +#include + +using namespace dab; +using namespace dab::flock; + +std::array VisNeighborSpace::sColor = { 0.0, 0.0, 0.0, 1.0 }; +float VisNeighborSpace::sLineWidth = 1.0; + +VisNeighborSpace::VisNeighborSpace(const std::string& pSpaceName) +: mSpaceName(pSpaceName) +, mColor(sColor) +, mLineWidth(sLineWidth) +{ + try + { + create(); + } + catch(Exception& e) + { + std::cout << e << "\n"; + } + +} + +VisNeighborSpace::~VisNeighborSpace() +{} + +const std::string& +VisNeighborSpace::spaceName() const +{ + return mSpaceName; +} + +const std::array& +VisNeighborSpace::color() const +{ + return mColor; +} + + +float +VisNeighborSpace::lineWidth() const +{ + return mLineWidth; +} + +void +VisNeighborSpace::setColor(const std::array& pColor) +{ + mColor = pColor; +} + +void +VisNeighborSpace::setLineWidth(float pLineWidth) +{ + mLineWidth = pLineWidth; +} + +void +VisNeighborSpace::create() throw (Exception) +{ + mVertices.clear(); + mIndices.clear(); + + Eigen::VectorXf agentPos; + Eigen::VectorXf neighborPos; + glm::vec3 agentPos3D; + glm::vec3 neighorPos3D; + + int spaceDim; + int spaceDimLim; + + try + { + std::shared_ptr space = Simulation::get().space().space(mSpaceName); + spaceDim = space->dim(); + spaceDimLim = std::min(spaceDim, 3); + + const std::vector& spaceObjects = space->objects(); + + int spaceObjectCount = spaceObjects.size(); + + for(int soI=0; soIposition(); + + for(int d=0; dneighborGroup(); + + int neighborCount = neighborGroup->neighborCount(); + + for(int nI=0; nIneighbor(nI)->position(); + + for(int d=0; d +#include +#include "ofVectorMath.h" +#include "ofShader.h" +#include "ofVbo.h" +#include "dab_exception.h" + +namespace dab +{ + + namespace flock + { + + class VisNeighborSpace + { + public: + friend class FlockVisuals; + + VisNeighborSpace(const std::string& pSpaceName); + ~VisNeighborSpace(); + + const std::string& spaceName() const; + const std::array& color() const; + float lineWidth() const; + + void setColor(const std::array& pColor); + void setLineWidth(float pLineWidth); + + void display(const ofShader& pShader); + + protected: + static std::array sColor; + static float sLineWidth; + + std::string mSpaceName; + std::array mColor; + float mLineWidth; + + std::vector mVertices; + std::vector mIndices; + + ofVbo mVbo; + glm::mat4x4 mModelMatrix; + + void create() throw (Exception); + }; + + }; + +}; + +#endif diff --git a/src/dab_flock_visual_show_space_event.cpp b/src/dab_flock_visual_show_space_event.cpp new file mode 100644 index 0000000..5291ecd --- /dev/null +++ b/src/dab_flock_visual_show_space_event.cpp @@ -0,0 +1,67 @@ +/** \file dab_flock_visual_show_space_event.cpp + */ + +#include "dab_flock_visual_show_space_event.h" +#include "dab_flock_visual.h" + +using namespace dab; +using namespace dab::flock; + +ShowSpaceEvent::ShowSpaceEvent() +: event::Event() +{} + +ShowSpaceEvent::ShowSpaceEvent( const std::string& pSpaceName ) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSpaceName(pSpaceName) +, mSpaceColor( { 0.0, 0.0, 0.0, 1.0 } ) +, mValueScale(1.0) +{} + +ShowSpaceEvent::ShowSpaceEvent( const std::string& pSpaceName, const std::array& pSpaceColor ) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSpaceName(pSpaceName) +, mSpaceColor(pSpaceColor) +, mValueScale(1.0) +{} + +ShowSpaceEvent::ShowSpaceEvent( const std::string& pSpaceName, const std::array& pSpaceColor, float pValueScale ) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSpaceName(pSpaceName) +, mSpaceColor(pSpaceColor) +, mValueScale(pValueScale) +{} + +ShowSpaceEvent::ShowSpaceEvent( const ShowSpaceEvent& pEvent ) +: event::Event(pEvent) +, mSpaceName(pEvent.mSpaceName) +, mSpaceColor(pEvent.mSpaceColor) +, mValueScale(pEvent.mValueScale) +{} + +ShowSpaceEvent::~ShowSpaceEvent() +{} + +event::Event* +ShowSpaceEvent::copy() const +{ + return new ShowSpaceEvent( *this ); +} + +event::Event* +ShowSpaceEvent::copy( double pTime ) const +{ + return new ShowSpaceEvent( *this ); +} + +void +ShowSpaceEvent::execute() throw (Exception) +{ + mStarted = true; + mFinished = false; + + FlockVisuals::get().showSpace( mSpaceName, mSpaceColor, mValueScale ); + + mStarted = false; + mFinished = true; +} \ No newline at end of file diff --git a/src/dab_flock_visual_show_space_event.h b/src/dab_flock_visual_show_space_event.h new file mode 100644 index 0000000..9eee992 --- /dev/null +++ b/src/dab_flock_visual_show_space_event.h @@ -0,0 +1,46 @@ +/** \file dab_flock_visual_show_space_event.h + * + * Created by Daniel Bisig on 6/19/09. + * Ported to OpenFrameworks by Daniel Bisig on 04/11/2017. + * + */ + +#ifndef _dab_flock_visual_show_space_event_h_ +#define _dab_flock_visual_show_space_event_h_ + +#include "dab_flock_simulation.h" +#include "dab_flock_swarm.h" +#include "dab_event.h" + +namespace dab +{ + +namespace flock +{ + +class ShowSpaceEvent : public event::Event +{ +public: + ShowSpaceEvent( const std::string& pSpaceName ); + ShowSpaceEvent( const std::string& pSpaceName, const std::array& pSpaceColor ); + ShowSpaceEvent( const std::string& pSpaceName, const std::array& pSpaceColor, float pValueScale ); + ShowSpaceEvent( const ShowSpaceEvent& pEvent ); + virtual ~ShowSpaceEvent(); + + event::Event* copy() const; + event::Event* copy( double pTime ) const; + void execute() throw (Exception); + +protected: + ShowSpaceEvent(); + + std::string mSpaceName; + std::array mSpaceColor; + float mValueScale; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_visual_show_swarm_event.cpp b/src/dab_flock_visual_show_swarm_event.cpp new file mode 100644 index 0000000..fdd3729 --- /dev/null +++ b/src/dab_flock_visual_show_swarm_event.cpp @@ -0,0 +1,80 @@ +/** \file dab_flock_visual_show_swarm_event.cpp + */ + +#include "dab_flock_visual_show_swarm_event.h" +#include "dab_flock_visual.h" + +using namespace dab; +using namespace dab::flock; + +ShowSwarmEvent::ShowSwarmEvent() +: event::Event() +{} + +ShowSwarmEvent::ShowSwarmEvent(const std::string& pSwarmName, const std::string& pPosParName ) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mPosParName(pPosParName) +, mVelParName() +, mTrailLength(-1) +{} + +ShowSwarmEvent::ShowSwarmEvent(const std::string& pSwarmName, const std::string& pPosParName, const std::string& pVelParName ) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mPosParName(pPosParName) +, mVelParName(pVelParName) +, mTrailLength(-1) +{} + +ShowSwarmEvent::ShowSwarmEvent(const std::string& pSwarmName, const std::string& pPosParName, unsigned int pTrailLength ) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mPosParName(pPosParName) +, mVelParName() +, mTrailLength(pTrailLength) +{} + +ShowSwarmEvent::ShowSwarmEvent(const std::string& pSwarmName, const std::string& pPosParName, const std::string& pVelParName, unsigned int pTrailLength ) +: event::Event(0.0, -1.0, event::RelativeTime) +, mSwarmName(pSwarmName) +, mPosParName(pPosParName) +, mVelParName(pVelParName) +, mTrailLength(pTrailLength) +{} + +ShowSwarmEvent::ShowSwarmEvent( const ShowSwarmEvent& pEvent ) +: event::Event(pEvent) +, mSwarmName(pEvent.mSwarmName) +, mPosParName(pEvent.mPosParName) +, mVelParName(pEvent.mVelParName) +, mTrailLength(pEvent.mTrailLength) +{} + +ShowSwarmEvent::~ShowSwarmEvent() +{} + +event::Event* +ShowSwarmEvent::copy() const +{ + return new ShowSwarmEvent( *this ); +} + +event::Event* +ShowSwarmEvent::copy( double pTime ) const +{ + return new ShowSwarmEvent( *this ); +} + +void +ShowSwarmEvent::execute() throw (Exception) +{ + mStarted = true; + mFinished = false; + + if(mTrailLength >= 0) FlockVisuals::get().showSwarm( mSwarmName, mPosParName, mVelParName, mTrailLength ); + else FlockVisuals::get().showSwarm( mSwarmName, mPosParName, mVelParName ); + + mStarted = false; + mFinished = true; +} \ No newline at end of file diff --git a/src/dab_flock_visual_show_swarm_event.h b/src/dab_flock_visual_show_swarm_event.h new file mode 100644 index 0000000..3e14a84 --- /dev/null +++ b/src/dab_flock_visual_show_swarm_event.h @@ -0,0 +1,50 @@ +/** \file dab_flock_visual_show_swarm_event.h + * + * Created by Daniel Bisig on 6/18/09. + * Ported to OpenFrameworks by Daniel Bisig on 04/11/2017. + * + */ + + +#ifndef _dab_flock_visual_show_swarm_event_h_ +#define _dab_flock_visual_show_swarm_event_h_ + +#include "dab_flock_simulation.h" +#include "dab_flock_swarm.h" +#include "dab_event.h" + +namespace dab +{ + +namespace flock +{ + +class ShowSwarmEvent : public event::Event +{ +public: + ShowSwarmEvent( const std::string& pSwarmName, const std::string& pPosParName ); + ShowSwarmEvent( const std::string& pSwarmName, const std::string& pPosParName, const std::string& pVelParName ); + ShowSwarmEvent( const std::string& pSwarmName, const std::string& pPosParName, unsigned int pMaxTrailLength ); + ShowSwarmEvent( const std::string& pSwarmName, const std::string& pPosParName, const std::string& pVelParName, unsigned int pTrailLength ); + + ShowSwarmEvent( const ShowSwarmEvent& pEvent ); + virtual ~ShowSwarmEvent(); + + event::Event* copy() const; + event::Event* copy( double pTime ) const; + void execute() throw (Exception); + +protected: + ShowSwarmEvent(); + + std::string mSwarmName; + std::string mPosParName; + std::string mVelParName; + int mTrailLength; +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/dab_flock_visual_swarm.cpp b/src/dab_flock_visual_swarm.cpp new file mode 100644 index 0000000..fe123db --- /dev/null +++ b/src/dab_flock_visual_swarm.cpp @@ -0,0 +1,340 @@ +/** \file dab_flock_visual_swarm.cpp +*/ + +#include "dab_flock_visual_swarm.h" +#include "dab_flock_visual_agent_shape.h" +#include "dab_flock_visual_agent_trail.h" +#include "dab_flock_swarm.h" +#include "dab_flock_simulation.h" + +using namespace dab; +using namespace dab::flock; + +VisSwarm::VisSwarm(const std::string& pSwarmName, const std::string& pPosParName, const std::string& pVelParName) +: mSwarmName(pSwarmName) +, mPosParName(pPosParName) +, mVelParName(pVelParName) +, mAgentShape(nullptr) +, mAgentTrail(nullptr) +{} + +VisSwarm::~VisSwarm() +{ + if(mAgentShape != nullptr) delete mAgentShape; + if(mAgentTrail != nullptr) delete mAgentTrail; + + int trailCount = mAgentTrails.size(); + for(int tI=0; tI +VisSwarm::agentColor() const +{ + if(mAgentShape != nullptr) return mAgentShape->color(); + return std::array(); +} + +glm::vec3 +VisSwarm::agentScale() const +{ + if(mAgentShape != nullptr) return mAgentShape->scale(); + return glm::vec3(); +} + +float +VisSwarm::agentLineWidth() const +{ + if(mAgentShape != nullptr) return mAgentShape->lineWidth(); + return 0.0; +} + +std::array +VisSwarm::trailColor() const +{ + if(mAgentTrail != nullptr) return mAgentTrail->color(); + return std::array(); +} + +int +VisSwarm::trailLength() const +{ + if(mAgentTrail != nullptr) return mAgentTrail->length(); + return 0; +} + +float +VisSwarm::trailWidth() const +{ + if(mAgentTrail != nullptr) return mAgentTrail->lineWidth(); + return 0.0; +} + +float +VisSwarm::trailDecay() const +{ + if(mAgentTrail != nullptr) return mAgentTrail->decay(); + return 0.0; +} + +std::vector& +VisSwarm::agentPositions() +{ + return mAgentPositions; +} + +std::vector& +VisSwarm::agentVelocities() +{ + return mAgentVelocities; +} + +std::vector< VisAgentTrail*>& +VisSwarm::agentTrails() +{ + return mAgentTrails; +} + +void +VisSwarm::createAgentShape(std::shared_ptr pGeometryGroup, const std::vector< bool >& pFilled) +{ + mAgentShape = new VisAgentShape(pGeometryGroup, pFilled); +} + +void +VisSwarm::createAgentTrail(unsigned int pMaxTrailSize) +{ + mAgentTrail = new VisAgentTrail(pMaxTrailSize); +} + +void +VisSwarm::setAgentColor(const std::array& pColor) +{ + if(mAgentShape == nullptr) return; + + mAgentShape->setColor(pColor); +} + +void +VisSwarm::setAgentScale(const glm::vec3& pScale) +{ + if(mAgentShape == nullptr) return; + + mAgentShape->setScale(pScale); +} + +void +VisSwarm::setAgentLineWidth(float pLineWidth) +{ + if(mAgentShape == nullptr) return; + + mAgentShape->setLineWidth(pLineWidth); +} + +void +VisSwarm::setTrailColor(const std::array& pColor) +{ + if(mAgentTrail == nullptr) return; + + mAgentTrail->setColor(pColor); + + int trailCount = mAgentTrails.size(); + + for(int tI=0; tIsetColor(pColor); + } +} + +void +VisSwarm::setTrailLength(int pLength) +{ + if(mAgentTrail == nullptr) return; + + mAgentTrail->setLength(pLength); + + int trailCount = mAgentTrails.size(); + + for(int tI=0; tIsetLength(pLength); + } +} + +void +VisSwarm::setTrailWidth(float pWidth) +{ + if(mAgentTrail == nullptr) return; + + mAgentTrail->setLineWidth(pWidth); + + int trailCount = mAgentTrails.size(); + + for(int tI=0; tIsetLineWidth(pWidth); + } +} + +void +VisSwarm::setTrailDecay(float pDecay) +{ + if(mAgentTrail == nullptr) return; + + mAgentTrail->setDecay(pDecay); + + int trailCount = mAgentTrails.size(); + + for(int tI=0; tIsetDecay(pDecay); + } +} + +void +VisSwarm::setAgentCount(unsigned int pAgentCount) +{ + if(mAgentPositions.size() == pAgentCount) return; + + mAgentPositions.resize(pAgentCount); + mAgentVelocities.resize(pAgentCount); + + int trailCount = mAgentTrails.size(); + + if(trailCount > pAgentCount) + { + for(int tI = trailCount - 1; tI>=(int)pAgentCount; --tI) + { + delete mAgentTrails[tI]; + mAgentTrails.erase(mAgentTrails.begin() + tI); + } + } + else + { + for(int tI = trailCount; tImaxLength()); + newVisAgentTrail->setColor(mAgentTrail->color()); + newVisAgentTrail->setDecay(mAgentTrail->decay()); + newVisAgentTrail->setLength(mAgentTrail->length()); + newVisAgentTrail->setLineWidth(mAgentTrail->lineWidth()); + + mAgentTrails.push_back(newVisAgentTrail); + } + } +} + +void +VisSwarm::update() +{ + Swarm* swarm; + int agentCount; + unsigned int posParIndex; + unsigned int velParIndex; + unsigned int posParDim; + + swarm = Simulation::get().swarm( mSwarmName ); + std::vector& agents = swarm->agents(); + agentCount = agents.size(); + + if(agentCount != mAgentTrails.size()) setAgentCount(agentCount); + if(agentCount == 0) return; + + posParIndex = agents[0]->parameterIndex( mPosParName ); + posParDim = agents[0]->parameter( posParIndex )->dim(); + if(posParDim > 3) posParDim = 3; + + if( mVelParName.empty() == false ) + { + //std::cout << "posParName " << mPosParName << " posParIndex " << posParIndex << " velParName " << mVelParName << " velParIndex " << swarm->parameterIndex( mVelParName ) << "\n"; + + velParIndex = swarm->parameterIndex( mVelParName ); + + for(unsigned int aI=0; aIparameter( posParIndex )->values(); + const Eigen::VectorXf& agentVelocity = agents[aI]->parameter( velParIndex )->values(); + + for(unsigned int d=0; dupdate( mAgentPositions[aI] ); + } + } + else + { + for(unsigned int aI=0; aIparameter( posParIndex )->values(); + + for(unsigned int d=0; dupdate( mAgentPositions[aI] ); + } + } + + // std::cout << "GLPanel::updateVisSwarms() end\n"; + +} + +void +VisSwarm::displayAgents(const ofShader &pShader) +{ + // display agent shapes + glLineWidth(mAgentShape->lineWidth()); + int agentCount = mAgentPositions.size(); + for(int aI=0; aIsetPosition(agentPos); + mAgentShape->setOrientation(agentVel); + mAgentShape->display(pShader); + + //std::cout << "display Agent " << aI << " pos " << agentPos << "\n"; + } +} + +void +VisSwarm::displayTrails(const ofShader &pShader) +{ + glLineWidth(mAgentTrail->lineWidth()); + int trailCount = mAgentTrails.size(); + + for(int tI=0; tIdisplay(pShader); + } +} + diff --git a/src/dab_flock_visual_swarm.h b/src/dab_flock_visual_swarm.h new file mode 100644 index 0000000..94fc480 --- /dev/null +++ b/src/dab_flock_visual_swarm.h @@ -0,0 +1,76 @@ +/** \file dab_flock_visual_swarm.h +*/ + +#ifndef _dab_flock_visual_swarm_h_ +#define _dab_flock_visual_swarm_h_ + +#include +#include +#include "ofVectorMath.h" +#include "ofShader.h" +#include "dab_geom_geometry_group.h" + +namespace dab +{ + +namespace flock +{ + +class VisAgentShape; +class VisAgentTrail; + +class VisSwarm +{ +public: + VisSwarm(const std::string& pSwarmName, const std::string& pPosParName, const std::string& pVelParName); + ~VisSwarm(); + + const std::string& swarmName() const; + const std::string& posParmName() const; + const std::string& velParName() const; + std::array agentColor() const; + glm::vec3 agentScale() const; + float agentLineWidth() const; + std::array trailColor() const; + int trailLength() const; + float trailWidth() const; + float trailDecay() const; + + std::vector< glm::vec3 >& agentPositions(); + std::vector< glm::vec3 >& agentVelocities(); + std::vector< VisAgentTrail* >& agentTrails(); + + void createAgentShape(std::shared_ptr pGeometryGroup, const std::vector< bool >& pFilled); + void createAgentTrail(unsigned int pMaxTrailSize); + void setAgentColor(const std::array& pColor); + void setAgentScale(const glm::vec3& pScale); + void setAgentLineWidth(float pLineWidth); + void setTrailColor(const std::array& pColor); + void setTrailLength(int pLength); + void setTrailWidth(float pWidth); + void setTrailDecay(float pDecay); + + void setAgentCount(unsigned int pAgentCount); + + void update(); + void displayAgents(const ofShader &pShader); + void displayTrails(const ofShader &pShader); + +protected: + std::string mSwarmName; + std::string mPosParName; + std::string mVelParName; + + std::vector< glm::vec3 > mAgentPositions; + std::vector< glm::vec3 > mAgentVelocities; + + VisAgentShape* mAgentShape; + VisAgentTrail* mAgentTrail; + std::vector mAgentTrails; +}; + +}; + +}; + +#endif