First Script - No Testing

Discussion on the Lua Scripting capabilities for RaceCapture/Pro. Also see the <a href="http://autosportlabs.net/RaceCapturePro_Lua_Scripting">Lua Scripting Guide</a>

Moderators: JeffC, stieg

Post Reply
Bryan@UnderbiteRacing
Posts: 25
Joined: Sun May 01, 2016 12:36 pm
Contact:

First Script - No Testing

Post by Bryan@UnderbiteRacing »

Hi folks -

Due to some circumstances beyond my control, I've run out of time to test my first Lua script in the garage before I head to the track this weekend. I'd really appreciate it if you could have a look to see if there are any fatal flaws in the way I've assembled the individual scripts borrowed from this site.

Thanks in advance for any insights!

Cheers,
Bryan

Code: Select all

tickRate = 10
setTickRate&#40;tickRate&#41;
 
--FUEL LEVEL--
fuel2Id = addChannel&#40;"FuelLevel",10,2,0,8,"gal"&#41;
maxAvg = 100 
 
fuelAvg=&#123;&#125;
fuel2Index = 1
 
function updateFuelAvg&#40;value&#41;
  local i
  if #fuelAvg == 0 then
    for i = 1, maxAvg do fuelAvg&#91;i&#93;=0 end
  end
  fuelAvg&#91;fuel2Index&#93; = value
  fuel2Index = fuel2Index + 1
  if fuel2Index > maxAvg then fuel2Index = 1 end
  local sum = 0
  for i = 1, #fuelAvg do
    sum = sum + fuelAvg&#91;i&#93;
  end
  setChannel&#40;fuel2Id, sum / maxAvg&#41;
end
 
--GEAR CALCULATION--
local _1stGear = 3.136
local _2ndGear = 1.888
local _3rdGear = 1.330
local _4thGear = 1.000
local _5thGear = 0.814
local FinalDrive = 4.30
local TireDia = 23.0  
local gearErr = 0.1
local rpmSpeedRatio = 0
local gearPos = 0 --this is the gear channel variable
 
function calcGear&#40;&#41; --updates gear position every second by default
 
local speed = getGpsSpeed&#40;&#41;
local rpm = getTimerRpm&#40;0&#41;
 
gearId = addChannel&#40;"Gear",5&#41;
 
if speed > 10 then
    
   rpmSpeedRatio = &#40;rpm/speed&#41;/&#40;FinalDrive*1056/&#40;TireDia*3.14159&#41;&#41;
 
    if &#40;&#40;_1stGear - rpmSpeedRatio&#41;^2&#41; < &#40;gearErr^2&#41; then gearPos = 1 end
    if &#40;&#40;_2ndGear - rpmSpeedRatio&#41;^2&#41; < &#40;gearErr^2&#41; then gearPos = 2 end
    if &#40;&#40;_3rdGear - rpmSpeedRatio&#41;^2&#41; < &#40;gearErr^2&#41; then gearPos = 3 end
    if &#40;&#40;_4thGear - rpmSpeedRatio&#41;^2&#41; < &#40;gearErr^2&#41; then gearPos = 4 end
    if &#40;&#40;_5thGear - rpmSpeedRatio&#41;^2&#41; < &#40;gearErr^2&#41; then gearPos = 5 end
 
else gearPos = 0 end
 
setChannel&#40;gearId, gearPos&#41; --outputs to virtual channel
 
end

--START LOGGING--
function loggingStart&#40;&#41;
  if getGpsSpeed&#40;&#41; > 25 then
    startLogging&#40;&#41;
  end
 
--GOPRO CONTROL--
goproSsid = 'UnderbiteRacing'
goproPwd = 'Password'
goproStart = 30
--GoPro will be stopped based on IsLogging&#40;&#41; == 0 below.
--goproStop = 5
debug = 0

port = 4
wifiStatus = 0
lastInitTime = 0
initTimeout = 20000
 
function logMsg&#40;msg&#41;
  println&#40;'&#91;GoProWiFi&#93; ' ..msg&#41;
end
 
function sendCrlf&#40;&#41;
  writeCSer&#40;port, 13&#41;
  writeCSer&#40;port, 10&#41;
end
 
function sendRaw&#40;val&#41;
  for i=1, #val do
    local c = string.sub&#40;val, i, i&#41;
    writeCSer&#40;port, string.byte&#40;c&#41;&#41;
  end
end
 
function sendAt&#40;val&#41;
  if debug == 1 then logMsg&#40;'send&#58; ' ..val&#41; end
  sendRaw&#40;val&#41;
  sendCrlf&#40;&#41;
end
 
function toInt&#40;val&#41;
  return string.sub&#40;val, 1, -3&#41;
end
 
function httpGet&#40;url&#41;
  sendAt&#40;'AT+CIPSTART="TCP","10.5.5.9",80'&#41;
  sleep&#40;500&#41;
  local crlf = string.char&#40;13&#41; ..string.char&#40;10&#41;
  local get = 'GET ' ..url ..' HTTP/1.0' ..crlf ..crlf
  sendAt&#40;'AT+CIPSEND=' ..toInt&#40;#get&#41;&#41;
  sleep&#40;100&#41;
  sendRaw&#40;get&#41;
  sleep&#40;100&#41;
  sendAt&#40;"AT+CIPCLOSE"&#41; 
end
 
function sendGoProShutter&#40;cmd&#41;
  httpGet&#40;'/bacpac/SH?t=' ..goproPwd ..'&p=%' ..cmd&#41;
end
 
function startGoPro&#40;&#41;
  logMsg&#40;'start GoPro'&#41;
  sendGoProShutter&#40;'01'&#41;    
end
 
function stopGoPro&#40;&#41;
  logMsg&#40;'stop GoPro'&#41;
  sendGoProShutter&#40;'00'&#41;    
end
 
recording = 0
 
function initWiFi&#40;&#41;
  logMsg&#40;'initializing'&#41;
  sendAt&#40;'AT+RST'&#41;
  sleep&#40;2000&#41;
  sendAt&#40;'AT+CWMODE_CUR=1'&#41;
  sleep&#40;1000&#41;
  sendAt&#40;'AT+CWJAP_CUR="' ..goproSsid ..'","' ..goproPwd ..'"'&#41;
  wifiStatus = 1
end
 
function processIncoming&#40;&#41;
  local line = readSer&#40;port, 100&#41;
  if line ~= '' and debug == 1 then print&#40;line&#41; end
  if string.match&#40;line, 'WIFI GOT IP'&#41; then 
    wifiStatus = 2
  end
  if wifiStatus == 2 and string.match&#40;line, 'OK'&#41; then
    wifiStatus = 3
    logMsg&#40;'ready for GoPro'&#41;
  end
end
 
function checkGoPro&#40;&#41;
  if wifiStatus == 0 then
    initWiFi&#40;&#41;
    lastInitTime = getUptime&#40;&#41;
    return
  end
  if wifiStatus == 1 and getUptime&#40;&#41; > lastInitTime + initTimeout then
    logMsg&#40;'could not connect to GoPro'&#41;
    wifiStatus = 0
  end
  processIncoming&#40;&#41;
  if wifiStatus ~= 3 then
    return
  end
  trigger1 = getGpsSpeed&#40;&#41;
  trigger2 = isLogging&#40;&#41;
 
  if recording == 0 and trigger1 > goproStart then
    startGoPro&#40;&#41;
    recording = 1
  end
  if recording == 1 and trigger2 == 0 then
    stopGoPro&#40;&#41;
    recording = 0
  end 
end
 
--MAX RPM FLAG--
maxRpmId = addChannel&#40;"MaxRPM", 10&#41;
maxRpm = 0
 
function logMaxRPM&#40;&#41;
  local rpm = getTimerRpm&#40;0&#41;
  if rpm > maxRpm then
    maxRpm = rpm
    setChannel&#40;maxRpmId, maxRpm&#41;
  end
end
 
--MAIN SCRIPT--
function onTick&#40;&#41;
 
  updateFuelAvg&#40;getAnalog&#40;1&#41;&#41;
  calcGear&#40;&#41;
  loggingStart&#40;&#41;
  checkGoPro&#40;&#41;
  logMaxRPM&#40;&#41;
 
end

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

Post by brentp »

First thing I checked was the use of a common onTick() function, which seemed to be there, so good job.

How is it working now for you?
Brent Picasso
CEO and Founder, Autosport Labs
Facebook | Twitter

Bryan@UnderbiteRacing
Posts: 25
Joined: Sun May 01, 2016 12:36 pm
Contact:

Post by Bryan@UnderbiteRacing »

Hi Brent -

Thanks for taking the time to reply. Due to some operator error, I didn't get the script saved on the RaceCapture unit before the last session. I did have success with the basic Amazon Fire tablet working fast enough to be a useful tachometer, and streaming telemetry to Podium from the Fire tablet over my iPhones personal hotspot.

Again, due to operator error, I didn't save any logs on the SD card. Since everything else worked automatically, I assumed the logging had also started.

I should have a chance to try loading the script in the shop before the next race at the end of January. I'll report back with my successes or failures...

Merry Christmas to you and the ASL team!

Cheers,
Bryan

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

Post by brentp »

No problem. Thanks, and keep us posted on the progress. :)
Brent Picasso
CEO and Founder, Autosport Labs
Facebook | Twitter

Bryan@UnderbiteRacing
Posts: 25
Joined: Sun May 01, 2016 12:36 pm
Contact:

Post by Bryan@UnderbiteRacing »

I had a chance today to test the script - no luck!

The script wouldn't load, giving me an "malformed number" error associated with the first line. When I remove the "--GENERAL--" comment, it would give me the same error associated with the "tickRate = 10" code.

When I copy and paste a basic script off the website, it will load fine.

Any suggestions?

Many thanks!
Bryan

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

Post by brentp »

When you look at the log after writing the script back to RCP, it will tell you what line number the error occurred.

You can also paste your script here if you get stuck.

Bryan@UnderbiteRacing
Posts: 25
Joined: Sun May 01, 2016 12:36 pm
Contact:

Post by Bryan@UnderbiteRacing »

Got it! To troubleshoot, I moved each of my functions into a separate script, but none would load. When they failed, I noticed that the error location was different in each, and eventually noticed that it corresponded to the first blank line.

In my copy & paste efforts, a number of "space" characters crept into the script, at empty lines and the beginning and end of other lines. Once I got those fixed, I had one missing "end" statement and now I'm up and running.

Thanks for the sounding board - I'm obviously still on the very steep part of the learning curve!

Cheers,
Bryan

Post Reply