-
Notifications
You must be signed in to change notification settings - Fork 5
Feature object config with injection and osi #365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
LukasWikander
merged 20 commits into
dev
from
feature_object_config_with_injection_and_OSI
Jun 29, 2021
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
1f4ed71
Added BackToStart module
konglobemeralt 1e64e8a
Revert "Added BackToStart module"
konglobemeralt 3034c77
Added backToStart module without functionality
konglobemeralt 8692536
Update README.md
konglobemeralt 9c68b35
Update main.cpp
konglobemeralt 2d878d1
Merge branch 'dev' into feature_backToStart
LukasWikander 373b210
Indentation and CMakeLists
LukasWikander 27d7019
Update
konglobemeralt 3bec0fe
Merge branch 'feature_objectfile_changes_for_BTS' into feature_backTo…
fridarei 20981b9
Added class for object configurations + read values for turning radiu…
fridarei db87f1c
Added printout for testing of BTS button command
fridarei 09d64ef
Moved objectconfig class to Maestro common and also included other se…
fridarei 5a8fd27
Renamed Turning radius to Turning Diameter
fridarei 926e1ac
Minor change
fridarei 3c6218f
Added draft implementation of support for injection maps and isOSICom…
fridarei 954fde7
Minor improvements
fridarei 8326b92
Update common/CMakeLists.txt
fridarei fc8399d
Update common/objectconfig.cpp
fridarei 3e92180
Update common/objectconfig.cpp
fridarei e59cfb0
Merge branch 'dev' into feature_object_config_with_injection_and_OSI
LukasWikander File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,254 @@ | ||
| #include "objectconfig.hpp" | ||
| #include "util.h" | ||
|
|
||
| ObjectConfig::ObjectConfig() { | ||
| origin.latitude_deg = origin.longitude_deg = origin.altitude_m = 0.0; | ||
| origin.isLongitudeValid = origin.isLatitudeValid = origin.isAltitudeValid = false; | ||
| } | ||
|
|
||
| ObjectConfig::ObjectConfig(const ObjectConfig&& other) : | ||
| objectFile(other.objectFile), | ||
| transmitterID(other.transmitterID), | ||
| injectionMap(other.injectionMap), | ||
| isAnchorObject(other.isAnchorObject), | ||
| isOSICompatible(other.isOSICompatible), | ||
| trajectory(other.trajectory), | ||
| origin(other.origin) | ||
| { | ||
|
|
||
| } | ||
|
|
||
| std::string ObjectConfig::toString() const { | ||
| char ipAddr[INET_ADDRSTRLEN]; | ||
| inet_ntop(AF_INET, &ip_addr, ipAddr, sizeof (ipAddr)); | ||
| std::string retval = ""; | ||
|
|
||
| std::string idsString; | ||
| for(auto id: injectionMap.targetIDs) { | ||
| idsString += std::to_string(id) + " "; | ||
| } | ||
|
|
||
| retval += "Object ID: " + std::to_string(transmitterID) | ||
| + ", IP: " + ipAddr + ", Trajectory: " + trajectory.name.c_str() | ||
| + ", Turning diameter: " + std::to_string(turningDiameter) + ", Max speed: " + std::to_string(maximumSpeed) | ||
| + ", Object file: " + objectFile.filename().string() + ", Anchor: " + (isAnchorObject? "Yes":"No") | ||
| + ", OSI compatible: " + (isOSICompatible? "Yes":"No") | ||
| + ", Injection IDs: " + idsString; | ||
| return retval; | ||
| } | ||
|
|
||
| void ObjectConfig::parseConfigurationFile( | ||
| const fs::path &objectFile) { | ||
|
|
||
| char setting[100]; | ||
| int result; | ||
| char path[MAX_FILE_PATH]; | ||
|
|
||
| UtilGetTrajDirectoryPath(path, sizeof (path)); | ||
|
|
||
| // Get IP setting | ||
| if (UtilGetObjectFileSetting(OBJECT_SETTING_IP, objectFile.c_str(), | ||
| objectFile.string().length()+1, setting, | ||
| sizeof (setting)) == -1) { | ||
| throw std::invalid_argument("Cannot find IP setting in file " + objectFile.string()); | ||
| } | ||
| result = inet_pton(AF_INET, setting, &this->ip_addr); | ||
| if (result == -1) { | ||
| using namespace std; | ||
| throw system_error(make_error_code(static_cast<errc>(errno))); | ||
| } | ||
| else if (result == 0) { | ||
| throw std::invalid_argument("Address " + std::string(setting) | ||
| + " in object file " + objectFile.string() | ||
| + " is not a valid IPv4 address"); | ||
| } | ||
|
|
||
| // Get ID setting | ||
| if (UtilGetObjectFileSetting(OBJECT_SETTING_ID, objectFile.c_str(), | ||
| objectFile.string().length(), | ||
| setting, sizeof (setting)) == -1) { | ||
| throw std::invalid_argument("Cannot find ID setting in file " + objectFile.string()); | ||
| } | ||
| char *endptr; | ||
| uint32_t id = static_cast<uint32_t>(strtoul(setting, &endptr, 10)); | ||
|
|
||
| if (endptr == setting) { | ||
| throw std::invalid_argument("ID " + std::string(setting) + " in file " | ||
| + objectFile.string() + " is invalid"); | ||
| } | ||
| this->transmitterID = id; | ||
|
|
||
| // Get anchor setting | ||
| if (UtilGetObjectFileSetting(OBJECT_SETTING_IS_ANCHOR, objectFile.c_str(), | ||
| objectFile.string().length(), | ||
| setting, sizeof (setting)) == -1) { | ||
| this->isAnchorObject = false; | ||
| } | ||
| else { | ||
| this->isAnchorObject = this->isSettingTrue(setting); | ||
| } | ||
|
|
||
| // Get trajectory file setting | ||
| if (UtilGetObjectFileSetting(OBJECT_SETTING_TRAJ, objectFile.c_str(), | ||
| objectFile.string().length(), | ||
| setting, sizeof (setting)) == -1) { | ||
| throw std::invalid_argument("Cannot find trajectory setting in file " + objectFile.string()); | ||
| } | ||
|
|
||
| fs::path trajFile(std::string(path) + std::string(setting)); | ||
| if (!fs::exists(trajFile)) { | ||
| throw std::invalid_argument("Configured trajectory file " + std::string(setting) | ||
| + " in file " + objectFile.string() + " not found"); | ||
| } | ||
| this->trajectory.initializeFromFile(setting); | ||
| LogMessage(LOG_LEVEL_DEBUG, "Loaded trajectory with %u points", trajectory.points.size()); | ||
|
|
||
| // Get origin settings | ||
| this->origin = {}; | ||
| if (UtilGetObjectFileSetting(OBJECT_SETTING_ORIGIN_LATITUDE, objectFile.c_str(), | ||
| objectFile.string().length(), | ||
| setting, sizeof (setting)) != -1) { | ||
| origin.latitude_deg = strtod(setting, &endptr); | ||
| if (setting != endptr) { | ||
| origin.isLatitudeValid = true; | ||
| } | ||
| } | ||
|
|
||
| if (UtilGetObjectFileSetting(OBJECT_SETTING_ORIGIN_LONGITUDE, objectFile.c_str(), | ||
| objectFile.string().length(), | ||
| setting, sizeof (setting)) != -1) { | ||
| origin.longitude_deg = strtod(setting, &endptr); | ||
| if (setting != endptr) { | ||
| origin.isLongitudeValid = true; | ||
| } | ||
| } | ||
|
|
||
| if (UtilGetObjectFileSetting(OBJECT_SETTING_ORIGIN_ALTITUDE, objectFile.c_str(), | ||
| objectFile.string().length(), | ||
| setting, sizeof (setting)) != -1) { | ||
| origin.altitude_m = strtod(setting, &endptr); | ||
| if (setting != endptr) { | ||
| origin.isAltitudeValid = true; | ||
| } | ||
| } | ||
|
|
||
| if (origin.isAltitudeValid == origin.isLatitudeValid | ||
| && origin.isLatitudeValid == origin.isLongitudeValid) { | ||
| if (!origin.isAltitudeValid) { | ||
| GeoPosition orig; | ||
| if (UtilReadOriginConfiguration(&orig) != -1) { | ||
| this->origin.latitude_deg = orig.Latitude; | ||
| this->origin.longitude_deg = orig.Longitude; | ||
| this->origin.altitude_m = orig.Altitude; | ||
| this->origin.isLatitudeValid = true; | ||
| this->origin.isLongitudeValid = true; | ||
| this->origin.isAltitudeValid = true; | ||
| } | ||
| else { | ||
| throw std::invalid_argument("No origin setting found"); | ||
| } | ||
| } | ||
| } | ||
| else { | ||
| throw std::invalid_argument("Partial origin setting in file " + objectFile.string()); | ||
| } | ||
|
|
||
| // Get Turning diameter | ||
| if (UtilGetObjectFileSetting(OBJECT_SETTING_TURNING_DIAMETER, objectFile.c_str(), | ||
| objectFile.string().length(), | ||
| setting, sizeof (setting)) == -1) { | ||
| throw std::invalid_argument("Cannot find Turning diameter setting in file " + objectFile.string()); | ||
| } | ||
| else { | ||
| char *endptr; | ||
| double val = strtod(setting, &endptr); | ||
|
|
||
| if (endptr == setting) { | ||
| throw std::invalid_argument("Turning diameter " + std::string(setting) + " in file " | ||
| + objectFile.string() + " is invalid"); | ||
| } | ||
| this->turningDiameter = val; | ||
| } | ||
|
|
||
| // Get Maximum speed | ||
| if (UtilGetObjectFileSetting(OBJECT_SETTING_MAX_SPEED, objectFile.c_str(), | ||
| objectFile.string().length(), | ||
| setting, sizeof (setting)) == -1) { | ||
| throw std::invalid_argument("Cannot find Max speed setting in file " + objectFile.string()); | ||
| } | ||
|
Comment on lines
+174
to
+178
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here |
||
| else { | ||
| char *endptr; | ||
| double val = strtod(setting, &endptr); | ||
|
|
||
| if (endptr == setting) { | ||
| throw std::invalid_argument("Max speed " + std::string(setting) + " in file " | ||
| + objectFile.string() + " is invalid"); | ||
| } | ||
| this->maximumSpeed = val; | ||
| } | ||
|
|
||
| // Get OSI compatibility | ||
| if (UtilGetObjectFileSetting(OBJECT_SETTING_IS_OSI_COMPATIBLE, objectFile.c_str(), | ||
| objectFile.string().length(), | ||
| setting, sizeof (setting)) == -1) { | ||
| this->isOSICompatible = false; | ||
| } | ||
| else { | ||
| this->isOSICompatible = this->isSettingTrue(setting); | ||
| } | ||
|
|
||
| // Get Injector IDs | ||
| if (UtilGetObjectFileSetting(OBJECT_SETTING_INJECTOR_IDS, objectFile.c_str(), | ||
| objectFile.string().length(), | ||
| setting, sizeof (setting)) == -1) { | ||
| throw std::invalid_argument("Cannot find Injector IDs setting in file " + objectFile.string()); | ||
| } | ||
|
Comment on lines
+201
to
+205
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The injection map can be initialized to empty if the setting is not found |
||
|
|
||
| std::vector<int> ids; | ||
| std::string settingString(setting); | ||
| this->split(settingString, ',', ids); | ||
|
|
||
| this->injectionMap.numberOfTargets = ids.size(); | ||
| this->injectionMap.sourceID = id; | ||
| this->injectionMap.isActive = true; | ||
| this->injectionMap.targetIDs.clear(); | ||
|
|
||
| for (const auto& id : ids) { | ||
| LogMessage(LOG_LEVEL_DEBUG, "Injection ID %d", id); | ||
| this->injectionMap.targetIDs.push_back(id); | ||
| } | ||
|
|
||
| this->objectFile = objectFile; | ||
| } | ||
|
|
||
| template<size_t N> | ||
| bool ObjectConfig::isSettingTrue(char (&setting)[N]) { | ||
| if (setting[0] == '1' || setting[0] == '0') { | ||
| return setting[0] == '1'; | ||
| } | ||
| else { | ||
| std::string settingString(setting); | ||
| for (char &c : settingString) { | ||
| c = std::tolower(c, std::locale()); | ||
| } | ||
| if (settingString.compare("true") == 0) { | ||
| return true; | ||
| } | ||
| else if (settingString.compare("false") == 0) { | ||
| return false; | ||
| } | ||
| else { | ||
| throw std::invalid_argument("Setting " + settingString + " is invalid"); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| void ObjectConfig::split(std::string &str, char delim, std::vector<int> &out) { | ||
| size_t start; | ||
| size_t end = 0; | ||
|
|
||
| while ((start = str.find_first_not_of(delim, end)) != std::string::npos) { | ||
| end = str.find(delim, start); | ||
| out.push_back(stoi(str.substr(start, end - start))); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| #pragma once | ||
|
|
||
| #include <netinet/in.h> | ||
| #include "trajectory.hpp" | ||
|
|
||
| // GCC version 8.1 brings non-experimental support for std::filesystem | ||
| #if __GNUC__ > 8 || (__GNUC__ == 8 && __GNUC_MINOR__ >= 1) | ||
| #include <filesystem> | ||
| namespace fs = std::filesystem; | ||
| #else | ||
| #include <experimental/filesystem> | ||
| namespace fs = std::experimental::filesystem; | ||
| #endif | ||
|
|
||
| struct DataInjectionMap { | ||
| uint32_t sourceID; | ||
| unsigned int numberOfTargets; | ||
| std::vector<uint32_t> targetIDs; | ||
| bool isActive; | ||
| }; | ||
|
|
||
| class ObjectConfig { | ||
| public: | ||
| ObjectConfig(); | ||
| ObjectConfig(const ObjectConfig&&); | ||
|
|
||
| void parseConfigurationFile(const fs::path& file); | ||
|
|
||
| bool isAnchor() const { return isAnchorObject; } | ||
| bool isOSI() const { return isOSICompatible; } | ||
| DataInjectionMap getInjectionMap() const { return injectionMap; } | ||
| in_addr_t getIP(void) const { return ip_addr; } | ||
| double getMaximumSpeed() const { return maximumSpeed; } | ||
| GeographicPositionType getOrigin() const { return origin; } | ||
| Trajectory getTrajectory() const { return trajectory; } | ||
| uint32_t getTransmitterID() const { return transmitterID; } | ||
| double getTurningDiameter() const { return turningDiameter; } | ||
|
|
||
| std::string toString() const; | ||
|
|
||
| private: | ||
| fs::path objectFile; | ||
| bool isAnchorObject = false; | ||
| bool isOSICompatible = false; | ||
| in_addr_t ip_addr = 0; | ||
| double maximumSpeed = 0; | ||
| GeographicPositionType origin; | ||
| Trajectory trajectory; | ||
| uint32_t transmitterID = 0; | ||
| double turningDiameter = 0; | ||
| DataInjectionMap injectionMap; | ||
|
|
||
| template<size_t N> | ||
| bool isSettingTrue(char (&setting)[N]); | ||
| void split(std::string &str, char delim, std::vector<int> &out); | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should handle the absence of these parameters in a better way, such as having a variable showing it is unknown or similar, when it is not present in the config file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I agree. Will figure something out.