diff --git a/engine/src/Utils/Spawning/SpawnSpace.cpp b/engine/src/Utils/Spawning/SpawnSpace.cpp index b1335d0076962b70660f1fa293fed959373e7a49..a22055cf67534d3b7b498cec3449df271dc556e0 100644 --- a/engine/src/Utils/Spawning/SpawnSpace.cpp +++ b/engine/src/Utils/Spawning/SpawnSpace.cpp @@ -117,83 +117,6 @@ SequentialSpawnSpace::FindSpot(const Padding &padding, units::velocity::meters_p }; } -DistributedSpawnSpace::DistributedSpawnSpace(const OpenScenarioEngine::v1_3::TrafficDistributions &distributions, std::vector<SpawnZones> &zones) - : SpawnSpace{distributions} -{ - for (const SpawnZones ®ions : zones) - { - for (const SpawnZone &zone : regions) - { - assert(zone.obstacles.size() > 1); - for (auto obstacle{std::next(zone.obstacles.begin())}; obstacle != zone.obstacles.end(); ++obstacle) - { - spots.emplace(*std::prev(obstacle), *obstacle); - } - } - } -} - -ObjectTemplatePtr DistributedSpawnSpace::SampleObjectTemplate(StochasticsInterface &stochastics) const -{ - const units::length::meter_t max_length{GetMaxIntervalLength()}; - const auto entity_end{FindSpawnableEntityEnd(max_length)}; - if (std::distance(entities.begin(), entity_end) <= 1) - { - return entity_end == entities.begin() ? ObjectTemplatePtr{} : entities.front().handle; - } - assert(weights.size() == entities.size() + 1); - const units::dimensionless::scalar_t max_weight{weights[static_cast<size_t>(std::distance(entities.begin(), entity_end))]}; - const units::dimensionless::scalar_t sampled_weight{stochastics.GetUniformDistributed(.0, max_weight.value())}; - return Sample(entities, weights, sampled_weight).handle; -} - -units::length::meter_t DistributedSpawnSpace::GetMaxIntervalLength() const -{ - return spots.empty() ? units::length::meter_t{} : GetLength(*spots.rbegin()); -} - -std::vector<Weighted<ObjectTemplatePtr>>::const_iterator DistributedSpawnSpace::FindSpawnableEntityEnd(units::length::meter_t threshold) const -{ - return std::upper_bound(entities.begin(), entities.end(), threshold, [](units::length::meter_t threshold, const Weighted<ObjectTemplatePtr> &entity) - { return threshold < GetLength(entity); }); -} -std::vector<Weighted<ObjectTemplatePtr>>::iterator DistributedSpawnSpace::FindSpawnableEntityEnd(units::length::meter_t threshold) -{ - return std::upper_bound(entities.begin(), entities.end(), threshold, [](units::length::meter_t threshold, const Weighted<ObjectTemplatePtr> &entity) - { return threshold < GetLength(entity); }); -} - -std::set<SpawnSpot, Less<ToLength>>::const_iterator DistributedSpawnSpace::SampleSpot(units::length::meter_t minLength, VelocityRange velocity, StochasticsInterface &stochastics) const -{ - auto spot{spots.lower_bound(minLength)}; - if (spot == spots.end()) - { - return spots.end(); - } - std::vector<decltype(spot)> candidates; - for (; spot != spots.end(); ++spot) - { - const bool canKeepUp{spot->velocity.Contains(velocity)}; - const bool isEnoughRoomNow{GetLength(*spot) > minLength}; - const bool isEnoughRoomAfter2Seconds{GetLength(*spot) + spot->velocity.GetDifference() * units::time::second_t{2.0} > minLength}; - if (canKeepUp && isEnoughRoomNow && isEnoughRoomAfter2Seconds) - { - candidates.push_back(spot); - } - } - if (candidates.size() <= 1) - { - return candidates.empty() ? spots.end() : *candidates.begin(); - } - ToAccumulatedLength accumulator; - std::vector<units::length::meter_t> lengths{{}}; - Transform(candidates, lengths, [&accumulator](const auto iterator) { // - return accumulator(*iterator); - }); - const units::length::meter_t sampledLength{stochastics.GetUniformDistributed(.0, lengths.back().value())}; - return Sample(candidates, lengths, sampledLength); -} - void UpdateSpot(std::vector<OpenScenarioEngine::v1_3::SpawnSpot> &stream, std::vector<OpenScenarioEngine::v1_3::SpawnSpot>::iterator spot, const Interval &occupied_space, diff --git a/engine/src/Utils/Spawning/SpawnSpace.h b/engine/src/Utils/Spawning/SpawnSpace.h index a30ed5a39d8d8852936ccf9f916e2abf00fc67a8..1e2ee47e439ee2c74277d0ad3cbf3b8d8e74358a 100644 --- a/engine/src/Utils/Spawning/SpawnSpace.h +++ b/engine/src/Utils/Spawning/SpawnSpace.h @@ -76,44 +76,6 @@ struct SequentialSpawnSpace : SpawnSpace const std::vector<mantle_api::TrafficArea> &areas; }; -/// A DistributedSpawnSpace is essentially a self-managing, depleting list of TrafficAreas and weighted entities optimized -/// for the use-case of spawning entities at the rear end of a TrafficArea (with offsets). It restructures the -/// data to be sorted by interval and entity length, allowing efficient filtering of remaining spawnable entities -/// and intervals as the space is filled. -struct DistributedSpawnSpace : SpawnSpace -{ - DistributedSpawnSpace(const OpenScenarioEngine::v1_3::TrafficDistributions &, std::vector<SpawnZones> &); - - /// Returns the entity out of the set of entities in this space based on the given sample - /// - /// \param sample Value within the accumulated weights of each entity of this space - /// \return Blueprint for spawning an entity alongside controllers for that entity - ObjectTemplatePtr GetObjectTemplate(units::dimensionless::scalar_t sample); - - //! Returns a random object template (entity + controllers) using the given number generator - //! - //! \param StochasticsInterface Random number generator used to sample a weight - //! \return Randomly selected object template - ObjectTemplatePtr SampleObjectTemplate(StochasticsInterface &) const; - - std::set<SpawnSpot, Less<ToLength>>::const_iterator SampleSpot(units::length::meter_t min_length, VelocityRange, StochasticsInterface &) const; - - /// Tries to spawn an entity and returns whether spawning was successful. - /// If successful, also adjusts the spawn space's intervals. - /// - /// \tparam EntityCreator Provides CreateEntity(const std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::IScenarioObject> &) - /// \param StochasticsInterface Used to sample the entity, its position and its velocity - template <typename EntityCreator> - bool Spawn(EntityCreator &&, StochasticsInterface &); - - units::length::meter_t GetMaxIntervalLength() const; - - typename std::vector<Weighted<ObjectTemplatePtr>>::const_iterator FindSpawnableEntityEnd(units::length::meter_t upper_bound) const; - typename std::vector<Weighted<ObjectTemplatePtr>>::iterator FindSpawnableEntityEnd(units::length::meter_t upper_bound); - - std::set<SpawnSpot, Less<ToLength>> spots; -}; - //! Receives a vector of spawn spots, an iterator to a spot within that vector, an interval contained by that spot and a velocity. //! Replaces the spot pointed to by the iterator with the disjunction of the spot's interval and the given interval. //! The velocities of the new spots match the given velocity at the end where they touch the given interval. @@ -178,25 +140,4 @@ bool SequentialSpawnSpace::Spawn(EntityCreator &&spawner, AttachControllers &&at return false; } -template <typename EntityCreator> -bool DistributedSpawnSpace::Spawn(EntityCreator &&spawner, StochasticsInterface &stochastics) -{ - ObjectTemplatePtr blueprint{SampleObjectTemplate(stochastics)}; - if (blueprint == nullptr) - { - return false; - } - const auto velocity_range{GetSpawnVelocityRange(blueprint)}; - const auto spot{SampleSpot(GetLength(blueprint), velocity_range, stochastics)}; - if (spot == spots.end()) - { - return false; - } - auto spawn_velocity{SampleVelocity(velocity_range, stochastics)}; - // TODO: Find last spawnable spot on the zone of the sampled interval - // spawner.CreateEntity(*entity, place.zone->GetPosition(distance)); - // TODO: Remove/replace interval - // spot->zone->RemoveInterval(*interval->interval, sampler(restricted_velocity.min, restricted_velocity.max)); - return true; -} } // namespace OpenScenarioEngine::v1_3