Hangups with 'require' and mavlink_msgs

Hi all! Hope you all are doing well. Having a little bit of trouble configuring an mRo PIxracer Pro with some of the example scripting utilities provided in the ArduPlane documentation.

I’m running the latest 4.4.4, with scripts enabled, and am trying to import ‘mavlink_msgs’ as is demonstrated in the example plane_aerobatics.lua.

I’ve written a very simple handler taken nearly entirely from this code, shown below

local function mavlink_receiver()
    local self = {}
    local mavlink_msgs = require("mavlink_msgs")

    local MESSAGE_ID = mavlink_msgs.get_msgid("DEBUG_VECT")
    gcs:send_named_float(MAV_SEVERITY.EMERGENCY, MESSAGE_ID)

    return self
end

But when the script is loaded, Mission Planner reports: Attempt to call a nil value (global ‘require’). A little bit lost in terms of where this may be coming from, given that things are pulled nearly 1-1 from the examples. Not sure if anyone has any particular insight into this, but would greatly appreciate any assistance that you all may have. Thanks!!

Same here, I went through this exact same process. The examples seem to be incorrect as well as the comments in the auto-generated lua docs.

Here is the example that uses require:

Here is the comment that claims you can use mavlink_msgs directly:

"
– initializes mavlink
@param num_rx_msgid uint32_t_ud|integer
@param msg_queue_length uint32_t_ud|integer
function mavlink:init(num_rx_msgid, msg_queue_length) end

– marks mavlink message for receive, message id can be get using mavlink_msgs.get_msgid(“MSG_NAME”)
@param msg_id number
function mavlink:register_rx_msgid(msg_id) end

– receives mavlink message marked for receive using mavlink:register_rx_msgid
@return string – bytes
@return number – mavlink channel
@return uint32_t_ud – receive_timestamp
function mavlink:receive_chan() end

– sends mavlink message, to use this function the call should be like this:
– mavlink:send(chan, mavlink_msgs.encode(“MSG_NAME”, {param1 = value1, param2 = value2, …}})
@param chan integer
@param msgid integer
@param message string
function mavlink:send_chan(chan, msgid, message) end

"

From here:

Has anyone used this before? Or do you have an understanding of the source code as to why this isn’t working?

Use the master branch. I can’t recall at the moment if “require” is valid in 4.5, but it’s definitely not going to work in 4.4 or older.

Previously, “require” was not possible within AP’s Lua engine.

I think you will also have to create the MAVLink directory inside the scripting directory on your SD card and copy the files within this link:

1 Like

Thanks for your reply, it was a huge help. I updated the firmware to 4.5.1 via QGroundControl and it seems to be recognising require successfully now. For anyone coming to this question you need to include the MAVLink files as Yuri mentioned, but also you need to create a APM/scripts/modules/MAVLink/ directory and include them in there. So let’s be thorough and clear:

In APM/scripts/
   your_test_script.lua
In APM/scripts/modules/MAVLink/
   mavlink_msg_COMMAND_ACK.lua
   mavlink_msg_COMMAND_LONG.lua
   mavlink_msgs.lua
  • Now in your_test_script.lua you can include the require line:

local mavlink_msgs = require("MAVLink/mavlink_msgs")

and this works because you can print the package.path variable and you will see the following search paths:

/APM/scripts/modules/?.lua;/APM/scripts/modules/?/init.lua;./?.lua;./?/init.lua