-
Notifications
You must be signed in to change notification settings - Fork 48
Hardware Configuration Manager #369
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
base: main
Are you sure you want to change the base?
Conversation
|
As a bit of an explanation: Several "devices" are defined, such as the serial connection, airspeed sensor, etc. For each device, there is a choice of several configurations. For example serial connection (device 0) can be over VCP (configuration 0), or UART (configurations 1-3). The airspeed sensor (device 1, I think) can be disabled(configuration 0), or connected to the Flexi port (configuration 1). Configuration settings are saved at the same time as parameters. Currently this is the /param_write service, but I plan on changing the name to reflect that it saves configurations as well. All devices default to configuration 0, which are/will be defined to "safe" settings. Configurations are currently only applied at boot. Currently, there are no checks for invalid configurations (such as GNSS and Airspeed both on the Flexi Port), but those could be added at the board level. There are currently no checks when a configuration is chosen that such a configuration even exists. In rosflight_io, I have left some room for adding verbose error messages. |
superjax
left a comment
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.
This is awesome man! Thanks for all the hard work
This was a monster PR. I think that this could have been split up into at least 3 changes that would have been a lot easier to review.
Biggest thing is actually const correct-ness. A couple of other minor architectural changes from me.
Thanks again!
| static constexpr uint8_t PARAMS_NAME_LENGTH = 16; | ||
|
|
||
| private: | ||
| union param_value_t |
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.
why did this need to become public?
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.
Did I make this public? Not a big deal, but I tend to make constants public. Especially here, because the parameter names pass through other classes, such as CommLink.
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.
Yeah, but they don't need to see this union; that's an internal implementation thing. I'd revert this to private
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.
OK, I see now that I'm looking at the right page on Github.
I needed to make the params_t struct public, so that the memory manager could hold one. Strangely, param_value_t does not need to be public for that to work, even though it is a member of params_t
scripts/rosflight.mk
Outdated
| nanoprintf.cpp | ||
| nanoprintf.cpp \ | ||
| config_manager.cpp \ | ||
| memory_manager.cpp \ |
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.
formatting
| sonar_outlier_filt_.init(SONAR_MAX_CHANGE_RATE, SONAR_SAMPLE_RATE, 0.0f); | ||
| int_start_us_ = rf_.board_.clock_micros(); | ||
|
|
||
| this->update_battery_monitor_multipliers(); |
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.
Is there some inheritance I missing?
if not, then just update_battery_monitor_multipliers(); should work
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.
I do that sometimes just to be explicit, but it would look more consistent without it.
src/sensors.cpp
Outdated
| break; | ||
| case PARAM_BATTERY_VOLTAGE_MULTIPLIER: | ||
| case PARAM_BATTERY_CURRENT_MULTIPLIER: | ||
| this->update_battery_monitor_multipliers(); |
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.
same as above
dpkoch
left a comment
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.
This is really, really good work; thank you @BillThePlatypus. Some suggestions of course, but this is great!
| bool success = true; | ||
| for(device_t device{static_cast<device_t>(0)}; device < Configuration::DEVICE_COUNT; ++device) | ||
| success = success &&RF_.board_.enable_device(device, config_.config[device], RF_.params_); | ||
| return success; |
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.
It looks like we have an opportunity here to catch configuration errors and not allow the flight controller to arm if they exist. This could probably happen in a future pull request, as it would take some thinking and refactoring. But we could have the configuration manager report error and error resolutions to the state manager to control arming, like what we do with RC, etc.
src/config_manager.cpp
Outdated
| uint32_t ConfigManager::generate_checksum() | ||
| { | ||
| //8 bit fletcher algorithm, because we can't assume that the struct is a multiple of 16 bits | ||
| const uint8_t *config_data = reinterpret_cast<const uint8_t*>(config_.config); | ||
| uint8_t check_a{0}; | ||
| uint8_t check_b{0}; | ||
| for(size_t index{0}; index< sizeof(config_.config); index++ ) | ||
| { | ||
| check_a += config_data[index]; | ||
| check_b += check_a; | ||
| } | ||
| return check_a & (check_b<<8) & (~check_a<<16) & (~check_b<<24); | ||
| } |
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.
I think this is not a true Fletcher checksum, because it's missing the modulo 255 step on check_a and check_b. You'll also want to make sure that check_a and check_b don't overflow if you're doing an actual Fletcher checksum, which means they should probably be uint16_t, and there should either be a period application of the modulo or a static_assert that sizeof(config_.config) isn't big enough to cause an overflow.
Fixing this up could probably be left to a separate PR request though, because we should probably transition the parameters and backup memory to use a Fletcher checksum as well, which should all share a common implementation.
dpkoch
left a comment
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.
Nice documentation! Just a typo or two
| @@ -0,0 +1,104 @@ | |||
| # Firmware Configuration | |||
|
|
|||
| The most recent versions of ROSflight allow you to specify the hardware setup of your aircraft in greater detail. These settings are dependant on your choice of flight controller. ROSflight does not support this feature on the Naze/Flip32. | |||
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.
"dependant" -> "dependent"
|
I've implemented requested changes, except for changes to the battery monitor, and changes that weren't practical, to which I responded. |
|
What is the status of this PR? |
4bbf59b to
e6a9d58
Compare
e6a9d58 to
7fb1809
Compare
# Conflicts: # .astylerc # boards/airbourne/airbourne_board.cpp # boards/breezy/breezy_board.cpp # comms/mavlink/mavlink.cpp # comms/mavlink/mavlink.h # include/board.h # include/comm_manager.h # include/command_manager.h # include/controller.h # include/estimator.h # include/interface/comm_link.h # include/mixer.h # include/param.h # include/rc.h # include/rosflight.h # include/util.h # src/comm_manager.cpp # src/command_manager.cpp # src/controller.cpp # src/mixer.cpp # src/param.cpp # src/sensors.cpp # test/command_manager_test.cpp # test/estimator_test.cpp # test/test_board.cpp # test/test_board.h # test/turbotrig_test.cpp
| ConfigManager::ConfigResponse resp; | ||
| resp.reboot_required = false; | ||
| resp.successful = false; | ||
| resp.message[0] = 0; // Just in case, because a string without a null terminator causes problems |
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.
could we move this into the constructor of ConfigManager::ConfigResponse so that it's impossible to forget this?
| } | ||
| resp.successful = true; | ||
| resp.reboot_required = true; | ||
| resp.message[0]=0; // Ensuring that the message is treated as a zero-length string |
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.
if we moved this to the constructor, then we won't need these lines.
| The state manager also includes functionality for recovering from hard faults. In the case of a hard fault, the firmware writes a small amount of data to backup memory then reboots. This backup memory location is checked and then cleared after every reboot. The backup memory includes the armed state of the flight controller. On reboot, the firmware will initialize then, if this armed-state flag is set, immediately transition back into the armed state. This functionality allows for continued RC control in the case of a hard fault. Hard faults are not expected with the stable firmware code base, but this feature adds an additional layer of safety if experimental changes are being made to the firmware itself. | ||
|
|
||
| ### Config Manager | ||
| This module handles the configurations for various devices, such as sensors and the serial connection. Each configuration is stored as an integer. Configurations can be set from the companion computer over the serial connection. On startup, the config manager sends configurations to the board support layer to initialize devices. |
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.
I don't know that the fact that configuration being stored as an integer important to a user.
|
Hey @BillThePlatypus, I think I'm struggling to follow the Github review process. Could you please "Resolve Conversation" if you're responded to our feedback? If all the conversations are resolved, then I think I'm happy to approve. |
|
This looks like a lot of great work that we should revisit at some point. |
This allows for hardware various hardware settings to be chosen, such as where things are plugged in, or which sensors are enabled.