BUG: nil in Lua script for CAN signal rates < 50Hz

Report any thing that looks like a bug or problem in the system here

Moderators: JeffC, stieg

Post Reply
GTIspirit
Posts: 249
Joined: Wed Jan 09, 2013 11:20 am
Location: SE Michigan

BUG: nil in Lua script for CAN signal rates < 50Hz

Post by GTIspirit »

Trying to troubleshoot my Lua script I figured out that there is a 'nil' error for CAN signal rates less than 50Hz.

So, when I try to print a variable using the command:

Code: Select all

println&#40;'rev&#58; ' ..getChannel&#40;"rev"&#41;&#41;
It only prints when the CAN signal rate is set to 50Hz.
If I change the rate to 25Hz then I get sporadic nils
rev: 0.0
[lua] Script error: [string "batt_u_warn = 11..."]:59.0: attempt to concatenate a nil value
rev: 0.0
rev: 0.0
rev: 0.0
rev: 0.0
[lua] Script error: [string "batt_u_warn = 11..."]:59.0: attempt to concatenate a nil value
rev: 0.0
rev: 0.0
rev: 0.0
rev: 0.0
[lua] Script error: [string "batt_u_warn = 11..."]:59.0: attempt to concatenate a nil value
When I change to 10Hz (or lower) then I get the constant error:
[lua] Script error: [string "batt_u_warn = 11..."]:59.0: attempt to concatenate a nil value
[lua] Failure: Runtime Error
TickRate doesn't seem to influence the behavior. I tried with TickRate of 1, thinking maybe it has to be equal to the refresh rate of the lowest CAN signal rate, which was 1Hz (temperatures don't change that quickly....) but that didn't seem to make a difference.

Temporary workaround for my display issue is to set the CAN signal rate to 50Hz for all variables used in the Lua script.

brentp
Site Admin
Posts: 6282
Joined: Wed Jan 24, 2007 6:36 am

Post by brentp »

Hi, this is expected behavior - it is not guaranteed to return a current value; you will need to check for nil before using the value.

See the note here: https://wiki.autosportlabs.com/RaceCapt ... r_name_.29
Brent Picasso
CEO and Founder, Autosport Labs
Facebook | Twitter

GTIspirit
Posts: 249
Joined: Wed Jan 09, 2013 11:20 am
Location: SE Michigan

Post by GTIspirit »

@brentp thanks for the response. However, this isn't how I expect it should work. CAN works on a buffer principle, last value is inherently held in the buffer until a new value comes in and overwrites the old value. That's how the hardware works. So as long as one single valid value was received, Lua should never return a nil.

I can prove this because the update rate on some of the CAN messages I'm using is 25ms, which is 40Hz. Setting the CAN sampling rate in RCPro to 50Hz means it's inherently sampling a stale value for a small period of time.

Sounds like there is a timing mismatch / module sync bug between CAN and Lua.

Since CAN inherently holds the last value in buffer until a new one comes in I'm hoping this is a relatively simple problem to resolve.

aUzer
Posts: 20
Joined: Mon May 18, 2020 8:19 am

Post by aUzer »

Part 1
---
From the documentation at https://wiki.autosportlabs.com/RaceCapt ... _Scripting, my understanding was that getChannel('name') would always return a value, as long as a value had been set for that named channel at least once -- i.e., my expectation was similar to GTIspirit's.

I did the following (RCP3, 2.17.8):
addChannel('numVch', 1, 0, 1, maxVchToMake)
to create a virtual channel that shows the number of virtual channels that have been added ... thus, it only gets updated when a channel is added.

For me, doing:
val = getChannel('numVch')
always returned a nil ... so the workaround was to maintain a map of virtual-channel IDs by channel name so I could later retrieve the IDs (to get the values) for the virtual channels that got created. To my understanding, because the virtual-channel names are always known, the ID/name map would be unnecessary if getChannel('name') only returned nil when the named channel either did not exist or had not yet had a value set. Is this true? If not, why not?

Part 2
---
It was my expectation that a virtual channel is simply an element that has the following characteristics:
- can be created via a lua script
- can have its value set via a lua script
- is only update via the lua script
- will be shown in the "raw channels" dashboard view
- can be used to create dashboard gauges

Are all these true? Are there other characteristics aside from those stated above?
---
Enquiring geek wants to know! #;-)

brentp
Site Admin
Posts: 6282
Joined: Wed Jan 24, 2007 6:36 am

Post by brentp »

Hi,

#1 - not true; you always have to check for nil, even if the value has been set previously.

#2 - is true; It creates a channel, and it appears like any other channel in the system. It can only be updated by Lua.
Brent Picasso
CEO and Founder, Autosport Labs
Facebook | Twitter

aUzer
Posts: 20
Joined: Mon May 18, 2020 8:19 am

Post by aUzer »

Please help me understand why getChannel('name') would ever return a nil after a value has been set?

This implies that getChannel('name') can intermittently return a nil or the currently-set value. Is that really true ... and, if so, what makes it so non-deterministic ... and are there other operations that are similarly non-deterministic?

It also implies that getChannel(channelID) could do the same ... if not, why not -- i.e., what makes getChannel('name') different from getChannel(channelID) when they presumably are just operations that extract the value from the same data structure?

brentp
Site Admin
Posts: 6282
Joined: Wed Jan 24, 2007 6:36 am

Post by brentp »

In a nutshell, the firmware processes the sample data like a pipeline, or a stream of data flowing from various sources and on to the SD card or telemetry.

At any one point, the current sample in-flight may or may not have the channel value populated when queried, based on the sample rate. That's why you need to perform the nil check. Increasing the sample rate of the channel will reduce the frequency of nil values.

Going forward, If we can improve this, we will. Thanks!
Brent Picasso
CEO and Founder, Autosport Labs
Facebook | Twitter

aUzer
Posts: 20
Joined: Mon May 18, 2020 8:19 am

Post by aUzer »

Not meaning to be a PITA, but the way it works is at least unexpected. If it's working the way you want it to work, then the documentation should indicate that using getChannel('NAME') may not (and likely will not) return a large percentage of the currently set values when compared to the values returned via getChannel(channelID).

I think it's safe to say that the normal interpretation of these two operations is that they are two ways of getting the same results ... but that is not true. As proof, I've attached a text file (test.txt) that contains 2 short test scripts and the results from running each on a RaceCapture/Pro Mk3 v2.17.8 -- the results are very different.

In my test, using getChannel('NAME'):
- at a 10 Hz tick rate, a value was returned 2% of the time
- at a 50 Hz tick rate, a value was returned 0% of the time
- at a 1000 Hz tick rate, a value was returned 1% of the time
... this is contrary to what you state should occur.

in contrast, getChannel(channelID) returned a value 100% of the time with all tick rates.
Attachments
test.txt
(7.78 KiB) Downloaded 414 times

brentp
Site Admin
Posts: 6282
Joined: Wed Jan 24, 2007 6:36 am

Post by brentp »

Good news, this will be resolved in the 2.18.0 firmware, due out soon in conjunction with the 2.0 app.

With this change, the only time it will return nil is if the channel name is invalid / unknown.
Brent Picasso
CEO and Founder, Autosport Labs
Facebook | Twitter

aUzer
Posts: 20
Joined: Mon May 18, 2020 8:19 am

Post by aUzer »

brentp wrote:... With this change, the only time it will return nil is if the channel name is invalid / unknown.
#;-))

Post Reply