PDA

View Full Version : DeviceLink mini example prog



lindyman
05-20-2004, 04:51 AM
OK, I know, I'm a geek, and I can't resist a challenge like this.

This is probably the most minimalistic DeviceLink program possible, but it has the basics from which you can build something.

The program is written to run under Linux (probably any *nix like OS will do, and probably most others as well, as long as they use the posix networking APIs.)

The machine running IL-2 is hardcoded to network address 192.168.1.3. Change that as required.

Before running it, you must enable DeviceLink in IL-2 by adding the below to your conf.ini:

<pre class="ip-ubbcode-code-pre">
[DeviceLink]
IPS=<IP-addr of machine running sample prog>
PORT=10000
</pre>

A sample run is shown below:
<pre class="ip-ubbcode-code-pre">
bash-2.05b$ ./a.out
R/2/22/
response is [26]"A/2\1.00/22\Il-2_1941_Late"
R/40/30/
response is [18]"A/40\1.100/30\0.36"
R/80/
response is [10]"A/80\-1.00"
</pre>

OK, it's nothing fancy, but the communication is there.

The program (with all its bugs and shortcomings, for example it erroneously expects a response from all commands, so if you enter a command without response, it will hang):
<pre class="ip-ubbcode-code-pre">
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>


int main(void)
{
int sock;
struct sockaddr_in other_end;
struct sockaddr_in this_end;

other_end.sin_port = htons(10000);
other_end.sin_addr.s_addr = inet_addr("192.168.1.3");
other_end.sin_family = AF_INET;
memset(&other_end.sin_zero, 0, sizeof(other_end.sin_zero));
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
{
perror("socket failed");
return errno;
}

this_end.sin_port=htons(0);
this_end.sin_addr.s_addr=htons(INADDR_ANY);
this_end.sin_family=AF_INET;
memset(&this_end.sin_zero, 0, sizeof(this_end.sin_zero));
if (bind(sock, &this_end, sizeof(this_end)) < 0)
{
perror("bind");
errno=0;
goto close_sock;
}
for (;;)
{
char buff[128];
size_t len;
if (fgets(buff, sizeof(buff), stdin) < 0) break;
len = strlen(buff);
if (sendto(sock, buff, len, 0, &other_end, sizeof(other_end)) < len)
{
perror("sendto");
errno=0;
break;
}
if (buff[0] == 'R')
{
buff[0]=0;
len = recvfrom(sock, buff, sizeof(buff), 0, NULL, NULL);
if (len < 0)
{
perror("recvfrom");
errno=0;
break;
}
printf("response is [%d]\"%.*s\"\n", len, len, buff);
}
}
close_sock:
if (errno) perror("Leaving");
close(sock);
return errno;
}

</pre>

lindyman
05-20-2004, 04:51 AM
OK, I know, I'm a geek, and I can't resist a challenge like this.

This is probably the most minimalistic DeviceLink program possible, but it has the basics from which you can build something.

The program is written to run under Linux (probably any *nix like OS will do, and probably most others as well, as long as they use the posix networking APIs.)

The machine running IL-2 is hardcoded to network address 192.168.1.3. Change that as required.

Before running it, you must enable DeviceLink in IL-2 by adding the below to your conf.ini:

<pre class="ip-ubbcode-code-pre">
[DeviceLink]
IPS=&lt;IP-addr of machine running sample prog&gt;
PORT=10000
</pre>

A sample run is shown below:
<pre class="ip-ubbcode-code-pre">
bash-2.05b$ ./a.out
R/2/22/
response is [26]"A/2\1.00/22\Il-2_1941_Late"
R/40/30/
response is [18]"A/40\1.100/30\0.36"
R/80/
response is [10]"A/80\-1.00"
</pre>

OK, it's nothing fancy, but the communication is there.

The program (with all its bugs and shortcomings, for example it erroneously expects a response from all commands, so if you enter a command without response, it will hang):
<pre class="ip-ubbcode-code-pre">
#include &lt;sys/types.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;netinet/in.h&gt;
#include &lt;arpa/inet.h&gt;
#include &lt;errno.h&gt;
#include &lt;stdio.h&gt;


int main(void)
{
int sock;
struct sockaddr_in other_end;
struct sockaddr_in this_end;

other_end.sin_port = htons(10000);
other_end.sin_addr.s_addr = inet_addr("192.168.1.3");
other_end.sin_family = AF_INET;
memset(&other_end.sin_zero, 0, sizeof(other_end.sin_zero));
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock &lt; 0)
{
perror("socket failed");
return errno;
}

this_end.sin_port=htons(0);
this_end.sin_addr.s_addr=htons(INADDR_ANY);
this_end.sin_family=AF_INET;
memset(&this_end.sin_zero, 0, sizeof(this_end.sin_zero));
if (bind(sock, &this_end, sizeof(this_end)) &lt; 0)
{
perror("bind");
errno=0;
goto close_sock;
}
for (;;)
{
char buff[128];
size_t len;
if (fgets(buff, sizeof(buff), stdin) &lt; 0) break;
len = strlen(buff);
if (sendto(sock, buff, len, 0, &other_end, sizeof(other_end)) &lt; len)
{
perror("sendto");
errno=0;
break;
}
if (buff[0] == 'R')
{
buff[0]=0;
len = recvfrom(sock, buff, sizeof(buff), 0, NULL, NULL);
if (len &lt; 0)
{
perror("recvfrom");
errno=0;
break;
}
printf("response is [%d]\"%.*s\"\n", len, len, buff);
}
}
close_sock:
if (errno) perror("Leaving");
close(sock);
return errno;
}

</pre>

lindyman
05-20-2004, 05:07 AM
BTW, there seems to be a small bug in DeviceLink. Set commands seem impossible to combine, or the syntax for doing so is different from what the docs say.

I can combine as many get commands as I feel like in one line, while I have only managed with single set commands, never sets combined with other sets or with gets. Ironically, this means that the very example posted in devicelink.txt, does not work, since it combines the query of altitude with the setting of power.

Also... I guess this is the way things are usually done in the IP world, but having string commands/responses that must be generated and parsed in both ends, instead of binary packets that are just interpreted from packet start, offset and field-size, seems like a waste of CPU cycles and latency. Although, admittedly, it makes it easier to test it with a simple program like the above.
_
/Bjorn.

lindyman
05-20-2004, 05:28 AM
Further testing...

It seems like I cannot combine commands which takes paremeters with any other commands, or rather that no command can follow after one which takes parameters. As long as the one requiring a parameter is the last one, then it's OK.

Unfortunately there are also some gets which require parameters (for exampple, the engine status gauges have an engine ID as its parameter.)

Seems like there's a problem with knowing when the parameter ends and the next command begins. A / or \ or space is not it, however.
_
/Bjorn.

Bandit.426Cdn
05-20-2004, 02:48 PM
So, umm, err.. nice coding for your example program to demonstrate devicelink, but for us that are clueless and lost our propeller beanies, what exactly does it do?? i look at it, and can only boggle.. the lights are on, but nobody is home, comprehension wise...

gombal40
05-20-2004, 03:20 PM
http://ubbxforums.ubi.com/images/smiley/351.gif

BaldieJr
05-20-2004, 03:31 PM
bah. i have to run, cant test. promised in-laws dinner...

possible \ escaping? just a thought.

<pre class="ip-ubbcode-code-pre">
My Specs (read 'em and weep):
* Automatically grinds whole beans before brewing
* Fully programmable 24 hours in advance
* Brew Pause feature lets you enjoy a cup before brewing has finished
* Automatically shuts off when brewing is complete
* Grind-off feature for brewing ground coffee
* 1-4 cup feature to accommodate coffee for one
* 10-cup double-wall insulated thermal carafe to keep your coffee hot long after brewing
* Gold tone commercial-style permanent filter eliminates the need to buy coffee filters
* Charcoal water filter removes impurities from the water
* Separate grinder chamber and filter area allow for easy cleanup
* Limited 3-year warranty
</pre>

GT182
05-20-2004, 05:21 PM
BaldieJr, too bad yer device program is AI only. http://ubbxforums.ubi.com/images/smiley/88.gif http://ubbxforums.ubi.com/images/smiley/16x16_smiley-wink.gif

"GT182" / "vonSpinmeister"
www.bombs-away.net (http://www.bombs-away.net)
"Fly to Survive, Survive to Fly"

BaldieJr
05-20-2004, 07:35 PM
You gotta check and make sure something isn't stripping \'s from yout input (i barely read compiled languanges, but i've been down this road lots of times with interpreted stuff and sockets).

I did:
R/40/401/81\1/80

with a one-shot write in lua. Results:
A/40\47.56/80\1.00

Auto pilot (401) was turned off and power went to max (1- the example is porked, you only get -1.00 thru 1.00.

I'm going to pound out a few longer examples and will post results here, but it appears to be working.

<pre class="ip-ubbcode-code-pre">
My Specs (read 'em and weep):
* Automatically grinds whole beans before brewing
* Fully programmable 24 hours in advance
* Brew Pause feature lets you enjoy a cup before brewing has finished
* Automatically shuts off when brewing is complete
* Grind-off feature for brewing ground coffee
* 1-4 cup feature to accommodate coffee for one
* 10-cup double-wall insulated thermal carafe to keep your coffee hot long after brewing
* Gold tone commercial-style permanent filter eliminates the need to buy coffee filters
* Charcoal water filter removes impurities from the water
* Separate grinder chamber and filter area allow for easy cleanup
* Limited 3-year warranty
</pre>

BaldieJr
05-20-2004, 08:22 PM
Yuk. Buggy.

You can't set multiple params that require a value. You can only set non-value keys (auto pilots and lights etc).

Some of these dont return thier states, like cockpit lights, which kinda makes it no fun... i cant check the state of the cockpit lights and set hardware to its value? oh well.

I'm wondering if setting axis values has to be independant of a get. I'll try it.

<pre class="ip-ubbcode-code-pre">
My Specs (read 'em and weep):
* Automatically grinds whole beans before brewing
* Fully programmable 24 hours in advance
* Brew Pause feature lets you enjoy a cup before brewing has finished
* Automatically shuts off when brewing is complete
* Grind-off feature for brewing ground coffee
* 1-4 cup feature to accommodate coffee for one
* 10-cup double-wall insulated thermal carafe to keep your coffee hot long after brewing
* Gold tone commercial-style permanent filter eliminates the need to buy coffee filters
* Charcoal water filter removes impurities from the water
* Separate grinder chamber and filter area allow for easy cleanup
* Limited 3-year warranty
</pre>

BaldieJr
05-20-2004, 09:08 PM
Blah. Axis writes dont work. Maybe they need to be deleted in conf. or something.

You can set/get anything in any order, you just cant send axis controls for some reason.

If "drawifnotfocused" is 1 in conf.ini, you can alt+tab windows (test 640x480) and use this:

R/323/324/327/329/331/333/335/337/339/341/343/345/347/80/86/92

view will zoom quick and you'll get power/elevator/prop settings.

We need axis control. I think i could live with everything else, but i really wanted to push axis data directly into the game because of the power it allows script-wise and a net-work trainer might be possible http://ubbxforums.ubi.com/images/smiley/16x16_smiley-wink.gif

<pre class="ip-ubbcode-code-pre">
My Specs (read 'em and weep):
* Automatically grinds whole beans before brewing
* Fully programmable 24 hours in advance
* Brew Pause feature lets you enjoy a cup before brewing has finished
* Automatically shuts off when brewing is complete
* Grind-off feature for brewing ground coffee
* 1-4 cup feature to accommodate coffee for one
* 10-cup double-wall insulated thermal carafe to keep your coffee hot long after brewing
* Gold tone commercial-style permanent filter eliminates the need to buy coffee filters
* Charcoal water filter removes impurities from the water
* Separate grinder chamber and filter area allow for easy cleanup
* Limited 3-year warranty
</pre>

lindyman
05-21-2004, 01:14 AM
<BLOCKQUOTE class="ip-ubbcode-quote"><font size="-1">quote:</font><HR>Originally posted by BaldieJr:
You can't set multiple params that require a value. You can only set non-value keys (auto pilots and lights etc).
<HR></BLOCKQUOTE>

Yes, that's a bummer.

<BLOCKQUOTE class="ip-ubbcode-quote"><font size="-1">quote:</font><HR>Originally posted by BaldieJr:
Some of these dont return thier states, like cockpit lights, which kinda makes it no fun... i cant check the state of the cockpit lights and set hardware to its value? oh well.
<HR></BLOCKQUOTE>

I think what you have to do, is what I've done in a slight refinement of the above program, for a start of a simple autopilot. In that one, I've separated the request from the response. What I mean with that, is that the program is always prepared to handle a response, if one turns up, but does never require one. This is not really a problem, since all responses contain the key telling what the value means. To achieve this, use poll() or select() on the socket.

For me, time for phase 3 in development now. The level stabiliser autopilot, that will control the aileron only.

Once that is working, it's yaw stabiliser and altitude hold, and then I can go on testing stall speeds!
_
/Bjorn.

lindyman
05-21-2004, 04:37 AM
Wingleveler autopilot is there, and working quite well.

It feels familiar. When I took my PPL a few years ago, I had an interesting situation. This was my 2nd solo flight, and after a few touch and go's, I briefly left the airfield. Upon returning I went through the checklist for approach, which includes verifying that the autopilot is off. This I did by touching the two buttons on it with my fingers, and check that they are in the off position. A minute later it was time to turn towards the traffic circuit, and the yoke wouldn't move. Quick check on all other control surfaces, and all was well. A few tests on turning with rudder only, and it worked rather nicely. Unfortunately it never struck me that it could be the autopilot, had it done that, I would've turned electricity off and see if it made a change (now I know.) Well there was almost no wind, and what little there was, was pretty perfectly aligned with the runway, so I decided to go in. No sharply marked downwind/base/final leg, rather a combined curve, with plenty of space for the final. Landing was good, and rather shaken I taxied to the apron. Turned everything off, and felt that the ailerons moved just fine.

Anyway, I've started on the sideslip stabilising, and it's trickier than I thought. The different planes have to very different rudder response, that what works for one, makes another oscillate and a third never really get it centered.

I guess it's possible to make the parameters for the control system adaptive, but that's above my skills, I'm afraid. Control systems wasn't my big thing, and I very nearly flunked the course.

However, with a plane where the sideslip stabilizer works, I've managed with something as odd as stalling a plane over its nose. I've never managed to do that in AEP manually, but here, I pulled and pulled on the elevator until the plane could fly no more, and down the nose went, not a wingtip.

Gotta fiddle a bit more with the rudder control, and then start working on the altitude hold.
_
/Bjorn.

BaldieJr
05-21-2004, 06:44 AM
http://ubbxforums.ubi.com/images/smiley/16x16_smiley-happy.gif

I came to the same conclusion last night: set one keys' value per write, and be sure to tack it to the end of the packet.

For my cockpit project, I was really hoping to poll more keys.. since I plan to use LED's as indicators for things like lights, smoke, and other oddities. Luckily, mags, wep, superchargers, and such all give up thier state.

Oh if only I could watch ammo stores http://ubbxforums.ubi.com/infopop/emoticons/icon_smile.gif

This stuff is mad fun.

<pre class="ip-ubbcode-code-pre">
My Specs (read 'em and weep):
* Automatically grinds whole beans before brewing
* Fully programmable 24 hours in advance
* Brew Pause feature lets you enjoy a cup before brewing has finished
* Automatically shuts off when brewing is complete
* Grind-off feature for brewing ground coffee
* 1-4 cup feature to accommodate coffee for one
* 10-cup double-wall insulated thermal carafe to keep your coffee hot long after brewing
* Gold tone commercial-style permanent filter eliminates the need to buy coffee filters
* Charcoal water filter removes impurities from the water
* Separate grinder chamber and filter area allow for easy cleanup
* Limited 3-year warranty
</pre>

WWSensei
05-21-2004, 06:56 AM
Argh, not getting the state is going to be a pita for proper setting of the LEDs on the GoFlight modules...

BaldieJr
05-21-2004, 08:27 AM
<BLOCKQUOTE class="ip-ubbcode-quote"><font size="-1">quote:</font><HR>Originally posted by WWSensei:
Argh, not getting the state is going to be a pita for proper setting of the LEDs on the GoFlight modules...<HR></BLOCKQUOTE>

some give up state, some don't. It just depends on the key you're dealing with.

Most of the important stuff does give up its state. Its those little things like lights/smoke that don't.

<pre class="ip-ubbcode-code-pre">
My Specs (read 'em and weep):
* Automatically grinds whole beans before brewing
* Fully programmable 24 hours in advance
* Brew Pause feature lets you enjoy a cup before brewing has finished
* Automatically shuts off when brewing is complete
* Grind-off feature for brewing ground coffee
* 1-4 cup feature to accommodate coffee for one
* 10-cup double-wall insulated thermal carafe to keep your coffee hot long after brewing
* Gold tone commercial-style permanent filter eliminates the need to buy coffee filters
* Charcoal water filter removes impurities from the water
* Separate grinder chamber and filter area allow for easy cleanup
* Limited 3-year warranty
</pre>

WWSensei
06-09-2004, 05:53 AM
Yeah, in my wrapper class I'm storing the state as a priv variable but if the player changes via keyboard then my GoFlight module gets out of sync.

Found one annoyingly missing state command though....effin' FLAPS! The flap axis get(82) is broken (it returns the power axis ARRRGGHH) and there is no simple command for getting whether flaps are in combat, landing or take off. Consequently, there is no set either! Could have been a simple +1/-1 flaps setting offerred.

I've made the request via the bug report email. I was told the flaps axis thing is "fixed in patch" which implies there is another patch coming...

So close...so close...

BBB_Hyperion
06-09-2004, 08:23 AM
BTW what FPS rates do you guys get when you run full speed interface without delay ?

I get only 5 fps then . With timer and 50 ms delay its 51 fps with data showing over Il2fb device context.

Without any app 57 fps on average.

This Interface can go hard on resources if you want really direct control.

Regards,
Hyperion

WWSensei
06-09-2004, 10:57 AM
Not an issue for me at present since I'm only doing stuff for GoFlight modules. I don't query unless you flip a switch or twist a knob.

However, it would go easier if 1C changed the interface to send real data rather than a string. Most of the data could be encapsulated in a single 32 bit integer needing only 4 bytes rather than the 12-20 bytes it needs now...

BBB_Hyperion
06-09-2004, 12:26 PM
I use it for recording flight data thats why a autopilot working on a 50 ms basis is acceptable in some areas while on others a higher density is needed. Thats why i tested the limits of the interface.

Regards,
Hyperion

gflinch
06-09-2004, 03:49 PM
sorry to just jump in here been observing for a while. In reading you guys comments on the interface, pretty much any future of implementing direct control like a throttle or something that need immedate reponse will not work (or just react slow).

Am I correct?

Greg

WWSensei
06-09-2004, 07:14 PM
I think given the limited command set and the inefficient communications mechanism any idea for an elaborate "super-program" is pretty much out of the question. I've seen some people thinking a "hack" could be done using this interface but in its current state anyone using such a program would do more harm than good.

It has some usefulness in small apps like the autopilot or in using some external hardware like simkits or goflight but they need to improve it tremendously before it could used effectly for something like mutli-quad throttles etc...

BBB_Hyperion
06-09-2004, 11:54 PM
Even when we ignore the response time problem the main problem of external hardware support consist.

Maybe a workaround would be coding a dummy driver that simulates a throttle or stick on usb interface. Question is does il2fb support multiple input devices ?

Regards,
Hyperion

gflinch
06-10-2004, 06:02 AM
No, well, it only supports something like 4-5 axis at most. And the throttle is botched for working with anything more than a keyboard on a multi-engin plane. [read keyboard layout for further info] It only accepts input from one throttle at a time (using one joystick axis) so something like the CHTrottle Quad is out unless they open up more Axis inputs. This is one little area that I was hopeing that would be fix/added to in 2.01. Heard it was possible to do from Oleg and co.

Greg