Multicolour Shiftx2 bar memory errors

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
stephen
Posts: 10
Joined: Wed Aug 22, 2018 2:32 am

Multicolour Shiftx2 bar memory errors

Post by stephen »

The startup works for this but soon has memory errors. Are these from the multiple calls to sxSetLed or Virtual channels. The script is only 4kB. So what do I need to do to get it to run?

Code: Select all

println&#40;"---Shift Light Twin Alert---"&#41;
sxCan=0
sxId=0
tickRate=30
sxBright=0  --0=automatic

L=7
--rpm0,rpm4=4000,6800
rpm0,rpm4=2000,4800
inc0=&#40;rpm4-rpm0&#41;/&#40;L+1&#41;
inc4=inc0/L
rpm1,rpm2,rpm3=rpm0+3*inc0,rpm0+5*inc0,rpm0+7*inc0

function sxShiftBar&#40;rpm&#41;
	if rpm<rpm0 then
		sxSetLed&#40;0,L,0,0,0,0&#41;
	elseif rpm<rpm1 then
		n=math.floor&#40;&#40;rpm-rpm0&#41;/inc0+1&#41;
		sxSetLed&#40;0,n,0,255,0,0&#41; --green
		sxSetLed&#40;n,L-n,0,0,0,0&#41;
	elseif rpm<rpm2 then
		n=math.floor&#40;&#40;rpm-rpm1&#41;/inc0+1&#41;
		sxSetLed&#40;0,3,0,255,0,0&#41; --green
		sxSetLed&#40;3,n,255,255,0,0&#41; --yellow
		sxSetLed&#40;n+3,L-n-3,0,0,0,0&#41;
	elseif rpm<rpm3 then
		n=math.floor&#40;&#40;rpm-rpm2&#41;/inc0+1&#41;
		sxSetLed&#40;0,3,0,255,0,0&#41; --green
		sxSetLed&#40;3,2,255,255,0,0&#41; --yellow
		sxSetLed&#40;5,n,255,0,0,0&#41; --red
		sxSetLed&#40;n+5,L-n-5,0,0,0,0&#41;
	elseif rpm<rpm4 then
		n=math.floor&#40;&#40;rpm-rpm3&#41;/inc4+1&#41;
		sxSetLed&#40;0,n,255,255,255,0&#41; --white
		sxSetLed&#40;n,L-n,255,0,0,0&#41;
	else
		sxSetLed&#40;0,L,255,0,0,5&#41; --red flash
	end
end

st,stend=0,7000/30

--Virtual Channel ID's
IDopr = addChannel&#40;"Pres-rpm",25,0,0,30,"psi"&#41;
--IDkph = addChannel&#40;"KPH",25,0,0,300,"kph"&#41;
--IDcnr = addChannel&#40;"CnR",25,0,0,300,"m"&#41;
--IDcmb = addChannel&#40;"AccComb",25,0,0,3,"g"&#41;

function sxOnUpdate&#40;&#41;
	if st<stend then
		--Startup Sequence
		if st<stend/2 then
			ut=st/stend*2.2
		else
			ut=&#40;stend-st&#41;/stend*2.2
		end
		sxShiftBar&#40;rpm4*ut&#41;
		sxUpdateAlert&#40;0, 150*ut&#41;
		sxUpdateAlert&#40;1, 50*ut&#41;
		st=st+1
	else
		rpm=getChannel&#40;"RPM"&#41;
		if rpm==nil then rpm=100 end
		sxShiftBar&#40;rpm&#41;
		oilp=getAnalog&#40;0&#41;
		sxUpdateAlert&#40;1, oilp&#41; --lhs alert
		sxUpdateAlert&#40;0, getChannel&#40;"OilTemp"&#41;&#41; --rhs Alert

		--update Virtual Channels
		if rpm>0 then setChannel&#40;IDopr,oilp/rpm*1000&#41; end
		--setChannel&#40;IDkph,getGpsSpeed&#40;&#41;*1.60934&#41;
		--setChannel&#40;IDcnr,getGpsSpeed&#40;&#41;^2/getImu&#40;0&#41;*0.020378&#41;
		--setChannel&#40;IDcmb,math.sqrt&#40;getImu&#40;0&#41;^2+getImu&#40;1&#41;^2&#41;&#41;
	end
end

function sxOnInit&#40;&#41;
	--configure first alert &#40;right LED&#41; as engine temp
	sxSetAlertThresh&#40;0,0,  0, 70,240,240,0&#41; --cyan
	sxSetAlertThresh&#40;0,1, 60,  0,255,  0,0&#41; --l.green
	sxSetAlertThresh&#40;0,2, 95,255,165,  0,0&#41; --yellow
	sxSetAlertThresh&#40;0,3,115,255,  0,  0,0&#41; --red
	sxSetAlertThresh&#40;0,4,120,255,  0,  0,5&#41; --flash

	--configure second alert &#40;left LED&#41; as oil pressure
	sxSetAlertThresh&#40;1,0, 0,255,  0,  0,5&#41; --red flash
	sxSetAlertThresh&#40;1,1,15,255,165,  0,0&#41; --yellow
	sxSetAlertThresh&#40;1,2,20,  0,255,  0,0&#41; --green
	sxSetAlertThresh&#40;1,3,60,230,140, 50,0&#41; --orange

end

function sxOnBut&#40;b&#41;
	println&#40;'button&#58; ' ..b&#41;
end

---ShiftX2 functions---

function sxSetLed&#40;i,l,r,g,b,f&#41;
	sxTx&#40;10,&#123;i,l,r,g,b,f&#125;&#41;
end

function sxSetAlertThresh&#40;id,tid,th,r,g,b,f&#41;
	sxTx&#40;21,&#123;id,tid,spl&#40;th&#41;,sph&#40;th&#41;,r,g,b,f&#125;&#41;
end

function setBaseConfig&#40;bright&#41;
	sxTx&#40;3,&#123;bright&#125;&#41;
end

function sxSetAlert&#40;id,r,g,b,f&#41;
	sxTx&#40;20,&#123;id,r,g,b,f&#125;&#41;
end

function sxUpdateAlert&#40;id,v&#41;
	if v~=nil then sxTx&#40;22,&#123;id,spl&#40;v&#41;,sph&#40;v&#41;&#125;&#41; end
end

function sxInit&#40;&#41;
	println&#40;'config shiftX2'&#41;
	setBaseConfig&#40;sxBright&#41;
	if sxOnInit~=nil then sxOnInit&#40;&#41; end
end

function sxChkCan&#40;&#41;
	id,ext,data=rxCAN&#40;sxCan,0&#41;
	if id==sxCanId then sxInit&#40;&#41; end
	if id==sxCanId+60 and sxOnBut~=nil then sxOnBut&#40;data&#91;1&#93;&#41; end
end

function sxProcess&#40;&#41;
	sxChkCan&#40;&#41;
	if sxOnUpdate~=nil then sxOnUpdate&#40;&#41; end
end

function sxTx&#40;offset, data&#41;
	txCAN&#40;sxCan, sxCanId + offset, 1, data&#41;
	sleep&#40;10&#41;
end

function spl&#40;v&#41; return bit.band&#40;v,0xFF&#41; end
function sph&#40;v&#41; return bit.rshift&#40;bit.band&#40;v,0xFF00&#41;,8&#41; end

---End Shiftx2 functions---

function onTick&#40;&#41;
    sxProcess&#40;&#41;
    collectgarbage&#40;&#41;
end

sxCanId = 0xE3600 + &#40;256 * sxId&#41;
println&#40;'shiftx2 base id ' ..sxCanId&#41;

setTickRate&#40;tickRate&#41;
sxInit&#40;&#41;

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

Post by brentp »

Try eliminating your global variables and just hardcode the RPM values and so on.

Also, in your onTick() function you can try adding calling the garbage collector, to ensure Lua has cleaned up all available memory:


function onTick()
collectgarbage()

...
...

end

Hope this helps!
Brent Picasso
CEO and Founder, Autosport Labs
Facebook | Twitter

stephen
Posts: 10
Joined: Wed Aug 22, 2018 2:32 am

Lua Newbie

Post by stephen »

Found there was a bit of a learning curve for the RC Lua Scripting. Very annoying to debug but it's very flexible and worthwhile. Really like that the ShiftX2 Leds are individually controllable. Brentp, I didn't want to hard code the rpm as I wanted it adjustable. Maybe fixed shift lights is all I need, I'll find out Sunday. Think code below is working I need to fit in a trial before Sunday.

Here are some Newbie things that helped me:

- Using SciTE on windows for scripting. Can't run scripts but gives line numbers to interpret debug warnings and it is far easier and quicker than doing it through the Windows app.

- Cut and pasting code between it and RC

- Memory errors: Avoid Global variables, Reduce function calls, use local variables, garbage collection and sometimes need to delete script and reset RC.

- Not all the Lua functions are available along with custom RC functions. The reduced Lua on the RC needs a link to reference guide.

- Debugging messages aren't very verbose.

- 'nil' values in variables or function returns can cause issues.

- Where you can test small snipets in SciTE, or cut and past small trials into RC. Mst code can only run on RC.

- OBD and Analog are easy. CAN is to if you have the ID's. Scanning CAN is possible to.

I think this code is now working. Temptation is to keep fiddling but I do need to focus on driving. The overhead of controlling individual Leds doesn't seem to bad. Though offloading this to the ShiftX2 functions would be better.

Next things I might look at:
- Add multiple warning sources on the 2 warning lights.
- I have the button acting as mode switch, so might add road mode to disable logging or predictive timer mode.
- Tidying it up, it's full of hit and miss coding.

Code: Select all

println&#40;"--OilP--Shift Bar--Temp--"&#41;
--By&#58; S.S.Nash Sept'18
--ShiftX2 3/2/2 Shift Bar with Shift point flash
--by Direct control of Leds
--State change on ShiftX2 button
--Virtual Channels
--ShiftX2 Led numbers &#91;9&#93; &#91;0,1,2,3,4,5,6,7&#93; &#91;8&#93;

local sxCan=0
local sxId=0
local tickRate=25
local sxBright,sxScale=0,50  --0=automatic, Scaling

--local rpm0,rpm1,rpm2=4050,6500,7200
local rpm0,rpm1,rpm2=4000,6300,7000
local inc0,inc1=&#40;rpm1-rpm0&#41;/7,&#40;rpm2-rpm1&#41;/7
local State=0
local function sxOnBut&#40;b&#41;
	if b==1 then
		State=&#40;State+1&#41;%2
		if State==0 then
			rpm0,rpm1,rpm2=4000,6300,7000
			sxTx&#40;10,&#123;State,1,255,0,0,0&#125;&#41; --signal State change
		elseif State==1 then
			rpm0,rpm1,rpm2=2050,4500,5200
			sxTx&#40;10,&#123;State,1,0,255,0,0&#125;&#41; --signal State change
		end
		--println&#40;'button&#58; ' ..b.." State&#58;"..State%2&#41;
		inc0,inc1=&#40;rpm1-rpm0&#41;/7,&#40;rpm2-rpm1&#41;/7
		println&#40;"Shift&#58;"..rpm0..",&#91;"..inc0.."&#93;,"..rpm1..",&#91;"..inc1.."&#93;,"..rpm2&#41;
		sleep&#40;150&#41;
	end
end


--Virtual Channel ID's
local IDopr = addChannel&#40;"Pres-rpm",25,1,0,30,"psi"&#41;
local IDkph = addChannel&#40;"KPH",25,0,0,300,"kph"&#41;
local IDcnr = addChannel&#40;"CnR",25,0,0,300,"m"&#41;
local IDcmb = addChannel&#40;"AccComb",25,2,0,3,"g"&#41;

local function sxShiftBar&#40;rpm&#41;
    local n
    if rpm<rpm0 then
        sxTx&#40;10,&#123;0,7,0,0,0,0&#125;&#41;
    elseif rpm<rpm1 then
        n=math.floor&#40;&#40;rpm-rpm0&#41;/inc0+1&#41;
        if n<=3 then
            sxTx&#40;10,&#123;0,n  ,  0,255,  0,0&#125;&#41; --green
        elseif n<=5 then
            sxTx&#40;10,&#123;3,n-3,255,128,  0,0&#125;&#41; --yellow
            --if n==5 then -- reset on rev drop
            --    sxTx&#40;10,&#123;0,3  ,  0,255,  0,0&#125;&#41; --green
            --end
        elseif n<=7 then
            if n==7 then -- reset on rev drop
                sxTx&#40;10,&#123;0,3  ,  0,255,  0,0&#125;&#41; --green
                sxTx&#40;10,&#123;3,2  ,255,128,  0,0&#125;&#41; --yellow
            end
            sxTx&#40;10,&#123;5,n-5,255,  0,  0,0&#125;&#41; --red
        end
    if n<7 then sxTx&#40;10,&#123;n,7-n,0,0,0,0&#125;&#41; end
    elseif rpm<rpm2 then
        n=math.floor&#40;&#40;rpm-rpm1&#41;/inc1+1&#41;
        sxTx&#40;10,&#123;0,n,255,255,255,0&#125;&#41; --white
        if n<7 then sxTx&#40;10,&#123;n,7-n,255,0,0,0&#125;&#41; end
    else
        sxTx&#40;10,&#123;0,7,255,0,0,10&#125;&#41; --red flash
    end
    --if n~=nil then print&#40;math.floor&#40;rpm&#41;.."&#58;"..n.." "&#41; end
end

local st=0
local rpml=0
local function sxOnUpdate&#40;&#41;
    local ut
    local stend=4000/30
    if st<stend then
        --Startup Sequence--
        if st<stend/2 then
            ut=st/stend*2.2
        else
            ut=&#40;stend-st&#41;/stend*2.2
        end
        sxShiftBar&#40;rpm0+&#40;rpm2-rpm0&#41;*ut&#41;
        sxUpdateAlert&#40;0, 150*ut&#41;
        sxUpdateAlert&#40;1, 20*ut&#41;
        st=st+1
        --print&#40;math.floor&#40;rpm2*ut&#41;.." "&#41;
    else
		--println&#40;"--Start ShiftX2--"&#41;
		local kph=getGpsSpeed&#40;&#41;*1.60934
		local rpm=getChannel&#40;"RPM"&#41;
        local oilp=getAnalog&#40;0&#41;
		local t1=getChannel&#40;"OilTemp"&#41;
		local gx,gy=getImu&#40;0&#41;,getImu&#40;1&#41;
        if rpm==nil then rpm=rpml else rpml=rpm end
		--local t1,t2,t3=getChannel&#40;"OilTemp"&#41;,getAnalog&#40;1&#41;,getChannel&#40;"Coolant"&#41;
        --update Virtual Channels
        if rpm>0 then setChannel&#40;IDopr,math.min&#40;40,oilp/rpm*1000&#41;&#41; end
        setChannel&#40;IDkph,kph&#41;
        setChannel&#40;IDcnr,math.min&#40;300,kph^2/math.abs&#40;gx&#41;*0.007868&#41;&#41;
        setChannel&#40;IDcmb,math.sqrt&#40;gx^2+gy^2&#41;&#41;
        --update Alerts
        sxShiftBar&#40;rpm&#41;
        sxUpdateAlert&#40;1, oilp/rpm*1000&#41;     --LHS Alert
        sxUpdateAlert&#40;0, t1&#41; --RHS Alert
        --sxUpdateAlert&#40;0, math.max&#40;t1,t2,t3&#41;&#41; --RHS Alert
    end
end

---ShiftX2 functions---

function sxSetAlertThresh&#40;id,tid,th,r,g,b,f&#41;
    sxTx&#40;21,&#123;id,tid,spl&#40;th&#41;,sph&#40;th&#41;,r,g,b,f&#125;&#41;
end

function sxUpdateAlert&#40;id,v&#41;
    if v~=nil then sxTx&#40;22,&#123;id,spl&#40;v&#41;,sph&#40;v&#41;&#125;&#41; end
end

function sxInit&#40;&#41;
    println&#40;'config shiftX2'&#41;
    --setBaseConfig&#40;sxBright,sxScale&#41;
    sxTx&#40;3,&#123;sxBright,sxScale&#125;&#41;

	--sxOnInit&#40;&#41;
    --configure first alert &#40;right LED&#41; as engine temp
    sxSetAlertThresh&#40;0,0,  0, 70,240,240,0&#41; --cyan
    sxSetAlertThresh&#40;0,1, 60,  0,255,  0,0&#41; --l.green
    sxSetAlertThresh&#40;0,2,110,255,128,  0,0&#41; --yellow
    sxSetAlertThresh&#40;0,3,120,255,  0,  0,0&#41; --red
    sxSetAlertThresh&#40;0,4,125,255,  0,  0,10&#41; --flash
    --configure second alert &#40;left LED&#41; as oil pressure
    sxSetAlertThresh&#40;1,0,  0,255,  0,  0,10&#41; --red flash
    sxSetAlertThresh&#40;1,1,7.5,255,128,  0,0&#41; --yellow
    sxSetAlertThresh&#40;1,2,15,  0,255,  0,0&#41; --green
    --sxSetAlertThresh&#40;1,3,30,255,128,  0,0&#41; --orange
end

function sxTx&#40;offset, data&#41;
    txCAN&#40;sxCan, sxCanId + offset, 1, data&#41;
    sleep&#40;10&#41;
end

function spl&#40;v&#41; return bit.band&#40;v,0xFF&#41; end
function sph&#40;v&#41; return bit.rshift&#40;bit.band&#40;v,0xFF00&#41;,8&#41; end

---End Shiftx2 functions---

function onTick&#40;&#41;
	--local ut=getUptime&#40;&#41;
    collectgarbage&#40;&#41;
    --sxProcess&#40;&#41;
    --sxChkCan&#40;&#41;
    id,ext,data=rxCAN&#40;sxCan,0&#41;
    if id==sxCanId then sxInit&#40;&#41; end
    if id==sxCanId+60 and sxOnBut~=nil then sxOnBut&#40;data&#91;1&#93;&#41; end

    if sxOnUpdate~=nil then sxOnUpdate&#40;&#41; end
	--println&#40;string.format&#40;"Duty time&#58; %f",getUptime&#40;&#41;-ut&#41;&#41;
end

sxCanId = 0xE3600 + &#40;256 * sxId&#41;
println&#40;'shiftx2 base id ' ..sxCanId&#41;

setTickRate&#40;tickRate&#41;
sxInit&#40;&#41;


Post Reply