Esempio n. 1
0
/**
 * 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;

}
Esempio n. 4
0
/// Sets the reference epoch
void keplerian::set_ref_epoch(const kep_toolbox::epoch& when) {
	m_ref_mjd2000 = when.mjd2000();
}
Esempio n. 5
0
// 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);
}