Skip to content
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

AP_Scripting: added external AHRS scripting backend #25678

Open
wants to merge 16 commits into
base: master
Choose a base branch
from

Conversation

tridge
Copy link
Contributor

@tridge tridge commented Dec 2, 2023

This allows lua scripts to provide the following backends:

  • external AHRS (position, velocity, attitude etc)
  • GPS
  • Baro
  • Compass
  • airspeed
  • IMU

It builds on top of #25674 and re-implements the InertialLabs driver as a lua script
also builds on:

@IamPete1
Copy link
Member

Why do we need the drivers for the anything other than external AHRS? Currently the external AHRS lib already populates all the libraries directly with the existing drivers? Why does the scripting driver need to publish via external AHRS and directly to the sensor driver?

@tridge
Copy link
Contributor Author

tridge commented Dec 18, 2023

Currently the external AHRS lib already populates all the libraries directly with the existing drivers?

no, it doesn't, it is the individual backends that do that, not the library itself. It really needs to be this way as the backend knows what makes sense to publish and can have more details that the frontend knows (eg. backend usually knows the GPS details, frontend only knows the estimator solution)

@IamPete1
Copy link
Member

no, it doesn't, it is the individual backends that do that, not the library itself. It really needs to be this way as the backend knows what makes sense to publish and can have more details that the frontend knows (eg. backend usually knows the GPS details, frontend only knows the estimator solution)

Currently this tells external AHRS the accel and gyro and then passes the same information to the INS lib. Why not just pass the information to AHRS and have it pass on to the INS lib rather than doing it in the script? There is not the duplication for the other sensors, but you could include them in the state, or have new function that passes though to the sensor lib.

My concern is more really about the code structure and the data flow. Its useful for all the data to flow the same way between all the different back-ends. It makes testing and debugging easier if there are few "entry points" for the data from the script. I guess the counter argument is that the script itself is a external AHRS back end so it is the same as the others. I think I would tend to make the distinction at the scripting bindings, the script itself is part of the external AHRS unit not part of AP. Some use UART to get the data into AP, the scripting back end used the scripting bindings.

@tridge
Copy link
Contributor Author

tridge commented Dec 18, 2023

Why not just pass the information to AHRS and have it pass on to the INS lib rather than doing it in the script?

this is by design, and is quite important.
When the external AHRS is active we use the external AHRS gyro and accel for the AHRS data products such as the EF accel used for landing detection. This makes it all consistent with the velocity data we are providing.
Meanwhile, the external AHRS can also (optionally!) be presenting its IMU data to AP_InertialSensor. If enabled (using EAHRS_SENSORS) then this makes the IMU data available to other estimators such as EKF3 or DCM. If we only provided it via AHRS then it would not be possible to run EKF3 with the external IMU, and that is one of the more useful cases if you have something like a FOG which has extremely high quality IMUs, but don't fully trust the black box state estimation inside the FOG (with its lack of good logging, no replay etc)
The same applies for baro, gps, mag, airspeed. In each case there is a distinct difference between the external system providing a serial connected sensor and it providing a data product for use by AHRS.

state.velocity = _state.velocity;
}

if (_state.have_origin && !state.have_origin) {
Copy link
Member

@IamPete1 IamPete1 Dec 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This confused me for a few moments, that extra _ is a bit subtle. Maybe new_state rather than _state?

local mag_data_message_t_ud = {}

---@return mag_data_message_t_ud
function mag_data_message_t() end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth a rename on this, its the creation function so you would have to rename the whole object.

Its a little late now, but I wonder it we would have been better to namespace these userdata. Currently you do:

data = mag_data_message_t()

We could name space it so the creation is not global:

data = compass:mag_data_message_t()


-- set field
---@param value Vector3f_ud
function mag_data_message_t_ud:field(value) end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The generator gives you a default description all of the user data fields "set field" or "get field". So I think have a field called "field" is confusing. Maybe the object could be compass_data_message and the filed mag_field.

Comment on lines +415 to +424
---@param value number
function gps_data_message_t_ud:ned_vel_down(value) end

-- set field
---@param value number
function gps_data_message_t_ud:ned_vel_east(value) end

-- set field
---@param value number
function gps_data_message_t_ud:ned_vel_north(value) end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not a vector 3? Or a vector 2 for north/east and a float for down?


-- set field
---@param value integer
function gps_data_message_t_ud:satellites_in_view(value) end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is quite verbose, some of the others are really not. "vdop", "ms_tow".

@@ -95,6 +95,7 @@ singleton AP_BattMonitor method get_cell_voltage boolean uint8_t'skip_check uint
include AP_GPS/AP_GPS.h

singleton AP_GPS depends (AP_GPS_ENABLED && (!defined(HAL_BUILD_AP_PERIPH) || defined(HAL_PERIPH_ENABLE_GPS)))
singleton AP_GPS semaphore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the semaphore at this point mean that all the methods call it. Why not just add it in the cpp for the handle_external function? Like wise for all the others.

include AP_Airspeed/AP_Airspeed.h
singleton AP_Airspeed depends (AP_AIRSPEED_EXTERNAL_ENABLED == 1) && (APM_BUILD_TYPE(APM_BUILD_ArduPlane)||APM_BUILD_COPTER_OR_HELI)
singleton AP_Airspeed semaphore
singleton AP_Airspeed rename airspeed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm amazed airspeed is not used a local variable in any of our example scripts. But this might conflict with scripts in the wild.

I think its OK because the local variable with overwrite the global so the script will work, just not the this new lib, but it might be worth checking, would also be interesting to see if luacheck would catch it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants