I had to add math to the layout plugin so I could do sin, cos and floor, then just looking at the motor status and updating xpos, ypos and ang.
Then using the set_bounds_callback to return a bounding box.
For the rotation, I generated 360 image states (1 for each degree of rotation) and used the set_element_state_callback to return the image number. (This is terribly inefficient, the layout size ends up being 800k or so).
Code
<!-- the content of the script element will be called as a function by the layout plugin -->
<!-- use CDATA block to avoid the need to escape angle brackets and ampersands -->
<script><![CDATA[
-- file is the layout file object
print("BIGTRAK2.LAY")
print("LAYOUT LOADED file.device.name = "..file.device.name)
print("LAYOUT LOADED file.device.shortname = "..file.device.shortname)
print("LAYOUT LOADED file.device.tag = = "..file.device.tag)
print(math.cos(3.4)) -- math isn't in env table
print(machine.output:get_value("left_motor_forward"))
print(machine.output:get_value("motor_pos"))
speed = 9 / 60
axle = 6.4 / 2
ang = 0
xpos = 50
ypos = 50
function calcpos(val)
if val == "11000" then xpos = xpos + math.cos(ang) * speed ypos = ypos + math.sin(ang) * speed
elseif val == "00110" then xpos = xpos - math.cos(ang) * speed ypos = ypos - math.sin(ang) * speed
elseif val == "10010" then ang = ang + speed / axle
elseif val == "01100" then ang = ang - speed / axle
print(ang)
end
end
file:set_resolve_tags_callback(
function ()
file.views["Internal Layout"].items["bigtrak"]:set_bounds_callback(
function ()
local b = emu.render_bounds()
local boxxsize = 25
local boxysize = 25
xc = xpos
yc = ypos
x0 = xc - boxxsize / 2
y0 = yc - boxysize / 2
x1 = xc + boxxsize / 2
y1 = yc + boxysize / 2
bs = 1/100 -- boundscale (must scale it down to between 0.0 and 1.0)
b:set_xy(x0 * bs, y0 * bs, x1 * bs, y1 * bs)
out = machine.output
newval = tostring(out:get_value("left_motor_forward")) ..
tostring(out:get_value("right_motor_forward")) ..
tostring(out:get_value("left_motor_reverse")) ..
tostring(out:get_value("right_motor_reverse")) ..
tostring(out:get_value("0.1"))
print(newval, xpos, ypos, x0, y0, x1, y1, ang)
calcpos(newval)
return b
end)
file.views["Internal Layout"].items["bigtrak"]:set_element_state_callback(
function ()
image = math.floor(ang / 3.14 * 180.0)
image = (image + 90) % 360
print ("image" .. image)
return image
end)
end)
]]></script>
One thing that I was thinking about was a parameter that would have a list of values, and each time the parameter is used, it will return the next value in the list.