Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
58c3fed
Initial commit
Mar 31, 2023
84bd801
Working verison, adds attribute and value and then prints the doc upd…
Apr 10, 2023
68dc6c3
Working for all plugins
Apr 10, 2023
21c7b98
Created function to parse the plugin specific xml file. This is worki…
Apr 11, 2023
c95c68a
Code cleanup
Apr 11, 2023
45508c5
Removed mission file change
Apr 11, 2023
75a9aa9
minor error message changes, added extra digit to time UI
Apr 11, 2023
812b327
Merge branch 'william-qol' of https://github.com/gtri/scrimmage into …
Apr 11, 2023
cc27377
Added returns in case of error with finding params files
Apr 11, 2023
afd20a8
Working with scrimmage_plugin_path environment variable
Apr 18, 2023
ad6b58f
Mission.plugin.xml log file added
Apr 18, 2023
a9fb57d
Code cleanup
Apr 18, 2023
2d04f5a
Initial commit of mission to mission xml pull request. Currently, abl…
May 24, 2023
36187fa
Struct is working between mission parse and sim control files. Can re…
May 25, 2023
87f2ed7
Working for updating x, y, and z pos of new entities
May 26, 2023
811875e
Removes original entity blocks
May 26, 2023
2f9d201
Additional checks/removals
May 31, 2023
b2936d3
Added tag to determine if mission 2 mission output file should be cre…
Jun 1, 2023
a5d6fce
Remove block tag working for original entities being added/removed fr…
Jun 5, 2023
4fce2a7
New final entity state file is created to view the final states of ea…
Jun 5, 2023
b8eaacb
Code cleanup
Jun 5, 2023
1e0fa94
Code cleanup
Jun 7, 2023
794e018
Working before trying to put struct with fwd decl file
Jun 7, 2023
7902c32
Struct in header is now working... do not need fwd decl or the new he…
Jun 7, 2023
b119eab
Delete EntEndStates.h
laserjetprinter Jun 7, 2023
7e6d3cb
Cleanup and support for struct in simcontrol header
Jun 7, 2023
d47c78d
Merge branch 'plugintomissionxml' of https://github.com/gtri/scrimmag…
Jun 7, 2023
1b53c6f
Updating header comments
Jun 7, 2023
683ef14
Test commit
Jun 14, 2023
d09062e
Code clean up
Jun 21, 2023
495c54a
Fixing a seg fault case based on mission xml tags
Jun 23, 2023
50e6269
Working on getting the plugin specific xml tag values. Currently am a…
Jun 26, 2023
300567f
Function working to get the xml tag values from the autonomy plugin
Jun 26, 2023
5115e3b
Rapid xml is working, writing plugin specific tags to the motion mode…
Jun 28, 2023
44a8fd7
Fully working for plugin specific xml tags populating the mission to …
Jun 30, 2023
5ae9f77
Fixed so that the plugin xml tags that are from the function overwrit…
Jun 30, 2023
35035ae
Fixed remove block tag logic
Jul 5, 2023
d54a383
Code cleanup and adding briefs
Jul 6, 2023
f5dfa48
Changing var names of miss2miss
Jul 6, 2023
09bde10
Added brief to Mission Parse header
Jul 6, 2023
4271d6a
RST file
Jul 10, 2023
318b405
Forgot to add the mission-to-mission-xml rst file
Jul 10, 2023
050e2d5
Minor updates
Jul 13, 2023
bd6a242
Merge branch 'master' of https://github.com/gtri/scrimmage into plugi…
Jul 25, 2023
ebf9605
Removing files that were used only for demoing
Aug 2, 2023
2ddb14b
Reverting William's changes to see if Docker builds
Aug 2, 2023
c025b7c
Fixed issue where docker was seg faulting for the test_openai.py file
Aug 2, 2023
c0267fa
Adding williams changes back
Aug 9, 2023
064bcd5
Merge branch 'master' of https://github.com/gtri/scrimmage into plugi…
Aug 21, 2023
fd5c886
Fixed the team id check and wording in the tutorial file
Aug 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions docs/source/tutorials/mission-to-mission-xml.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
==================================
Mission to Mission XML Generation
==================================

This tutorial covers the process of capturing the end states of entities in
an XML file, which can be used as starting points for future simulations. The
following must be completed before the mission to mission capabilities can be
utilized:

1. In the mission XML file, the following tag must be included with the value ``true``::

<mission_to_mission>true</mission_to_mission>

2. In the mission XML file's entity block, if the block should be included in the output
mission XML file - meaning future simulations will require the block, the following tag
must be included with the value ``false``. If it is not included, the entity block will be removed
from the output mission XML file. ::

<remove_block>false</remove_block>

3. If plugin specific XML tag attributes (applicable to motion, sensor, autonomy, and controller plugins)
are expected to be updated while the simulation is running, the following function declaration will need to
be added to the plugin's header file::

std::map<std::string,std::string> mission_xml_get() override;

The mission_xml_get function must insert plugin specific xml tags as strings to a map. Depending on the variable
type of the xml tag, extra formatting might be needed - for example: converting a bool to a string results in
"0" or "1," which will need to be converted to "true" or "false."

Here is an example of the mission_xml_get, implemented in the SimpleAircraft.cpp file::

std::map<std::string,std::string> SimpleAircraft::mission_xml_get() {
std::map<std::string,std::string> mission_xml;

mission_xml.insert({"Name","SimpleAircraft"});
mission_xml.insert({"min_velocity",std::to_string(min_velocity_)});
mission_xml.insert({"max_velocity",std::to_string(max_velocity_)});
mission_xml.insert({"max_roll",std::to_string(max_roll_)});
mission_xml.insert({"max_roll_rate",std::to_string(max_roll_rate_)});
mission_xml.insert({"max_pitch",std::to_string(max_pitch_)});
mission_xml.insert({"max_pitch_rate",std::to_string(max_pitch_rate_)});
mission_xml.insert({"speed_target",std::to_string(speedTarget_)});
mission_xml.insert({"radius_slope_per_speed",std::to_string(lengthSlopePerSpeed_)});
mission_xml.insert({"turning_radius",std::to_string(length_)});

return mission_xml;
}

Note that the plugin name must be specified as the first entry in the map, with the key ``Name`` and the
value ``<plugin_name>``. In the map, each xml specific tag attribute name must be the key of the map and
the attribute value must be the value of the map.

There will be 2 output files, which can be found in the simulation's log directory:
``~/.scrimmage/logs/<scrimmage_run_log_directory>``.

1. The ``mission_to_mission.xml`` file captures the final entity states and formats the data to be used as an
input file to future SCRIMMAGE simulations.

2. The ``final_ent_states.txt`` file captures the final state information for each entity. These values can be
used as reference to verify end states and capture values like velocity, which do not have entity specific tags.
The following entity end states are included in the output text file:

* Team_ID
* X_Pos
* Y_Pos
* Z_Pos
* Vel_X
* Vel_Y
* Vel_Z
* Heading
* Pitch
* Roll
* Altitude
* Health
1 change: 1 addition & 0 deletions docs/source/tutorials/tutorials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ swarm behaviors.
utilities.rst
simcontrol.rst
capture-the-flag.rst
mission-to-mission-xml.rst
7 changes: 7 additions & 0 deletions include/scrimmage/autonomy/Autonomy.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ class Autonomy : public EntityPlugin {
StatePtr &desired_state();
void set_desired_state(StatePtr desired_state);

/// @brief Plugin specific xml tags are inserted to a map and returned. The map
/// is used to update the mission to mission xml file, which captures entity end states
/// to be used as starting points in future simulations.
/// @return A map of keys and values of type string, representing plugin specific
/// xml tag attribute names and associated values
virtual std::map<std::string,std::string> mission_xml_get();

ContactMapPtr &get_contacts();
ContactMap &get_contacts_raw();
virtual void set_contacts(ContactMapPtr &contacts);
Expand Down
15 changes: 15 additions & 0 deletions include/scrimmage/entity/Entity.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,21 @@ class Entity : public std::enable_shared_from_this<Entity> {
MotionModelPtr &motion();
std::vector<ControllerPtr> &controllers();

/// @brief Loops through each motion model for the given entity and retrieves a map of plugin
/// specific xml tags
/// @return A map of keys and values of type string, representing plugin specific xml tag
/// attribute names and associated values
std::map<std::string,std::string> set_motion_xml_map();

/// @brief Loops through each sensor, autonomy, or controller plugin for the given entity and
/// retrieves a map of plugin specific xml tags. Each map corresponds to a given plugin and
/// is pushed into a vector.
/// @return A vector of maps of keys and values of type string, representing plugin specific
/// xml tag attribute names and associated values
std::vector<std::map<std::string,std::string>> set_sensor_xml_vect();
std::vector<std::map<std::string,std::string>> set_autonomy_xml_vect();
std::vector<std::map<std::string,std::string>> set_controller_xml_vect();

void set_id(ID &id);
ID &id();

Expand Down
11 changes: 11 additions & 0 deletions include/scrimmage/motion/Controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ class Controller : public EntityPlugin {
desired_state_ = nullptr;
}

/// @brief Plugin specific xml tags are inserted to a map and returned. The map
/// is used to update the mission to mission xml file, which captures entity end states
/// to be used as starting points in future simulations.
/// @return A map of keys and values of type string, representing plugin specific
/// xml tag attribute names and associated values
virtual std::map<std::string,std::string> mission_xml_get() {
std::map<std::string,std::string> mission_xml;
return mission_xml;
};


protected:
StatePtr state_;
StatePtr desired_state_;
Expand Down
8 changes: 8 additions & 0 deletions include/scrimmage/motion/MotionModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ class MotionModel : public EntityPlugin {
std::map<std::string, std::string> &params);

virtual bool step(double time, double dt);

/// @brief Plugin specific xml tags are inserted to a map and returned. The map
/// is used to update the mission to mission xml file, which captures entity end states
/// to be used as starting points in future simulations.
/// @return A map of keys and values of type string, representing plugin specific
/// xml tag attribute names and associated values
virtual std::map<std::string,std::string> mission_xml_get();

virtual bool posthumous(double t);
virtual StatePtr &state();
virtual void set_state(StatePtr &state);
Expand Down
24 changes: 24 additions & 0 deletions include/scrimmage/parse/MissionParse.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
#include <scrimmage/proto/Visual.pb.h>

#include <scrimmage/proto/Color.pb.h>
#include <scrimmage/simcontrol/SimControl.h>
#include <rapidxml/rapidxml.hpp>

#include <list>
#include <vector>
Expand Down Expand Up @@ -84,6 +86,19 @@ class MissionParse {
bool create_log_dir();
void set_overrides(const std::string &overrides);
bool parse(const std::string &filename);

/// @brief Adds all plugin specific xml attributes to the plugin_spec_attrs map
/// @param node_name
/// @param node_value
void get_plugin_params(std::string node_name, std::string node_value);

/// @brief Generate the mission to mission xml file for all final states of entities
/// @param all_end_states
void final_state_xml(std::list<SimControl::ent_end_state> & all_end_states);

/// @brief Track the number of entity blocks in the input Mission XML file
int num_ents = 0;

bool write(const std::string &filename);

double t0();
Expand Down Expand Up @@ -159,9 +174,18 @@ class MissionParse {
bool output_type_required(const std::string& output_type);

protected:
rapidxml::xml_document<> doc;

std::string mission_filename_ = "";
std::string mission_file_content_ = "";

std::string mission_to_mission_file_content = "";
std::stringstream ent_state_file_content;

std::string mission_plugin_file_content = "";
std::string scrimmage_plugin_path = "";
std::map<std::string, std::string> plugin_spec_attrs;

double t0_ = 0;
double tend_ = 50;
double dt_ = 0.00833333;
Expand Down
10 changes: 10 additions & 0 deletions include/scrimmage/sensor/Sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ class Sensor : public EntityPlugin {

virtual bool step() {return true;}

/// @brief Plugin specific xml tags are inserted to a map and returned. The map
/// is used to update the mission to mission xml file, which captures entity end states
/// to be used as starting points in future simulations.
/// @return A map of keys and values of type string, representing plugin specific
/// xml tag attribute names and associated values
virtual std::map<std::string,std::string> mission_xml_get() {
std::map<std::string,std::string> mission_xml;
return mission_xml;
};

virtual scrimmage::MessageBasePtr sensor_msg(double t);

/*! \brief version when T = MessageBase (calls sensor_msg without casting) */
Expand Down
29 changes: 29 additions & 0 deletions include/scrimmage/simcontrol/SimControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,32 @@ class SimControl {

void set_running_in_thread(bool running_in_thread);

/// @brief Contains the final state values of each entity
struct ent_end_state {
int team_id;
double x_pos;
double y_pos;
double z_pos;

double yaw;
double pitch;
double roll;

int health_points;

double vel_x;
double vel_y;
double vel_z;

std::map<std::string,std::string> motion_xml_tags;
std::vector<std::map<std::string,std::string>> autonomy_xml_tags;
std::vector<std::map<std::string,std::string>> controller_xml_tags;
std::vector<std::map<std::string,std::string>> sensor_xml_tags;

} end_state;

std::list<ent_end_state> all_end_states;

protected:
// Key: Entity ID
// Value: Team ID
Expand Down Expand Up @@ -365,6 +391,9 @@ class SimControl {
bool finished_ = false;
bool exit_ = false;

/// @brief Holds the mission_to_mission tag. If true, will create an output XML file of final entity states
bool mission_to_mission = false;

std::mutex finished_mutex_;
std::mutex contacts_mutex_;
std::mutex exit_mutex_;
Expand Down
5 changes: 5 additions & 0 deletions src/autonomy/Autonomy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ void Autonomy::init() {}
void Autonomy::init(std::map<std::string, std::string> &/*params*/) {}
bool Autonomy::need_reset() {return need_reset_;}

std::map<std::string,std::string> Autonomy::mission_xml_get() {
std::map<std::string,std::string> mission_xml;
return mission_xml;
}

StatePtr &Autonomy::desired_state() {return desired_state_;}

void Autonomy::set_desired_state(StatePtr desired_state) {desired_state_ = desired_state;}
Expand Down
50 changes: 48 additions & 2 deletions src/entity/Entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -726,8 +726,54 @@ void Entity::print_plugins(std::ostream &out) const {
out << c->name() << endl;
}
out << "----------- Motion -------------" << endl;
if (motion_model_->name() != "BLANK") {
if (motion_model_ && motion_model_->name() != "BLANK") {
out << motion_model_->name() << endl;
}
}
} // namespace scrimmage

std::map<std::string,std::string> Entity::set_motion_xml_map(){
std::map<std::string,std::string> cur_motion_xml;
if (motion_model_ && motion_model_->name() != "BLANK") {
cur_motion_xml = motion_model_->mission_xml_get();
}

return cur_motion_xml;
}

std::vector<std::map<std::string,std::string>> Entity::set_sensor_xml_vect(){
std::vector<std::map<std::string,std::string>> all_sensor_xml;
std::map<std::string,std::string> cur_sensor_xml;

for (auto &kv : sensors_) {
cur_sensor_xml = kv.second->mission_xml_get();
all_sensor_xml.push_back(cur_sensor_xml);
}

return all_sensor_xml;
}

std::vector<std::map<std::string,std::string>> Entity::set_autonomy_xml_vect(){
std::vector<std::map<std::string,std::string>> all_autonomy_xml;
std::map<std::string,std::string> cur_autonomy_xml;

for (AutonomyPtr a : autonomies_) {
cur_autonomy_xml = a->mission_xml_get();
all_autonomy_xml.push_back(cur_autonomy_xml);
}

return all_autonomy_xml;
}

std::vector<std::map<std::string,std::string>> Entity::set_controller_xml_vect(){
std::vector<std::map<std::string,std::string>> all_controller_xml;
std::map<std::string,std::string> cur_controller_xml;

for (ControllerPtr c : controllers_) {
cur_controller_xml = c->mission_xml_get();
all_controller_xml.push_back(cur_controller_xml);
}

return all_controller_xml;
}

} // namespace scrimmage
14 changes: 13 additions & 1 deletion src/parse/ConfigParse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,19 @@ bool ConfigParse::parse(const std::map<std::string, std::string> &overrides,
buffer << file.rdbuf();
file.close();
std::string content(buffer.str());
doc.parse<0>(&content[0]);
try {
// Note: This parse function can hard fail (seg fault, no exception) on
// badly formatted xml data. Sometimes it'll except, sometimes not.
// doc.parse<0>(mission_file_content_vec.data());
doc.parse<0>(&content[0]);
}
catch (const rapidxml::parse_error& e)
{
std::cout << e.what() << std::endl;
throw std::runtime_error("Error parsing config file " + filename);
// cout << "scrimmage::MissionParse::parse: Exception during rapidxml::xml_document<>.parse<>()." << endl;
return false;
}

rx::xml_node<> *config_node = doc.first_node("params");
if (config_node == 0) {
Expand Down
Loading