Program Listing for File rover.cc¶
↰ Return to documentation for file (agents/rover.cc)
#include "lupnt/agents/rover.h"
#include "lupnt/conversions/attitude_conversions.h"
#include "lupnt/conversions/coordinate_conversions.h"
#include "lupnt/conversions/frame_converter.h"
#include "lupnt/core/data_logger.h"
#include "lupnt/core/logger.h"
#include "lupnt/states/state.h"
namespace lupnt {
// Rover
Rover::Rover(Config& agent_config) : AgentWithDynamics(agent_config) {
Logger::Debug(fmt::format("Creating Rover {}", name_), "Rover");
// Initial state
if (agent_config["initial_state"]) {
// Reference location
auto cfg = agent_config["initial_state"];
Real lat_ref = RAD * cfg["lat_ref"].as<Real>();
Real lon_ref = RAD * cfg["lon_ref"].as<Real>();
r_ref_pa_ = Cart3(LatLonAltToCart(Vec3(lat_ref, lon_ref, 0.0), R_MOON), Frame::MOON_PA);
DataLogger::LogState(name_, r_ref_pa_);
// State
Real x = cfg["x"].as<Real>();
Real y = cfg["y"].as<Real>();
Real z = 0;
Real theta = RAD * cfg["th"].as<Real>();
state2d_ = SurfaceState2D({x, y, theta});
Real vx = 0.0, vy = 0.0, vz = 0.0;
Cart6 rv_enu({x, y, z, vx, vy, vz}, Frame::MOON_PA);
Cart6 rv_pa = EastNorthUpToCart(rv_enu, r_ref_pa_);
state_ = rv_pa;
// Attitude
Vec3 front = {cos(theta), sin(theta), 0.0};
Vec3 up = Vec3::UnitZ();
Vec3 left = up.cross(front);
Mat3 pa_R_body;
pa_R_body << front, left, up;
Vec3 w_pa = Vec3::Zero();
Vec4 q_pa = RotToQuat(pa_R_body);
attitude_ = Attitude(q_pa, w_pa, Frame::MOON_PA);
// Control
control_ = State(2);
control_.SetNames({"v", "w"});
control_.SetUnits({"m/s", "rad/s"});
Logger::Debug(fmt::format("Reference location: ({}, {})", lat_ref * DEG, lon_ref * DEG),
"Rover");
Logger::Debug(fmt::format("Initial state: {}", state_), "Rover");
} else {
LUPNT_CHECK(false, "No initial state found", "Rover");
}
}
void Rover::Propagate(Real t) {
Logger::Debug(fmt::format("Propagating {} from t={} s to t={} s", name_, time_, t), "Agent", t);
state2d_ = dynamics_->Propagate(state2d_, time_, t, &control_);
Real x = state2d_(0);
Real y = state2d_(1);
Real theta = state2d_(2);
Real z = 0;
Real v = control_(0);
Real w = control_(1);
Cart6 rv_enu({x, y, z, v * cos(theta), v * sin(theta), 0.0}, Frame::MOON_PA);
Cart6 rv_pa = EastNorthUpToCart(rv_enu, r_ref_pa_);
state_ = rv_pa;
// Attitude
Vec3 front = {cos(theta), sin(theta), 0.0};
Vec3 up = Vec3::UnitZ();
Vec3 left = up.cross(front);
Mat3 pa_R_body;
pa_R_body << front, left, up;
Mat3 R_enu2pa = RotEastNorthUpToCart(r_ref_pa_, R_MOON);
Vec3 w_pa = R_enu2pa * Vec3{0.0, 0.0, w};
Vec4 q_pa = RotToQuat(pa_R_body);
attitude_ = Attitude(q_pa, w_pa, Frame::MOON_PA);
time_ = t;
}
void Rover::Log(Real time) {
Agent::Log(time);
// State2D
// for (int i = 0; i < state2d_.size(); i++) {
// auto name = state2d_.GetNames()[i];
// auto unit = state2d_.GetUnits()[i];
// std::replace(unit.begin(), unit.end(), '/', '_');
// auto value = state2d_(i);
// DataLogger::Log(fmt::format("{}/state2d/{}_{}", name_, name, unit), value);
// }
// DataLogger::Log(fmt::format("{}/state2d_vec", name_), state2d_);
}
REGISTER_FACTORY_CLASS(Agent, Rover)
} // namespace lupnt