-
Notifications
You must be signed in to change notification settings - Fork 47
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
Hardware Configuration Manager #369
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. |
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!
include/param.h
Outdated
@@ -225,8 +232,6 @@ class Params | |||
|
|||
public: | |||
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
src/sensors.cpp
Outdated
@@ -78,6 +79,8 @@ void Sensors::init() | |||
diff_outlier_filt_.init(DIFF_MAX_CHANGE_RATE, DIFF_SAMPLE_RATE, 0.0f); | |||
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
@@ -106,6 +109,10 @@ void Sensors::param_change_callback(uint16_t param_id) | |||
case PARAM_FC_YAW: | |||
init_imu(); | |||
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
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!
src/config_manager.cpp
Outdated
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.
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.
@@ -86,12 +86,21 @@ The operation of the state manager is defined by the following finite state mach | |||
|
|||
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.