Topic: Live For Speed + Chumby ???

Hello All.

Have a look at this post, it explains most of what I want to do:
http://www.lfsforum.net/showthread.php?t=53892

Now. There's got to be some way to at least display the gear I'm in. If someone could get me that far, I'm sure I can figure out the rest.

Mono doesn't run on Chumby (yet?), right?

Jake

2 (edited by ChumbyLurker 2009-03-15 13:15:51)

Re: Live For Speed + Chumby ???

It looks like an interesting problem.  You could probably use something like nc to read the data, then pipe that through perl, unpack() the data, then print that out to an XML file.  You might want to have a rolling list of files, say 5 or so, to avoid synchronization issues.

It would be something along the lines of:

nc -l -u 4000 | perl -e '$i=0; while(<>) { ($time, $car, $flags, $gear, $spareB, $speed, $rpm, $turbo, $engtemp, $fuel, $oilpress, $spare1, $spare2, $spare3, $throttle, $brake, $clutch, $display1, $display2, $id) = unpack("Ic4IccffffffffffffC16C16I", $_); open(my $f, ">", "/tmp/lfs-" . (($i)%5) . ".xml"); print $f "<tag time=\"$time\" car=\"$car\" flags=\"$flags\" gear=\"$gear\" spareb=\"$spareb\" speed=\"$speed\" rpm=\"$rpm\" turbo=\"$turbo\" engtemp=\"$engtemp\" fuel=\"$fuel\" oilpress=\"$oilpress\" spare1=\"$spare1\" spare2=\"$spare2\" spare3=\"$spare3\" throttle=\"$throttle\" brake=\"$brake\" clutch=\"$clutch\" display1=\"$display1\" display2=\"$display2\"/>\n"; close($f); open(my $f, ">", "/tmp/current-file"); print $f (($i++)%5); close($f); }'

Then you read /tmp/current-file, figure out what the latest file is, then open /tmp/lfs-$currentfile, and read everything in.

I'm not sure if netcat will work, though.  Give it a shot and see what happens.  Try just running

nc -l -u 4000 | hexdump

and seeing if any data comes out of it.  If it does, you know it's an approach you can take.

Re: Live For Speed + Chumby ???

When I run -u is apparently an invalid option. I changed -u to -p and get:

chumby:~# nc -l -p 4000 | hexdump
hexdump 1.01
<stdin>

No data?, or did I do something wrong?

(Thanks for the reply)

Re: Live For Speed + Chumby ???

Unfortunately, it appears that the 'nc' command in the chumby does not support UDP, which you'd need to capture the packets coming from Live For Speed  - that's what the -u option specifies.

5 (edited by ChumbyLurker 2009-03-17 15:35:25)

Re: Live For Speed + Chumby ???

You're right.  That's what I get for prototyping on a non-Chumby device.

There's a working netcat binary available at this empeg site: http://www.trejan.com/projects/empeg/#NETCAT.  I've verified that it works on Chumby, and that it can, indeed, receive UDP packets.  To a point.

There are a few support scripts you'll need on your dongle, in addition to the nc binary available above.  The first is a simple script that wraps the UDP packet.  By default, netcat wants to set up a bidirectional communication, which isn't what you want.  This script simply sends a linefeed so that netcat will realize it's unable to establish communication, so when it does receive a packet it'll quit right away:

#!/bin/sh
#get_udp_packet.sh [port]
echo "\n" | /mnt/usb/nc -l -p $1 -u

Then there's the perl script.  I figure that at the size it's grown to, it no longer qualifies as a one-liner by any stretch of the imagination smile.  You'll want to adjust the paths, and I'm still not at all sure the unpack() has a working string:

#!/usr/bin/perl -w
my $i=0;
sub get_line {
    open(my $fh, '-|', '/mnt/usb/get_udp_packet.sh 4000');
    my $t = <$fh>;
    close($fh);
    return $t;
}

$SIG{'TERM'} = sub { exit(); };

while(1) {
    my $line = get_line();
#    print STDERR "Got line: [$line]\n";
    my ($time, $car, $flags, $gear, $spareB, $speed, $rpm, $turbo,
        $engtemp, $fuel, $oilpress, $spare1, $spare2, $spare3, $throttle,
        $brake, $clutch, $display1, $display2, $id)
        = unpack("Ic4IccffffffffffffC16C16I", $line);

    open(my $f, ">", "/tmp/lfs-" . (($i)%5) . ".xml");
    print $f "<tag time=\"$time\" car=\"$car\" flags=\"$flags\" gear=\"$gear\" "
           . "spareb=\"$spareB\" speed=\"$speed\" rpm=\"$rpm\" "
           . "turbo=\"$turbo\" engtemp=\"$engtemp\" fuel=\"$fuel\" "
           . "oilpress=\"$oilpress\" spare1=\"$spare1\" spare2=\"$spare2\" "
           . "spare3=\"$spare3\" throttle=\"$throttle\" brake=\"$brake\" "
           . "clutch=\"$clutch\" display1=\"$display1\" "
           . "display2=\"$display2\"/>\n";
    close($f);

    open(my $f2, ">", "/tmp/current-file");
    print $f2 (($i++)%5);
    close($f2);
}

6 (edited by germansoccer6113 2009-03-22 16:54:50)

Re: Live For Speed + Chumby ???

I'll get the netcat binaries, and try ChumbyLurker's first suggestion again when I have time.

[edit: It works!]

chumby:/mnt/tmp# ./nc -l -u -p 4000
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%äO                                        
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%âV
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%â[
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%äh
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%fn
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%Úr
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%\x
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%R}
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%ì~
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%<
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%d
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%ª
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%Ò
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%\
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%ä
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%Î
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%°
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%¤
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%`
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%8
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%è
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%R
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%\ 
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%Ø¡
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%â¦
UF1@3µÿ>?Fuel 49.9%   Brake Bal Fr 83%¨§

That's about 30 seconds worth of data.


I tried using ChumbyLurker's other scripts:

chumby:/mnt/usb# ./script2.pl
Use of uninitialized value in concatenation (.) or string at ./script2.pl line 21.

That line repeats until the script is canceled.
script2.pl is the perl script. Line 21 of it reads:

    print $f "<tag time=\"$time\" car=\"$car\" flags=\"$flags\" gear=\"$gear\" "

7 (edited by ChumbyLurker 2009-03-22 19:55:27)

Re: Live For Speed + Chumby ???

It's quite interesting to see that it works without that shell script hack I also posted.  Better, in fact, because that means it's not constantly forking off new processes smile

That issue means I got the unpack() string wrong.  If you log some of the packets by running the following for a short time and then posting the resulting binary somewhere where I can take a look at it, it would make it much easier to come up with either a perl program or a C program that would generate the XML you'd need to write a Flash movie to do what you want to do.

./nc -l -u -p 4000 > lfs.bin

Re: Live For Speed + Chumby ???

Here's lfs.bin
It's not pretty...:D

Using my new favorite file sharing site:
http://drop.io/nglvk8t

Re: Live For Speed + Chumby ???

A note on the OutGauge documentation: words are 16-bits.  Anyway, give the following a try.  It uses your method of reading from netcat, rather than the script I put together:

#!/usr/bin/perl -w
my $i=0;
{
    my $h;
    sub get_line {
        if( !defined $h ) {
            open($h, '-|', '/mnt/usb/nc -l -u -p 4000')
#            open($h, '<', 'lfs.bin')
                or die("Couldn't open netcat: $!");
            }
        read($h, $f, 0x60) or die("Couldn't read: $!");
        return $f;
    }
}

$SIG{'TERM'} = sub { exit(); };

while(1) {
    my $line = get_line();
#    print STDERR "Got line: [$line]\n";
    my ($time, $car, $flags, $gear, $spareB, $speed, $rpm, $turbo,
        $engtemp, $fuel, $oilpress, $spare1, $spare2, $spare3, $throttle,
        $brake, $clutch, $display1, $display2, $id)
        = unpack("IA4SccffffffffffffA16A16I", $line);

    open(my $f, ">", "/tmp/lfs-" . (($i)%5) . ".xml");
    print $f "<tag time=\"$time\" car=\"$car\" flags=\"$flags\" gear=\"$gear\" "
           . "spareb=\"$spareB\" speed=\"$speed\" rpm=\"$rpm\" "
           . "turbo=\"$turbo\" engtemp=\"$engtemp\" fuel=\"$fuel\" "
           . "oilpress=\"$oilpress\" spare1=\"$spare1\" spare2=\"$spare2\" "
           . "spare3=\"$spare3\" throttle=\"$throttle\" brake=\"$brake\" "
           . "clutch=\"$clutch\" display1=\"$display1\" "
           . "display2=\"$display2\" id=\"$id\"/>\n";
    close($f);

    open(my $f2, ">", "/tmp/current-file");
    print $f2 (($i++)%5);
    close($f2);
}

10 (edited by germansoccer6113 2009-03-24 14:43:27)

Re: Live For Speed + Chumby ???

Works! lfs-[0-4].xml display all the info.

chumby:~# cat /tmp/lfs-0.xml
<tag time="193090" car="BF1" flags="16388" gear="8" spareb="0" speed="1.2611686789234e-44" rpm="3452.15771484375" turbo="0" engtemp="0" fuel="0.49265894293785" oilpress="0" spare1="0" spare2="0" spare3="0" throttle="0.137314170598984" brke="0" clutch="1" display1="Fuel 49.3%" display2="Front ARB  120.0" id="0"/>

Is there a way to view the data real-time, switching to the next file every so-and-so miliseconds? Is it possible to direct the content of the current xml file to the echo command?
Thank you very much for your help, by the way.

11 (edited by ChumbyLurker 2009-03-24 14:54:06)

Re: Live For Speed + Chumby ???

No problem smile

If you print it to the screen in addition to the file, it'll do what you want.  Change the "print "\r$s"" to "print "$s\n"" to get a backlog of packets.  Untested, but ought to work:

#!/usr/bin/perl -w
my $i=0;
{
    my $h;
    sub get_line {
        if( !defined $h ) {
            open($h, '-|', '/mnt/usb/nc -l -u -p 4000')
#            open($h, '<', 'lfs.bin')
                or die("Couldn't open netcat: $!");
            }
        read($h, $f, 0x60) or die("Couldn't read: $!");
        return $f;
    }
}

$SIG{'TERM'} = sub { exit(); };
my $s;
while(1) {
    my $line = get_line();
#    print STDERR "Got line: [$line]\n";
    my ($time, $car, $flags, $gear, $spareB, $speed, $rpm, $turbo,
        $engtemp, $fuel, $oilpress, $spare1, $spare2, $spare3, $throttle,
        $brake, $clutch, $display1, $display2, $id)
        = unpack("IA4SccffffffffffffA16A16I", $line);

    open(my $f, ">", "/tmp/lfs-" . (($i)%5) . ".xml");
    $s = "<tag time=\"$time\" car=\"$car\" flags=\"$flags\" gear=\"$gear\" "
           . "spareb=\"$spareB\" speed=\"$speed\" rpm=\"$rpm\" "
           . "turbo=\"$turbo\" engtemp=\"$engtemp\" fuel=\"$fuel\" "
           . "oilpress=\"$oilpress\" spare1=\"$spare1\" spare2=\"$spare2\" "
           . "spare3=\"$spare3\" throttle=\"$throttle\" brake=\"$brake\" "
           . "clutch=\"$clutch\" display1=\"$display1\" "
           . "display2=\"$display2\" id=\"$id\"/>";
    print $f "$s\n";
    print "\r$s";
    close($f);

    open(my $f2, ">", "/tmp/current-file");
    print $f2 (($i++)%5);
    close($f2);
}

12 (edited by germansoccer6113 2009-03-24 15:23:59)

Re: Live For Speed + Chumby ???

(Quickest reply I've ever gotten on a forum.)
Works perfectly. I am definitely writing "learn perl" on my list of things to do.
I'll look at what I'll do with flash and so on when I have more time. (Term paper for school, etc....)
Do you race in LFS at all? Or did you read through all the documentation just to help?
Thanks Again. smile

Edit: Just noticed I also have you to thank for "Lots of stuff for Chumby". The tools have helped me out more than once.

Re: Live For Speed + Chumby ???

I hadn't heard of it before you mentioned it.  But it's fairly well-documented, and seemed like an interesting challenge.

Perl on the Chumby isn't the easiest thing to learn on, mostly because it's missing all of the modules.  If it had the modules, you could do it entirely in perl, without needing netcat.  I think the "Lots of stuff for Chumby" includes a full perl build.  Glad to hear it helped out.

14 (edited by germansoccer6113 2009-04-10 17:10:34)

Re: Live For Speed + Chumby ???

[Sorry to bump?]

http://www.bindows.net/free_gauges/
^ an XML guage powered by javascript.

What I can't figure out is how to get the data (either from perl or directly from netcat) into the javascript that controls the guages. Here is is (in an html):

<html>
    <head>
    <title>Bindows gauge sample</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <!-- Import the bindows gauges javascriptpackage -->
    <script type="text/javascript" src="guage_scripts/bindows_gauges.js"></script>

    </head>
    <body>

    <!-- Create a div to hold the gauge -->
    <div id="gaugeDiv" style="width: 400; height: 400" ></div>

<script type="text/javascript">
    var gauge = bindows.loadGaugeIntoDiv("gauge.xml", "gaugeDiv");

    // dynamically update the gauge at runtime
    var t = 0;
    function updateGauge() {
        t += 100;
        gauge.needle.setValue( 50 + 50 * Math.sin(t/1000) );
    }
    updateGauge();
    setInterval(updateGauge, 100);
</script>
    </body>
    </html>

You can set the gauge needle's value through JavaScript by using gauge.needle.setValue([whatever value])
Is there a way to replace the math that is being used to set the value with dynamic data from netcat (or perl)?

Re: Live For Speed + Chumby ???

You might consider modifying it so that it writes to stdout, and use a named pipe to read the file.  Use the code described here.  Since you'll be getting the data in realtime, you won't have to worry about that whole /tmp/current-file nonsense.  The only issue I could see you running into might be too much data coming in on the named pipe, in which case you might want to have the Perl code throw away every second or third update.

In any case, modify the Perl program so it looks like:

#!/usr/bin/perl -w
my $i=0;
{
    my $h;
    sub get_line {
        if( !defined $h ) {
            open($h, '-|', '/mnt/usb/nc -l -u -p 4000')
#            open($h, '<', 'lfs.bin')
                or die("Couldn't open netcat: $!");
            }
        read($h, $f, 0x60) or die("Couldn't read: $!");
        return $f;
    }
}

$SIG{'TERM'} = sub { exit(); };
my $s;
while(1) {
    my $line = get_line();
    my ($time, $car, $flags, $gear, $spareB, $speed, $rpm, $turbo,
        $engtemp, $fuel, $oilpress, $spare1, $spare2, $spare3, $throttle,
        $brake, $clutch, $display1, $display2, $id)
        = unpack("IA4SccffffffffffffA16A16I", $line);

    $s = "<tag time=\"$time\" car=\"$car\" flags=\"$flags\" gear=\"$gear\" "
           . "spareb=\"$spareB\" speed=\"$speed\" rpm=\"$rpm\" "
           . "turbo=\"$turbo\" engtemp=\"$engtemp\" fuel=\"$fuel\" "
           . "oilpress=\"$oilpress\" spare1=\"$spare1\" spare2=\"$spare2\" "
           . "spare3=\"$spare3\" throttle=\"$throttle\" brake=\"$brake\" "
           . "clutch=\"$clutch\" display1=\"$display1\" "
           . "display2=\"$display2\" id=\"$id\"/>";
    print "<frame>";
    print "$s";
    print "</frame>\n";
}

You'll have the Flash code do something in the constructor (taken from the URL forum posted above):

_pipeOpen = ASnative(5,191);
input = _pipeOpen("perl /mnt/usb/l4s.pl" ,"r"); // Open for Read
 _pipeRead = ASnative(5,193);
//s = _pipeRead( input );
this.myListener = Object();
this.myListener.onEvent = function( status, comments )
{
   if (status == "data")
   {
       trace( "got myListener.DataReceived.onEvent(" + comments + ")" );
       // Parse XML here, using XML object.
   }
   else
   {
       // only data and eof supported
       trace( "status = " + status );
   }
};
ExtendedEvents.DataReceived.addListener( myListener );
_pipeSetInput = ASnative(5,192);
_pipeSetInput( input, "DataReceived" );

Then you'd