/** * Constructs a global optimization problem (box-bounded, continuous) representing an interplanetary trajectory modelled * as a Multiple Gravity Assist trajectory that allows one only Deep Space Manouvre between each leg. * * @param[in] seq std::vector of kep_toolbox::planet_ptr containing the encounter sequence for the trajectoty (including the initial planet) * @param[in] t0_l kep_toolbox::epoch representing the lower bound for the launch epoch * @param[in] t0_u kep_toolbox::epoch representing the upper bound for the launch epoch * @param[in] tof time-of-flight vector containing lower and upper bounds (in days) for the various legs time of flights * @param[in] Tmax maximum time of flight * @param[in] Dmin minimum distance from Jupiter (for radiation protection) * * @throws value_error if the planets in seq do not all have the same central body gravitational constant * @throws value_error if tof has a size different from seq.size() */ mga_incipit_cstrs::mga_incipit_cstrs( const std::vector<kep_toolbox::planets::planet_ptr> seq, const kep_toolbox::epoch t0_l, const kep_toolbox::epoch t0_u, const std::vector<std::vector<double> > tof, double Tmax, double Dmin) : base(4*seq.size(),0,1,2,2,1E-3), m_tof(tof), m_tmax(Tmax), m_dmin(Dmin) { // We check that all planets have equal central body std::vector<double> mus(seq.size()); for (std::vector<kep_toolbox::planets::planet_ptr>::size_type i = 0; i< seq.size(); ++i) { mus[i] = seq[i]->get_mu_central_body(); } if ((unsigned int)std::count(mus.begin(), mus.end(), mus[0]) != mus.size()) { pagmo_throw(value_error,"The planets do not all have the same mu_central_body"); } // We check the consistency of the time of flights if (tof.size() != seq.size()) { pagmo_throw(value_error,"The time-of-flight vector (tof) has the wrong length"); } for (size_t i = 0; i < tof.size(); ++i) { if (tof[i].size()!=2) pagmo_throw(value_error,"Each element of the time-of-flight vector (tof) needs to have dimension 2 (lower and upper bound)"); } // Filling in the planetary sequence data member. This requires to construct the polymorphic planets via their clone method for (std::vector<kep_toolbox::planets::planet_ptr>::size_type i = 0; i < seq.size(); ++i) { m_seq.push_back(seq[i]->clone()); } // Now setting the problem bounds size_type dim(4*m_tof.size()); decision_vector lb(dim), ub(dim); // First leg lb[0] = t0_l.mjd2000(); ub[0] = t0_u.mjd2000(); lb[1] = 0; lb[2] = 0; ub[1] = 1; ub[2] = 1; lb[3] = m_tof[0][0]; ub[3] = m_tof[0][1]; // Successive legs for (std::vector<kep_toolbox::planets::planet_ptr>::size_type i = 1; i < m_tof.size(); ++i) { lb[4*i] = - 2 * boost::math::constants::pi<double>(); ub[4*i] = 2 * boost::math::constants::pi<double>(); lb[4*i+1] = 1.1; ub[4*i+1] = 30; lb[4*i+2] = 1e-5; ub[4*i+2] = 1-1e-5; lb[4*i+3] = m_tof[i][0]; ub[4*i+3] = m_tof[i][1]; } // Adjusting the minimum and maximum allowed fly-by rp to the one defined in the kep_toolbox::planet class for (std::vector<kep_toolbox::planets::planet_ptr>::size_type i = 0; i < m_tof.size()-1; ++i) { lb[4*i+5] = m_seq[i]->get_safe_radius() / m_seq[i]->get_radius(); ub[4*i+5] = (m_seq[i]->get_radius() + 2000000) / m_seq[i]->get_radius(); //from gtoc6 problem description } set_bounds(lb,ub); }
void printValues() { cout << "Start epoch: " << start.mjd2000() << " (" << start << ")" <<endl; cout << "Duration: " << duration << endl; cout << "Asteroid density: " << asteroidsDensity << endl; cout << "BEE delta v limit: " << maxDeltaV << endl; cout << "Filter delta v limit: " << maxDatabaseDeltaV << endl; cout << "Nelder Mead delta v limit (max transfer cost) : " << nelderMeadDeltaV << endl; cout << "Nelder Mead resolution: " << nelderMeadGridResolution << endl; cout << "Nelder Mead epsilon: " << epsilon << endl; cout << "Porkchop resolution: " << porkchopResolution << endl; cout << endl; }
int main(int argc, char** argv) { double before, after; auto vm = parseCommandLine(argc, argv); if (vm.count("help")) { return 1; } printValues(); if (print) { return 0; } model::NelderMead::setEpsilon(epsilon); model::NelderMead::setMaxIterations(100); model::NelderMead::setMissionDuration(duration); model::NelderMead::setMaximumTof(maxTof); model::NelderMead::setMissionStart(start); model::NelderMead::setResolution(nelderMeadGridResolution); model::NelderMead::setMaximumDeltaV(nelderMeadDeltaV); // generate filtered database if (filterAsteroids) { model::NelderMead::setMaximumDeltaV(maxDatabaseDeltaV); model::FilterAsteroids().run(&hive, sourceDatabase, filteredDatabase, true); model::NelderMead::setMaximumDeltaV(nelderMeadDeltaV); } // perform search if (search) { // load filtered database std::vector<model::Asteroid*> asteroids; before = model::getMillis(); asteroids = model::AstorbReader(filteredDatabase).readAsteroids(asteroidsDensity); asteroids.push_back(&hive); after = model::getMillis(); cout << "Database contains " << asteroids.size() << " asteroids, loaded in " << after - before << " ms." << endl; cout << endl; model::Transferbase transferbase(progressFile, asteroids, start.mjd2000(), duration, nelderMeadDeltaV, nelderMeadGridResolution, epsilon, static_cast<int>(asteroids.size()), asteroidsDensity); if (transferbase.fileExists() and not noResume) { // resume previous progress before = model::getMillis(); transferbase.load(true); after = model::getMillis(); if (not noResume) { cout << "Resumed from previous progress in " << after - before << " ms." << endl << endl; } } else { // create new database transferbase.create(); } before = model::getMillis(); hive.calculateTransfers(asteroids, &transferbase, maxDeltaV, static_cast<int>(start.mjd2000())); after = model::getMillis(); cout << "Performed search in " << (after - before) / 1000.0 << " s." << endl << endl; } if (finalize.length() > 0) { // split filenames size_t commaIndex = finalize.find(','); if (commaIndex == std::string::npos) { cout << "Could not parse the filenames" << endl; return 1; } std::string inputFile = finalize.substr(0,commaIndex), outputFile = finalize.substr(commaIndex+1, finalize.length() - commaIndex - 1); // load unfiltered database std::vector<model::Asteroid*> asteroids; before = model::getMillis(); asteroids = model::AstorbReader(filteredDatabase).readAsteroids(1); asteroids.push_back(&hive); after = model::getMillis(); before = model::getMillis(); model::Transferbase::finalizeTransferbase(&hive, asteroids, maxDeltaV, inputFile, outputFile); after = model::getMillis(); cout << "Finalized transfer database in " << after - before << "ms." << endl; } if (porkchop.length() > 0) { // load unfiltered database std::vector<model::Asteroid*> asteroids; before = model::getMillis(); asteroids = model::AstorbReader(sourceDatabase).readAsteroids(1); asteroids.push_back(&hive); after = model::getMillis(); cout << "Database contains " << asteroids.size() << " asteroids, loaded in " << after - before << " ms." << endl; cout << endl; asteroids.push_back(&hive); // find asteroid names size_t commaIndex = porkchop.find(','); if (commaIndex == std::string::npos) { cout << "Could not parse the asteroid names" << endl; return 1; } std::string fromString = porkchop.substr(0,commaIndex), toString = porkchop.substr(commaIndex+1, porkchop.length() - commaIndex - 1); cout << "Generating porkchop from " << fromString << " to " << toString << endl; // find asteroids model::Asteroid *from=nullptr, *to=nullptr; for (model::Asteroid* asteroid : asteroids) { if (asteroid->getName().find(fromString) != std::string::npos) { from = asteroid; } if (asteroid->getName().find(toString) != std::string::npos) { to = asteroid; } } if (from == nullptr) { cout << "could not find an asteroid in database named " << fromString << endl; return 1; } else { cout << "Found from asteroid:\t" << from->getName() << " " << from->getPlanet().get_elements() << endl; } if (to == nullptr) { cout << "could not find an asteroid in database named " << toString << endl; return 1; } else { cout << "Found to asteroid:\t" << to->getName()<< " " << to->getPlanet().get_elements() << endl; } bool porkchopTof = true; cout << "Generating pork-chop plot" << endl; model::PorkChop porkchop(from->getPlanet(), to->getPlanet(), porkchopResolution, porkchopResolution, start, kep_toolbox::epoch(start.mjd2000() + duration), -1, maxDeltaV); // model::PorkChop porkchop(kep_toolbox::planet_ss("Earth"), kep_toolbox::planet_ss("Mars"), porkchopResolution, porkchopResolution, start, kep_toolbox::epoch(start.mjd2000() + duration), -1, maxDeltaV); if (porkchopTof) { porkchop.generateTof("porkchop"); } else { porkchop.generateArrival("porkchop", kep_toolbox::epoch(2137), kep_toolbox::epoch(2161)); } } if (printBranching.length() > 0) { cout << "Printing branching for file \"" << printBranching << "\"" << endl; // load filtered database std::vector<model::Asteroid*> asteroids; before = model::getMillis(); asteroids = model::AstorbReader(filteredDatabase).readAsteroids(asteroidsDensity); asteroids.push_back(&hive); after = model::getMillis(); model::Transferbase transferbase(printBranching, asteroids); transferbase.load(false); transferbase.printTransferbase(&hive, maxDeltaV); } #if NELDER_MEAD_DEBUG model::NelderMead::printDebug(); #endif cout << "finished" << endl; }
/// Sets the reference epoch void keplerian::set_ref_epoch(const kep_toolbox::epoch& when) { m_ref_mjd2000 = when.mjd2000(); }
// Wrappers for the ephemerides computations static inline tuple eph_wrapper1(const kep_toolbox::planet::base &p, const kep_toolbox::epoch &when) { kep_toolbox::array3D r, v; p.eph(when.mjd2000(),r,v); return boost::python::make_tuple(r,v); }