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
Add RPM field to blackbox logs #12562
Conversation
This comment has been minimized.
This comment has been minimized.
AUTOMERGE: (FAIL)
|
We now have 8 debug channels to show |
The problem of adding fields if that the blackbox must keep the speed while writing all of them, if not, other data is lost or it can affect the pid loop time. I think is good to add "general" data as fields and not let all the work to the debug field, so the PR is ok to me. Maybe we must decide wich fields are the most important/habitual and let disabled by default, using the mask, all the others. Adding the mask to the configurator will help the users to decide what enable/disable according his preferences. |
@McGiverGim we already using the mask in configurator: betaflight/betaflight-configurator#3363 |
It didn't appear with the virtual fc, I searched for it 😋 Then it's ok, maybe decide what let as defaults. |
I know, but then you can't have any other debug mode active. This field also support up to 8 motors (it should, haven't tested yet due to a lack of octo copter) but unlike the 8 debug channel version it only logs the motors that the multi rotor has, whereas the debug field will waste time and memory on writing zeros to the remaining fields. Unfiltered gyros should probably also be given a real field. There we are currently wasting even more resources on zero data (and every tuning guide in existence won't have to describe how to set the black box debug mode to gyro scaled).
I'm very aware of the possible performance problem. As I mentioned above, the field should be more efficient than using the debug field, and as you said, worst case it can just be disabled by default. The field can already be toggled from the CLI by the same mechanism as other BB fields. |
@tbolin if it's contained in the mask we just have to add another value in the configurator. DId you check the link above?
|
@@ -71,6 +82,7 @@ typedef enum FlightLogFieldSelect_e { // no more than 32 | |||
FLIGHT_LOG_FIELD_SELECT_ACC, | |||
FLIGHT_LOG_FIELD_SELECT_DEBUG_LOG, | |||
FLIGHT_LOG_FIELD_SELECT_MOTOR, | |||
FLIGHT_LOG_FIELD_SELECT_RPM, |
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 should go after GPS
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.
Should be in the correct position now
I did now, and I was aware of that menu. I'll move the RPM enum and try it with the configurator PR soon(ish). I was worried there were some arcane configuration step that I was not aware of but I guess I don't have to worry about that now since I'm technically not adding any variables. |
We already get many users with gaps in their logs, and also heavy logging messes with CPU stability. |
We need to evaluate which blackbox log fields to keep/drop/add anyway. We can probably also add gyro pre-filtered, just like @tbolin recommended, and even drop some legacy blackbox fields. Disabling some bb fields by default is also a good addition, I agree. |
I agree that some fields might have to be off by default, but I think there are better candidates than RPM. Also, the PR for Blackbox Explorer is up now betaflight/blackbox-log-viewer#633 |
This comment has been minimized.
This comment has been minimized.
src/main/blackbox/blackbox.c
Outdated
@@ -1097,6 +1142,12 @@ static void loadMainState(timeUs_t currentTimeUs) | |||
blackboxCurrent->motor[i] = lrintf(motor[i]); | |||
} | |||
|
|||
#ifdef USE_DSHOT_TELEMETRY | |||
for (int i = 0; i < motorCount; i++) { | |||
blackboxCurrent->rpm[i] = getDshotTelemetry(i); |
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.
Just now saw that this logged eRPM and not actual RPM
blackboxCurrent->rpm[i] = getDshotTelemetry(i); | |
blackboxCurrent->rpm[i] = erpmToRpm(getDshotTelemetry(i)); |
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.
Just now saw that this logged eRPM and not actual RPM
That's intentional (for now at least). Logging eRPM saves a little bit of calculation on the FC and might avoid some loss of precision. The eRPM to RPM calculation is done in Black box explorer.
tl;dr for the stream of thought bellow: the exact value to be logged is still TBD.
I still haven't decided on exactly which value that should be logged. The getDshotTelemetry function raises a few alarm bells when I look at it, especially when extended dhsot telemetry might come into play. There are too much calculations and too many side effects there for my liking right now, and I'm not sure that it won't interfere with the RPM based gyro filters.
It could also be a good idea to filter the RPM signal before logging to help the compression, but then it might as well log the value used by the RPM filters. I'll have to look at how much information there is left on higher frequencies. In the very short log I have now there is just noise.
I ran a stress test with a F411 logging at 3205 Hz with all fields enabled. Log and details in updated OP. |
The encoding looks like it should fit the purpose. If there turns out to be a more efficient encoding its easy to change later. |
I had a look at Not directly related to the PR but the current pattern where the dhsot telemetry is triggered by the getShotTelemetry function should probably be changed and the function divided into a calculation and a get. Especially with extended telemetry on the way. |
I think it's most user friendly to log RPM directly from the filtered RPM values that are also used by the RPM Filter. If we need eRPM or something else, we still have the debug channels. The current
That might indeed be a bit worrysome. Should still be working fine if there are some corrupted eRPM samples here and there but we should still try to avoid it, of course. Which line are you talking about specifically? |
Storing the filtered values would be hard since they have been converted to float. The black box encodings relies quite heavily on the values being integers. Grabbing values from Pure RPM would have the same problems as the current eRPM/100 values, just less loss of precision at low RPM but more problems with compression rate at high RPM, and right now I'm more concerned with compression than the loss of precision. I agree that pure RPM would be a bit more friendly to those that like to read raw black box values, but I don't think that is the typical user. Since both the black box data and data rate are constrained, and it's easy to process the interval data into RPM before displaying it, I think it's better to go with the most machine friendly option here. I'm almost done with a version using the interval, so you might want to hold of on the refactoring for a moment. |
This comment has been minimized.
This comment has been minimized.
Update using intervals instead of RPM pushed together with corresponding black box explorer commit. A bit more work than I thought it would be, but the compression should be slightly more efficient now, and it's possible to see very low RPMs. |
This comment has been minimized.
This comment has been minimized.
Pushed an update with a bunch of fixes and added some logs from testing to the first post. |
src/main/blackbox/blackbox.c
Outdated
blackboxWriteMainStateArrayUsingAveragePredictor(offsetof(blackboxMainState_t, rpm), getMotorCount()); | ||
const int motorCount = getMotorCount(); | ||
for (int x = 0; x < motorCount; x++) { | ||
if(testBlackboxCondition(CONDITION(MOTOR_1_HAS_RPM) + x)) { |
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(testBlackboxCondition(CONDITION(MOTOR_1_HAS_RPM) + x)) { | |
if (testBlackboxCondition(CONDITION(MOTOR_1_HAS_RPM) + x)) { |
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.
fixed
This comment has been minimized.
This comment has been minimized.
I'm feeling quite happy with the firmware code now, and the black box explorer works as well. |
This comment has been minimized.
This comment has been minimized.
You might want to rename all instances of "RPM" with "eInterval" where you really mean "eInterval". Also the title of this PR doesn't fit the content anymore. |
I think that we need to look hard at how we can optimise the DShot telemetry code, so that we operate with either RPM or eRPM, but not both, to avoid swapping from one to the other many times. |
I realized I should do some testing and calculations before deciding which value to log. I recorded 4 logs, 2 with Bluejay and 2 with BLHeli 32. For each ESC firmware I made one log at 1602 Hz and one at 3205 Hz.
Notes
Based on this data I have a hard time motivating the switch from eRPM to eIntervals. The improvement is extremely minor. From some estimates I've done there shouldn't be a significant loss of precision either (IIRC the worst error in an entire log was equivalent to 0.3 Hz, the average was much lower). As for the name of the field: the intention I have with the PR was that a user should be able to choose to log how fast the motors are spinning in Configurator and then have a field with that value appear in blackbox explorer. I have two suggestions for how to proceeds with this PR:
go back to eRPM
I'm leaning towards going back to eRPM. |
recommend setting PR as "draft" until truly ready. same for config/bbe pr's |
@KarateBrot I could really use some input on this. This PR has been in limbo for long enough and I don't want to code up more changes before I've got a go ahead in some direction. If the field in the black box log includes the unit, like |
- move dshot decoding calculations to sepparate function from getDshotTelemetry avoids having to call getDshotTelemetry before retreiving non-eRPM values - save dshot interval in us rather than eRPM*100 to avoid (unlikely) overflow - add getDshotTelemetryIntervalUs function - rename getDshotTelemetry to getDshotTelemetryERpm to avoid confusion with getDshotTelemetryPeriodUs - log period in us instead of eRPM in RPM black box field to increase resolution and make compression more efficient
- change eInterval I frame encoding to UNSIGNED_VB (was SIGNED_VB) - change eInterval P fram prediction to PREVIOUS (was AVERAGE_2) - if getDshotTelemetryIntervalUs is zero, UINT16_MAX will be written to the log - add check for zero value in usIntervalToERpm, in will now give zero rpm out - ensure that eInterval values are only writen to P frames if all conditions for RPM logging are fullfiled
Do you want to test this code? Here you have an automated build: |
That was apparently a lie. I have made an alternative PR which uses eRPM #12823 |
Closing this PR since I prefer #12823 |
Adds a separate field for motor RPM from dshot telemetry.
Will only log the existing motors and only if bidirectional dshot is activated, and leaves the debug field free to use for other things.
Can also be disabled just like other black box fields.
Work in progress.
The code is working but there might still be some quirks with both how the rpm values are retrieved and the black box logging itself.
Corresponding PRs
Blackbox Explorer: betaflight/blackbox-log-viewer#633
Configurator: betaflight/betaflight-configurator#3392
Some of the extended Dshot telemetry features from #12170 should probably be included at some point, but not sure if it will be in this PR.
Data
rpm_bb_stress.zip
Log from a F411 with all standard BB fields and 8 debug fields enabled running at 3205 Hz. No dropped frames until the flash ran out of space.
blackbox_rpm_new_format_009_stalled_fixed.zip
blackbox_rpm_new_format_010_almost_stalled.zip
blackbox_rpm_new_format_011_almost_stalled_rpm_telemetry_debug.zip
blackbox_rpm_new_format_012_no_telemetry.zip
blackbox_rpm_new_format_013_rpm_filter_debug.zip
Todo
FlightLogFieldSelect_e
enumerator