Hello all,
I am wondering if anyone could help me. I am new to Julia language and it is being quiete difficult to understand how to embed julia in a cpp code.
What I am trying is to use the pkg SatelliteToolbox from julia in a satellite simulator code written in cpp in order to improve the orbit propagation module with the SGP4 propagation from the SatelliteToolbox. I do not know also if it is possible (although I guess yes after reading the docu…).
I have developed the code embeding the functions and then I have implemented a test achieving the following error:
Note that the simulator is based in the ns3 library (https://www.nsnam.org/
As I see the error, it seems a library error… however, the test implemented is exactly the same for the Kepler orbit propagation written in cpp, and it is running without errors. As I have implemented the embedding code for the SGP4 propagation, since the outputs of the functions are the same, the test should be equal.
The embedded code is the following:
std::tuple<ECICoordinates, ECICoordinates> SGP4OrbitTrajectory::propagateOrbit(double time)
{
ECICoordinates eci_position;
ECICoordinates eci_velocity;
jl_init();
jl_eval_string("using SatelliteToolbox");
jl_module_t* SatTool = (jl_module_t *)jl_eval_string("SatelliteToolbox");
jl_function_t *sgp4_init = jl_get_function(SatTool, "sgp4_init");
jl_function_t *OrbitPropagatorSGP4 = jl_get_function(SatTool, "OrbitPropagatorSGP4");
jl_function_t *propagate = jl_get_function(SatTool, "propagate!");
// Convert cpp parameters to julia
jl_value_t *sgp4_gc = jl_eval_string("sgp4_gc_wgs84");
jl_value_t *epoch = jl_box_float64(TimeUtils::getJDEpoch()); //Should we use input time as epoch?
jl_value_t *meanMotion = jl_box_float64(m_angular_speed);
jl_value_t *eccentricity = jl_box_float64(m_orbit_params.eccentricity);
jl_value_t *inclination = jl_box_float64(m_orbit_params.inclination);
jl_value_t *raan = jl_box_float64(m_orbit_params.raan);
jl_value_t *argPerigee = jl_box_float64(m_orbit_params.arg_perigee);
jl_value_t *meanAnomaly = jl_box_float64(m_init_mean_anomaly);
jl_value_t *bStar = jl_box_float64(m_bStar);
struct _jl_value_t *arguments[9] = {sgp4_gc, epoch, meanMotion, eccentricity, inclination, raan, argPerigee, meanAnomaly, bStar};
struct _jl_value_t *sgp4d = jl_call(sgp4_init, arguments, 9); // Initialize the data structure of SGP4 algorithm.
struct _jl_value_t *orbp = jl_call(OrbitPropagatorSGP4, &sgp4d, 1); // Create and return the orbit propagator structure.
JL_GC_PUSH2(&sgp4d, &orbp);
/* In julia terminal, it should run -> jl_eval_string("r_TEME, v_TEME = propagate!(orbp, t)");
Then, propagate! funtion returns a 2D array object y = [r_TEME(x, y, z), v_TEME(x, y, z)].
*/
jl_array_t *y = (jl_array_t*)jl_call2(propagate, orbp, t); // Create and return the orbit propagator structure.
double *RVTeme = (double*)jl_array_data(y);
eci_position = RVTeme[0];
eci_velocity = RVTeme[1];
JL_GC_POP();
jl_atexit_hook(0);
return std::make_tuple(eci_position, eci_velocity);
}
I not an expert programing… So I guess that I will have many incoherences. And the test is the following:
#ifndef __TEST_SGP4_ORBIT_HPP__
#define __TEST_SGP4_ORBIT_HPP__
#include <gtest/gtest.h>
#include <complex>
#include "dss.hpp"
#include "SGP4OrbitTrajectory.hpp"
#include "OrbitalParams.hpp"
#include "ECICoordinates.hpp"
#include "TLE.hpp"
#include "SimulatorError.hpp"
namespace
{
class SGP4OrbitTest : public ::testing::Test
{
protected:
std::string tle_line;
TLE* random_tle;
SGP4OrbitTrajectory* orbit;
std::vector<std::tuple<ECICoordinates, ECICoordinates>> current_state;
std::vector<ECICoordinates> current_position;
std::vector<ECICoordinates> current_velocity;
std::vector<double> time {0.0, 360.0, 720.0, 1080.0, 1440.0, 1800.0, 2160.0, 2520.0,
2880.0, 3240.0, 3600.0, 3960.0, 4320.0 };
ECICoordinates p;
ECICoordinates p1;
ECICoordinates p2;
ECICoordinates p3;
ECICoordinates p4;
ECICoordinates p5;
ECICoordinates p6;
ECICoordinates p7;
ECICoordinates p8;
ECICoordinates p9;
ECICoordinates p1o;
ECICoordinates p11;
ECICoordinates p12;
ECICoordinates v;
ECICoordinates v1;
ECICoordinates v2;
ECICoordinates v3;
ECICoordinates v4;
ECICoordinates v5;
ECICoordinates v6;
ECICoordinates v7;
ECICoordinates v8;
ECICoordinates v9;
ECICoordinates v1o;
ECICoordinates v11;
ECICoordinates v12;
virtual void SetUp()
{
for(int k = 0; k < 13; k++) {
current_state.push_back(std::make_tuple(ECICoordinates(0.0, 0.0, 0.0), ECICoordinates(0.0, 0.0, 0.0)));
current_position.push_back(ECICoordinates(0.0, 0.0, 0.0));
current_velocity.push_back(ECICoordinates(0.0, 0.0, 0.0));
}
/* Random Satellite TLE */
tle_line = "RANDOM 1\n";
tle_line += "1 00005U 58002B 00179.78495062 .00000023 00000-0 28098-4 0 4753\n";
tle_line += "2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667";
random_tle = new TLE(tle_line);
/* Expected results */
p = ECICoordinates(7022.46529266, -1400.08296755, 0.03995155);
p1 = ECICoordinates(-7154.03120202, -3783.17682504, -3536.19412294);
p2 = ECICoordinates(-7134.59340119, 6531.68641334, 3260.27186483);
p3 = ECICoordinates(5568.53901181, 4492.06992591, 3863.87641983);
p4 = ECICoordinates(-938.55923943, -6268.18748831, -4294.02924751);
p5 = ECICoordinates(-9680.56121728, 2802.47771354, 124.10688038);
p6 = ECICoordinates(190.19796988, 7746.96653614, 5110.00675412);
p7 = ECICoordinates(5579.55640116, -3995.61396789, -1518.82108966);
p8 = ECICoordinates(-8650.73082219, -1914.93811525, -3007.03603443);
p9 = ECICoordinates(-5429.79204164, 7574.36493792, 3747.39305236);
p1o = ECICoordinates(6759.04583722, 2001.58198220, 2783.55192533);
p11 = ECICoordinates(-3791.44531559, -5712.95617894, -4533.48630714);
p12 = ECICoordinates(-9060.47373569, 4658.70952502, 813.68673153);
v = ECICoordinates(1.893841015, 6.405893759, 4.534807250);
v1 = ECICoordinates(4.741887409, -4.151817765, -2.093935425 );
v2 = ECICoordinates(-4.113793027, -2.911922039, -2.557327851);
v3 = ECICoordinates(-4.209106476, 5.159719888, 2.744852980);
v4 = ECICoordinates(7.536105209, -0.427127707, 0.989878080);
v5 = ECICoordinates(-0.905874102, -4.659467970, -3.227347517);
v6 = ECICoordinates(-6.112325142, 1.527008184, -0.139152358);
v7 = ECICoordinates(4.767927483, 5.123185301, 4.276837355);
v8 = ECICoordinates(3.067165127, -4.828384068, -2.515322836);
v9 = ECICoordinates(-4.999442110, -1.800561422, -2.229392830);
v1o = ECICoordinates(-2.180993947, 6.402085603, 3.644723952);
v11 = ECICoordinates(6.668817493, -2.516382327, -0.082384354);
v12 = ECICoordinates(-2.232832783, -4.110453490, -3.157345433);
}
};
TEST_F(SGP4OrbitTest, testSGP4Propagation)
{
double error = std::pow(10, -9);
SGP4OrbitTrajectory* random_orbit = new SGP4OrbitTrajectory(*random_tle, "random");
random_orbit->Initialize();
for (int i = 0; i <= 13; i++) {
current_state[i] = random_orbit-> propagateOrbit(time[i]);
current_position[i] = std::get<0>(current_state[i]);
current_velocity[i] = std::get<1>(current_state[i]);
}
//TODO: compare y and z components.
ASSERT_NEAR(current_position[0].x, p.x, error);
ASSERT_NEAR(current_velocity[0].x, v.x, error);
ASSERT_NEAR(current_position[1].x, p1.x, error);
ASSERT_NEAR(current_velocity[1].x, v1.x, error);
ASSERT_NEAR(current_position[2].x, p2.x, error);
ASSERT_NEAR(current_velocity[2].x, v2.x, error);
ASSERT_NEAR(current_position[3].x, p3.x, error);
ASSERT_NEAR(current_velocity[3].x, v3.x, error);
ASSERT_NEAR(current_position[4].x, p4.x, error);
ASSERT_NEAR(current_velocity[4].x, v4.x, error);
ASSERT_NEAR(current_position[5].x, p5.x, error);
ASSERT_NEAR(current_velocity[5].x, v5.x, error);
ASSERT_NEAR(current_position[6].x, p6.x, error);
ASSERT_NEAR(current_velocity[6].x, v6.x, error);
ASSERT_NEAR(current_position[7].x, p7.x, error);
ASSERT_NEAR(current_velocity[7].x, v7.x, error);
ASSERT_NEAR(current_position[8].x, p8.x, error);
ASSERT_NEAR(current_velocity[8].x, v8.x, error);
ASSERT_NEAR(current_position[9].x, p9.x, error);
ASSERT_NEAR(current_velocity[9].x, v9.x, error);
ASSERT_NEAR(current_position[10].x, p1o.x, error);
ASSERT_NEAR(current_velocity[10].x, v1o.x, error);
ASSERT_NEAR(current_position[11].x, p11.x, error);
ASSERT_NEAR(current_velocity[11].x, v11.x, error);
ASSERT_NEAR(current_position[12].y, p12.y, error);
ASSERT_NEAR(current_velocity[12].y, v12.y, error);
}
}
#endif /* __TEST_SGP4_ORBIT_HPP__ */
And the cmake code to find the julia library is
# -- Julia library:
find_package(Julia REQUIRED)
include_directories(SYSTEM ${Julia_INCLUDE_DIRS})
include_directories(${JULIA_HEADER_DIR} ${JULIA_HEADER_DIR}/support ${JULIA_PATH}/usr/include )
# set the path to the library folder
link_directories(${JULIA_LIB_DIR})
# link the libraries to the executable
link_libraries (julia)
add_definitions(-DJULIA_INIT_DIR="${JULIA_LIB_DIR}")
add_definitions(-DJULIA_LOG_ENABLE)
add_definitions(-DJULIA_INIT_DIR="${JULIA_LIB_DIR}")
If anyone could help me I would appreciate it so much… I’ve been stuck a long time with that error and I have exhausted my ideas… If I have to provide more info or provide the complete files, I won’t have any inconveniences.
Many thanks in advance.