Create a new Application
Guide to help you create a new project using OnOrbitROS framework. All the applications follow the same structure, and all connected by the project's launch file. The package package_template can be used as a guide to create a new application from it.
Create the new project
Download the framework following the Installation Guide. It is recommended that the new projects are located under > orbit_ws > src as occur with the examples. After installation you will find a package template, package_template, and inside you will find the configuration, launch, source code, urdf and worlds folders, as well as the prepared CMakeLists file and others needed to use the framework. You can then add the files corresponding to your specific needs.
The packages are created using the following command as recommended in the ROS Documentation, that creates the CMakeLists.txt and package.xml files among other with the deppendencies specified in the command:
catkin_create_pkg package_template roscpp gazebo_ros urdf geometry_msgs std_msgs message_generation
Launch file
There is a default launch file that includes the loading of all functionalities:
- Gazebo simulation parameters.
- Launch of the orbit and orbit publisher package.
- The world file (converting the .xacro to .world) and then loading with then the gazebo_ros launcher.
- Spacecraft / robot URDF loaded to the param server.
- World position of the spacecraft / robot model in the world.
- Loads of the ROS controllers.
When creating a new application, it is recommended to follow the same structure as the presented in the previously made applications to ensure all the functionalities are launched simply from one file.
In the package_template you will find a default.launch file that includes those functionalities to launch the default application, with ''custom'' tags to modify the properties of the simulation, the world and models to load, the controllers, etc.
Modify the world
The Gazebo world of the application is located in the worlds folder of the package and includes the physic properties of the simulation environment and the models of the orbit (by default called orbitReference). It is defined as a .xacro and converted to .world in the launch file. By default, the world is set to work under zero gravity conditions and the LVLH is located at the origin of the Gazebo frame of reference.
Note
If you encounter any errors when launching the world, for example that the default Gazebo world loads instead, create manually the .world file from the .xacro and leave it in the worlds folder by executing the following command:
$ rosrun xacro xacro <path_to_world/world_name>.world.xacro > <path_to_world/world_name>.world
Add a spacecraft
The spacecraft and robots are loaded URDFs converted from XACROS. This is the protocol Gazebo has to load the different models in the simulation where you can define the different links, joints, controllers... of the model. You can find many guides on how to defined them, as these URDF tutorials.
After creating your desired models, you must add the Gazebo OORplugin at a plugin at the end of the model as follows:
<gazebo>
<plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
<robotNamespace>/</robotNamespace>
</plugin>
<plugin name="Orbit_robot_pkg_plugin" filename="libOrbit_robot_pkg_plugin.so"/>
</gazebo>
That plugin is defined under > orbit_ws > src > orbit_robot_pkg > src > Orbit_robot_pkg_plugin.cpp, and uses the header OrbitLink.h from OrbitLink.cpp. These two latter files are used to define the properties of each link of the spacecraft, both cinematically and dynamically (such as positions, torques, velocities, etc), and to apply the gravity gradient and forces generated by the relative motion to an elliptical . Then, those methods are used by the principal file, Orbit_robot_pkg_plugin.cpp, that manages the subscription to the orbital topics and manages the application of the different perturbations. The script includes comments that can be checked to better understand the implementation.
Note
Place the base link of your model at the origin (0,0,0). If you would like to give an offset to the model from the LVLH, change the origin of your model in the .launch file, NOT in the .xacro file.
<arg name="world_pose" value="-x 0 -y 0 -z 1" />
Also, keep in mind that, if you set the LVLH link with visual elements (by default) and your model collides with it, the physical properties of said link will make your model to drift away. To solve it you can either set the offset as mentioned, or remove the visual properties of said link to: <link name="referenceSpaceCraft"/>.
Add the atmospheric drag sensor
Warning
Currently under development, this perturbation is not included in the current version of OnOrbitROS. Sorry for the inconvenience.
The spacecraft and robot's URDF file also defines the sensor used to simulate the atmospheric drag. The file must include the laser_scan.xacro to define the matrix of rays that simulate the air drag the spacecrafts suffer. Multiple sensors can be added and their size and position must be modified so they cover all the models of the simulations, going opposite to the direction of the motion (to calculate the atmospheric drag as it is explained in Atmospheric Drag). As it is defined as link of the robot's model, it is possible to have a sensor for each of the possible models the simulation can hold.
Another link is created to host the atmospheric drag sensor, which is a floating child of the base link so the sensor matrix can have the orientation of the LVLH (opposite direction of the y axis) and keep an offset distance from the base link of the robot model (calculated from the laser plugin). That sensor can be configured to match with the specific applications, as the matrix should exceed the dimension of the model to ensure all parts are being influenced by the drag. You will find the tag <!-- custom --> in the places that are specific of each application to modify them.
<xacro:include filename="$(find orbit_robot_pkg)/urdf/laser_scan.xacro"/> <!-- Xacro for the laser sensor -->
<!--- SENSOR --->
<link name="drag_sensor_link"/>
<joint name="drag_sensor_joint" type="floating">
<parent link="base_link"/>
<child link="drag_sensor_link"/>
<origin xyz="0 2 1"/>
</joint-->
<!--- Load Sensors -->
<!--
Pose offset in relation to "drag_sensor_link";
Configuration of the ray: lenght, number of rays, angles of the cone;
Configuration of the matrix of rays: x and z number and separation;
Offset of the sensor from the base of the model (it should match with the y components of the joint and pose)
Name of the model to publish the data from the sensor (it should match the name set in the .world file)
--> <!-- custom -->
<xacro:multi_laser_scan
x="-0.0"
y="2"
z="1.0"
roll="0"
pitch="0"
yaw="-1.5708"
visualize="true"
samples="1"
min_angle="-0.0"
max_angle="0.0"
length_ray="6"
num_lasers_x="20"
num_lasers_z="20"
offset_x="0.25"
offset_z="0.25"
offset_model_sensor="2.0"
model_name="robot"
reference_link="drag_sensor_link"/>
That laser scan xacro generates num_lasers_x * num_lasers_z rays in the pose x,y,z from the reference link, with an offset among the rays of offset_x and offset_z. samples indicates the amount of rays for each sensor (forming a cone of rays), and length_ray the distance length of the ray in meters. Each sensor is fixed to a link jointed to the reference_link (by default ''drag_sensor_link'') and model_name is the name of the URDF model of the spacecraft where the sensor information will be published (which must be coincident with the spacecraft model set in the world file). The offset_model_sensor sets the distance between the base link of the model and the origin of the sensor matrix, that should be adapted according to the size of the model (eg. if the model is large the sensor should be farther away).
Define an orbit
The orbit is declared in a .yaml file located in orbit_ws > orbit_publisher_pkg > config (by default the file is dynamic_orbit.yaml), and defines the LVLH information in reference to the ECI. Then that file has to be loaded from the application's launch file, for example orbit_ws > ets_vii > launch > effort_controllers_wgg.launch for the ETS VII application, that calls another specific launch which by default is basic.launch or fix_basic.launch for fixed orbits, and located under orbit_ws > orbit_publisher_pkg > launch.
In the declaration from the launch of the project you can define the .yaml to be used and whether it is called through a dynamic (upper example), or a fixed (lower example) launch. In case the orbit is not fixed, you can also specify whether the orbital parameters calculated from the State Vector are published during the simulation or not in the argument publish_orbit_parameters (values such as Inclination, Eccentricity, RAAN, etc).
<!-- Launch orbit and orbit plublisher package -->
<arg name="publish" default="true" /> <!-- custom -->
<include file="$(find orbit_publisher_pkg)/launch/basic.launch"> <!-- custom -->
<arg name="orbit_file_name" value="dynamic_orbit.yaml" /> <!-- custom -->
<arg name="publish_orbit_parameters" value="$(arg publish)" />
</include>
OR
<include file="$(find orbit_publisher_pkg)/launch/basic_fix.launch"> <!-- custom -->
<arg name="orbit_file_name" value="fixed_orbit.yaml" /> <!-- custom -->
</include>
The information from the orbit .yaml file is read by orbit_ws > orbit_publisher_pkg > src > Orbit.cpp (that uses Orbit.h header that has all the variables and methods defined). The relevant orbit information is then published in their corresponding topics from the file orbit_ws > orbit_publisher_pkg > src > orbit_publisher_pkg_node.cpp (for fixed orbits the information is published from fix_orbit_publisher_pkg_node.cpp). In case more orbital information wants to be shared with the plugin it will be published from this script.
Default Orbit Information
Orbit information declared in the
.yamlfile in the Simple Orbit default module. The value's units are km and ยบ accordingly as presented in Two-Line Element (TLE) set.
publish rate
eccentricity
semi major axis
inclination
rate of right ascension
initial right ascension
rate of argument of perigee
initial argument of perigee
initial mean anomaly
time pass perigee
time start
angular velocity
atmosphere angular velocity
drag coefficient
Published Orbit Information
Information of the orbit is being published in the following topics. By default, the air density is calculated following the US Standard Atmosphere 1976 (USSA76) standard on each iteration from the altitude value (also calculated on each iteration from the other orbital parameters).
/OrbitPosition
/OrbitVelocity
/AtmosphereAngularVelocity
/OrbitAirDensity
/OrbitDragCoeffient
/OrbitAltitude
Note
The air density is calculated automatically with the USSA76 density profile from sea level to an altitude of 1000km. For orbits above that a different method should be taken into account, although atmospheric drag at that altitude could be disregarded.
Other information regarding the orbital parameters is calculated during the simulation from the State Vector (position and velocity). This data can be published or not by specifying it when calling the launch file, under publish_orbit_parameters.
/OrbitArgumentOfPerigee
/OrbitEccentricity
/OrbitInclination
/OrbitPeriod
/OrbitRAAN
/OrbitSemiMajorAxis
/OrbitTrueAnomaly
Add more Orbit Information
In case more orbital information is needed, it can be declared in the
.yamlfile, defined inOrbit.h, read byOrbit.cppand (if needed), published fromorbit_publisher_pkg_node.cpp.
There are two different options when publishing the information: continously or just the first x seconds. Usually all the information is always being updated but sometimes this is not necessary or needs to be updated from another script instead, therefore also exsist the single publish option. This is configured from the orbit_publisher_pkg_node.cpp file.
Safe Information
To save the simulation information in a file rosbags can be used to store the messages published in the selected topics. To use it, add the following command in the project's launch file, specifying the folder to allocate the .bag files (by default inside the project's folder, under log).
<node pkg="rosbag" type="record" name="rosbag_record" args="record -o $(find <your_package_name>/log/data /<your_topics>"/>
Warning
If the folder you have specified in the command does not exist, the rosbag will not be saved.
For example, this is how it is done in the template_project > launch > default.launch to store all the topics:
<node pkg="rosbag" type="record" name="rosbag_record" args="record -o $(find package_template)/log/data /OrbitPosition /OrbitVelocity /OrbitAltitude /ModelPosition /ModelPositionLVLH /OrbitEccentricity /OrbitSemiMajorAxis /OrbitInclination /OrbitRAAN /OrbitArgumentOfPerigee /OrbitTrueAnomaly /OrbitPeriod"/>
Later on, those files can be opened using PlotJuggler for example.