9constexpr float kMissingTargetDistance = 99999.0f;
10constexpr double kVelocitySolverTolerance = 1.0e-3;
11constexpr int kVelocitySolverMaxIterations = 30;
12constexpr double kVelocitySolverJacobianStep = 0.01;
13constexpr double kVelocitySolverDamping = 1.0;
17 registerKinematicsProblems();
22 if (knowns.find(
"r0") != knowns.end() && knowns.find(
"v0") != knowns.end()) {
27 auto solver =
makeSolver(body, knowns, unknown);
32 std::vector<std::vector<std::string>> options;
34 auto it = solverMap.find(unknown);
35 if (it != solverMap.end()) {
37 for (
const auto& entry : it->second) {
38 options.push_back(entry.requiredKeys);
44bool ProblemRouter::areRequirementsMet(
const std::vector<std::string>& required,
const std::unordered_map<std::string, double>& knowns)
const {
45 return std::all_of(required.begin(), required.end(), [&](
const std::string& key) {
46 return knowns.find(key) != knowns.end();
51 auto it = solverMap.find(unknown);
52 if (it == solverMap.end()) {
53 std::cerr <<
"No solver registered for unknown: " << unknown << std::endl;
57 for (
const auto& entry : it->second) {
58 if (areRequirementsMet(entry.requiredKeys, knowns)) {
59 return entry.factory(body, knowns);
63 std::cerr <<
"Insufficient knowns provided for unknown: " << unknown << std::endl;
67void ProblemRouter::registerKinematicsProblems() {
68 constexpr double maxSimTime = 10.0;
144 SolverEntry eventEntry;
145 eventEntry.requiredKeys = {
146 "r0_x",
"r0_y",
"r0_z",
147 "v0_x",
"v0_y",
"v0_z",
148 "Stop_SubjectID",
"Stop_Prop",
"Stop_Op",
"Stop_Val",
150 "Stop_Val_X",
"Stop_Val_Y",
"Stop_Val_Z"
153 eventEntry.factory = [
this](
Physics::PhysicsBody* body,
const std::unordered_map<std::string, double>& knowns) {
154 glm::vec3 r0(knowns.at(
"r0_x"), knowns.at(
"r0_y"), knowns.at(
"r0_z"));
155 glm::vec3 v0(knowns.at(
"v0_x"), knowns.at(
"v0_y"), knowns.at(
"v0_z"));
157 physicsSystem.
reset();
161 int subjectID = (int)knowns.at(
"Stop_SubjectID");
162 int prop = (int)knowns.at(
"Stop_Prop");
163 int op = (int)knowns.at(
"Stop_Op");
164 float val = (float)knowns.at(
"Stop_Val");
166 if (subjectID == -1) {
167 std::cout <<
"Solver Error: No subject selected." << std::endl;
168 auto dummyMonitor = []() {
return -1.0f; };
169 auto dummyTimeout = []() {
return true; };
170 return std::make_unique<InterceptSolver>(dummyMonitor, dummyTimeout);
176 int targetID = (int)knowns.at(
"Stop_TargetID");
177 glm::vec3 targetPoint(knowns.at(
"Stop_Val_X"), knowns.at(
"Stop_Val_Y"), knowns.at(
"Stop_Val_Z"));
180 auto monitor = [=,
this]() ->
float {
181 float currentVal = 0.0f;
197 return col->closestPoint(targetPos).point;
204 glm::vec3 pTarget = getClosestOnBody(targetBody, centerSubject);
205 glm::vec3 pSubject = getClosestOnBody(subject, pTarget);
207 currentVal = glm::distance(pSubject, pTarget);
209 currentVal = kMissingTargetDistance;
219 currentVal = physicsSystem.
simTime;
224 return (currentVal - val);
227 return (val - currentVal);
231 auto timeout = [=]() {
return false; };
233 return std::make_unique<InterceptSolver>(monitor, timeout);
235 solverMap[
"Event"].push_back(eventEntry);
238 v0Entry.requiredKeys = {
239 "r0_x",
"r0_y",
"r0_z",
240 "Stop_SubjectID",
"Stop_Prop",
"Stop_Op",
"Stop_Val",
242 "Stop_Val_X",
"Stop_Val_Y",
"Stop_Val_Z",
246 v0Entry.factory = [
this](
Physics::PhysicsBody* body,
const std::unordered_map<std::string, double>& knowns) {
247 int subjectID = (int)knowns.at(
"Stop_SubjectID");
248 int stopTargetID = (int)knowns.at(
"Stop_TargetID");
250 double targetTime = knowns.count(
"Target_Time") ? knowns.at(
"Target_Time") : -1.0;
255 glm::vec3 r0(knowns.at(
"r0_x"), knowns.at(
"r0_y"), knowns.at(
"r0_z"));
256 int prop = (int)knowns.at(
"Stop_Prop");
257 int op = (int)knowns.at(
"Stop_Op");
258 float val = (float)knowns.at(
"Stop_Val");
259 glm::vec3 stopTargetPoint(knowns.at(
"Stop_Val_X"), knowns.at(
"Stop_Val_Y"), knowns.at(
"Stop_Val_Z"));
261 glm::vec3 targetPos(0.0f);
263 targetPos = stopTargetPoint;
264 }
else if (prop == 2 && targetBody) {
268 auto setter = [=,
this](
const glm::vec3& guess_v0) {
269 physicsSystem.
reset();
273 auto stopCondition = [=,
this]() ->
bool {
274 if (targetTime > 0.0f) {
275 return physicsSystem.
simTime >= targetTime;
277 if (!subjectBody)
return true;
279 float currentVal = 0.0f;
292 currentVal = kMissingTargetDistance;
300 if (op == 0)
return (currentVal <= val);
301 else return (currentVal >= val);
304 auto extractor = [=]() -> glm::vec3 {
308 return std::make_unique<VectorRootSolver<glm::vec3, glm::vec3>>(
309 setter, stopCondition, extractor, targetPos,
310 kVelocitySolverTolerance,
311 kVelocitySolverMaxIterations,
312 kVelocitySolverJacobianStep,
313 kVelocitySolverDamping
317 solverMap[
"v0"].push_back(v0Entry);
void setPosition(const glm::vec3 &pos, BodyLock lock)
glm::vec3 getVelocity(BodyLock lock) const
void setVelocity(const glm::vec3 &vel, BodyLock lock)
glm::vec3 getPosition(BodyLock lock) const
virtual Bounding::ICollider * getCollider() const
PhysicsBody * getBodyById(uint32_t id) const
std::vector< std::vector< std::string > > getRequiredKeys(const std::string &unknown) const
ProblemRouter(Physics::PhysicsSystem &physicsSystem)
std::unique_ptr< ISolver > makeSolver(Physics::PhysicsBody *body, const std::unordered_map< std::string, double > &knowns, const std::string &unknown) const
SolverDecision routeProblem(Physics::PhysicsBody *body, const std::unordered_map< std::string, double > &knowns, const std::string &unknown) const