feat: New predicting algorithm

This commit is contained in:
Pax1601
2025-03-16 22:33:28 +01:00
parent e2ac37ef18
commit 3aafa26c70
4 changed files with 47 additions and 4 deletions

View File

@@ -242,7 +242,12 @@ void GroundUnit::AIloop()
if (!getHasTask()) {
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'FireAtPoint', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << ", radius = 100}";
if (targetPosition.alt == NULL) {
taskSS << "{id = 'FireAtPoint', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << ", radius = 100}";
}
else {
taskSS << "{id = 'FireAtPoint', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << ", alt = " << targetPosition.alt << ", radius = 100}";
}
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
@@ -429,9 +434,22 @@ void GroundUnit::AIloop()
taskString += "Missing on purpose. Valid target at range: " + to_string((int) round(distance)) + "m";
double correctedAimTime = aimTime;
double dstep = 0;
double vstep = muzzleVelocity;
double dt = 0.1;
double k = 0.0086;
double gdelta = 9.81;
/* Approximate the flight time */
if (muzzleVelocity != 0)
correctedAimTime += distance / muzzleVelocity;
unsigned int stepCount = 0;
if (muzzleVelocity != 0) {
while (dstep < distance && stepCount < 1000) {
dstep += vstep * dt;
vstep -= (k * vstep + gdelta) * dt;
stepCount++;
}
correctedAimTime += stepCount * dt;
}
/* If the target is in targeting range and we are in highest precision mode, target it */
if (distance < targetingRange && shotsScatter == ShotsScatter::LOW) {

View File

@@ -619,6 +619,11 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
double lat = value[L"location"][L"lat"].as_double();
double lng = value[L"location"][L"lng"].as_double();
Coords loc; loc.lat = lat; loc.lng = lng;
if (value[L"location"].has_number_field(L"alt")) {
loc.alt = value[L"location"][L"alt"].as_double();
}
Unit* unit = unitsManager->getGroupLeader(ID);
if (unit != nullptr) {
unit->setTargetPosition(loc);

View File

@@ -50,6 +50,8 @@ import {
import { OlympusConfig } from "../../interfaces";
import { FaCheck, FaQuestionCircle, FaSave, FaSpinner } from "react-icons/fa";
import { OlExpandingTooltip } from "../components/olexpandingtooltip";
import { ftToM } from "../../other/utils";
import { LatLng } from "leaflet";
export function Header() {
const [mapHiddenTypes, setMapHiddenTypes] = useState(MAP_HIDDEN_TYPES_DEFAULTS);
@@ -219,6 +221,18 @@ export function Header() {
/>
</div>
<div className={`h-8 w-0 border-l-[2px] border-gray-700`}></div>
<OlRoundStateButton
onClick={() => {
getApp().getUnitsManager().getSelectedUnits().forEach((unit) => {
let position = new LatLng(unit.getPosition().lat, unit.getPosition().lng);
position.lat += 0.01;
position.alt = ftToM(15000);
unit.fireAtArea(position);
})
}}
checked={false}
icon={faFlag}
/>
<div className={`flex h-fit flex-row items-center justify-start gap-1`}>
{Object.entries({
human: olButtonsVisibilityHuman,

View File

@@ -20,7 +20,9 @@ export abstract class Weapon extends CustomMarker {
#hidden: boolean = false;
#detectionMethods: number[] = [];
#speedVector: number[] = [];
#altitude: number[] = [];
getAlive() {
return this.#alive;
}
@@ -86,6 +88,7 @@ export abstract class Weapon extends CustomMarker {
break;
case DataIndexes.speed:
this.#speed = dataExtractor.extractFloat64();
this.#speedVector.push(this.#speed);
updateMarker = true;
break;
case DataIndexes.heading:
@@ -113,6 +116,9 @@ export abstract class Weapon extends CustomMarker {
setAlive(newAlive: boolean) {
this.#alive = newAlive;
if (this.#speedVector.length > 0 && newAlive === false) {
let asd = 1;
}
}
belongsToCommandedCoalition() {