1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#![feature(slice_patterns, type_ascription, rustc_macro, try_from)]
//! This crate provides functionality for configuring and running a simulation of a range-based
//! tracking system.
//!
//! Simulations are run by creating a [`SimulationRunner`] \(using the [`new`] method) and calling
//! the [`step`] method. Each step returns a new [`SimulationFrame`] which contains all the
//! information about the simulation at a particular point in time.
//!
//! [`new`]: ./struct.SimulationRunner.html#method.new
//! [`step`]: ./struct.SimulationRunner.html#method.step
//!
//! # Examples
//!
//! [`SimulationConfig`] implements the [`Default`] trait, which allows you to quickly create and
//! use a new [`SimulationRunner`]:
//!
//! ```
//! let num_steps = 100;
//! let dt = 1.0;
//!
//! let mut simulation_runner = SimulationRunner::new(&Default::default());
//!
//! for frame in (0..num_steps).map(|_| simulation_runner.step(dt)) {
//!     // Use simulation frame ...
//! }
//! ```
//!
//! Alternatively you can define a specific configuration by creating a [`SimulationConfig`]
//! explicitly, or by loading one from a JSON file:
//!
//! ```
//! // Explicit configuration definition
//! let config = SimulationConfig {
//!     // Config options...
//! };
//!
//! let mut simulation_runner = SimulationRunner::new(&config);
//!
//! // Use simulation runner ...
//! ```
//!
//! ```
//! // Json loading using serde_json
//! extern crate serde;
//! extern crate serde_json;
//!
//! let mut file = File::open("config.json").unwrap();
//! let config = serde_json::from_reader(&mut file).unwrap();
//!
//! let mut simulation_runner = SimulationRunner::new(&config);
//!
//! // Use simulation runner ...
//! ```
//!
//! For more information about custom configurations see the documentation for [`SimulationConfig`].
//!
//! # Configuration options
//!
//! The easiest way to configure the simulation is to load a JSON file with the desired settings and
//! loading (as shown above). The default configuration corresponds to the following JSON file:
//!
//! ```ignore
//! {
//!   "uavs": [
//!     {
//!       "capture_rate": 1.0,
//!       "speed": 10.0,
//!       "controller": {
//!         "pattern_size": [50.0, 50.0],
//!         "pattern_center": [50.0, 50.0],
//!         "pattern_type": "Elliptical"
//!       },
//!       "receiver": {
//!         "signal_noise": 0.01,
//!         "gain_pattern": "Uniform",
//!         "propagation_model": "FreeSpace"
//!       }
//!     }
//!   ],
//!   "animals": [
//!     {
//!       "position": [50.0, 50.0],
//!       "speed": 0.6,
//!       "walk_variance": 0.1
//!     }
//!   ],
//!   "map_size": [100.0, 100.0],
//!   "num_particles": 10000,
//!   "particle_noise": 2.0
//! }
//! ```
//!
//! [`SimulationConfig`]: ./struct.SimulationConfig.html
//! [`SimulationRunner`]: ./struct.SimulationRunner.html
//! [`SimulationFrame`]: ./struct.SimulationFrame.html
//! [`Default`]: https://doc.rust-lang.org/std/default/trait.Default.html

extern crate cgmath;
extern crate particle_filter;
extern crate probability;
extern crate rand;
extern crate signal_models;
extern crate serde;
#[macro_use] extern crate serde_derive;

mod common;
mod simulation_runner;

pub mod animal;
pub mod signal;
pub mod uav;

use animal::AnimalConfig;
use signal::{SignalConfig, PropagationModel, GainPattern};
use uav::{UavConfig, UavController, PatternType};

pub use simulation_runner::{Measurement, SimulationRunner, SimulationFrame, FilterFrame};

/// Configuration options for a simulation
#[derive(Clone, Serialize, Deserialize)]
pub struct SimulationConfig {
    /// The list of UAVs to simulate
    pub uavs: Vec<UavConfig>,

    /// The list of animals to simulate
    pub animals: Vec<AnimalConfig>,

    /// The initial size of the map
    pub map_size: [f32; 2],

    /// The number of particles to use in the particle filter
    pub num_particles: usize,

    /// The amount of noise to use in the particle filter
    pub particle_noise: f32,
}

impl Default for SimulationConfig {
    fn default() -> SimulationConfig {
        SimulationConfig {
            uavs: vec![
                UavConfig {
                    capture_rate: 1.0,
                    speed: 10.0,
                    controller: UavController::new([50.0, 50.0], [50.0, 50.0], PatternType::Elliptical),
                    receiver: SignalConfig::new(0.01, GainPattern::Uniform, PropagationModel::FreeSpace),
                }
            ],
            animals: vec![AnimalConfig::new([50.0, 50.0], 0.6, 0.1)],
            map_size: [100.0, 100.0],
            num_particles: 10000,
            particle_noise: 2.0,
        }
    }
}