pioneer/src/TransferPlanner.cpp

147 lines
3.8 KiB
C++

// Copyright © 2008-2021 Pioneer Developers. See AUTHORS.txt for details
// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
#include "TransferPlanner.h"
#include "Frame.h"
#include "Game.h"
#include "Orbit.h"
#include "Pi.h"
#include "Player.h"
#include <sstream>
TransferPlanner::TransferPlanner() :
m_position(0., 0., 0.),
m_velocity(0., 0., 0.)
{
m_dvPrograde = 0.0;
m_dvNormal = 0.0;
m_dvRadial = 0.0;
m_startTime = 0.0;
m_factor = 1;
}
vector3d TransferPlanner::GetVel() const { return m_velocity + GetOffsetVel(); }
vector3d TransferPlanner::GetOffsetVel() const
{
if (m_position.ExactlyEqual(vector3d(0., 0., 0.)))
return vector3d(0., 0., 0.);
const vector3d pNormal = m_position.Cross(m_velocity);
return m_dvPrograde * m_velocity.Normalized() +
m_dvNormal * pNormal.Normalized() +
m_dvRadial * m_position.Normalized();
}
void TransferPlanner::AddStartTime(double timeStep)
{
if (std::fabs(m_startTime) < 1.)
m_startTime = Pi::game->GetTime();
m_startTime += m_factor * timeStep;
double deltaT = m_startTime - Pi::game->GetTime();
if (deltaT > 0.) {
FrameId frameId = Frame::GetFrame(Pi::player->GetFrame())->GetNonRotFrame();
Frame *frame = Frame::GetFrame(frameId);
Orbit playerOrbit = Orbit::FromBodyState(Pi::player->GetPositionRelTo(frameId), Pi::player->GetVelocityRelTo(frameId), frame->GetSystemBody()->GetMass());
m_position = playerOrbit.OrbitalPosAtTime(deltaT);
m_velocity = playerOrbit.OrbitalVelocityAtTime(frame->GetSystemBody()->GetMass(), deltaT);
} else
ResetStartTime();
}
void TransferPlanner::ResetStartTime()
{
m_startTime = 0;
Frame *frame = Frame::GetFrame(Pi::player->GetFrame());
if (!frame || GetOffsetVel().ExactlyEqual(vector3d(0., 0., 0.))) {
m_position = vector3d(0., 0., 0.);
m_velocity = vector3d(0., 0., 0.);
} else {
frame = Frame::GetFrame(frame->GetNonRotFrame());
m_position = Pi::player->GetPositionRelTo(frame->GetId());
m_velocity = Pi::player->GetVelocityRelTo(frame->GetId());
}
}
double TransferPlanner::GetStartTime() const
{
return m_startTime < 0.0 ? 0.0 : m_startTime;
}
void TransferPlanner::AddDv(BurnDirection d, double dv)
{
if (m_position.ExactlyEqual(vector3d(0., 0., 0.))) {
FrameId frame = Frame::GetFrame(Pi::player->GetFrame())->GetNonRotFrame();
m_position = Pi::player->GetPositionRelTo(frame);
m_velocity = Pi::player->GetVelocityRelTo(frame);
m_startTime = Pi::game->GetTime();
}
switch (d) {
case PROGRADE: m_dvPrograde += m_factor * dv; break;
case NORMAL: m_dvNormal += m_factor * dv; break;
case RADIAL: m_dvRadial += m_factor * dv; break;
}
}
void TransferPlanner::ResetDv(BurnDirection d)
{
switch (d) {
case PROGRADE: m_dvPrograde = 0; break;
case NORMAL: m_dvNormal = 0; break;
case RADIAL: m_dvRadial = 0; break;
}
if (std::fabs(m_startTime) < 1. &&
GetOffsetVel().ExactlyEqual(vector3d(0., 0., 0.))) {
m_position = vector3d(0., 0., 0.);
m_velocity = vector3d(0., 0., 0.);
m_startTime = 0.;
}
}
void TransferPlanner::ResetDv()
{
m_dvPrograde = 0;
m_dvNormal = 0;
m_dvRadial = 0;
if (std::fabs(m_startTime) < 1.) {
m_position = vector3d(0., 0., 0.);
m_velocity = vector3d(0., 0., 0.);
m_startTime = 0.;
}
}
double TransferPlanner::GetDv(BurnDirection d)
{
switch (d) {
case PROGRADE: return m_dvPrograde; break;
case NORMAL: return m_dvNormal; break;
case RADIAL: return m_dvRadial; break;
}
return 0.0;
}
void TransferPlanner::IncreaseFactor(void)
{
if (m_factor > 1000) return;
m_factor *= m_factorFactor;
}
void TransferPlanner::ResetFactor(void) { m_factor = 1; }
void TransferPlanner::DecreaseFactor(void)
{
if (m_factor < 0.0002) return;
m_factor /= m_factorFactor;
}
vector3d TransferPlanner::GetPosition() const { return m_position; }
void TransferPlanner::SetPosition(const vector3d &position) { m_position = position; }