Board index FlightGear Development

[closed] Flightgear plotter updated.

FlightGear is opensource, so you can be the developer. In the need for help on anything? We are here to help you.
Forum rules
Core development is discussed on the official FlightGear-Devel development mailing list.

Bugs can be reported in the bug tracker.

Re: Flightgear plotter updated.

Postby Hooray » Sat May 25, 2013 4:56 pm

I am not sure I understand what you're saying:
do you mean some FDM/autopilot-specific "debug" properties that are not generally accessible ?
If that's the case, they should definitely be made available through the property tree.

Could you provide an example that's easy to reproduce ?

EDIT: Assuming you are referring to the AP: http://wiki.flightgear.org/Autopilot_Co ... ence#Debug
It seems you are right, the autopilot's debug mode only writes to the console - but that should be simple to change if you can build from source, and it would seem like a good idea in my opinion, you should probably file a feature request: http://code.google.com/p/flightgear-bug ... %20request

https://gitorious.org/fg/flightgear/tre ... /Autopilot
Code: Select all
component.cxx:33:  _debug(false),
component.cxx:68:  if ( nodeName == "debug" ) {
component.cxx:69:    _debug = configNode->getBoolValue();
digitalfilter.cxx:430:  if(_debug) {
flipflop.cxx:464:    if(_debug) {
pidcontroller.cxx:123:        if( _debug ) cout <<  "Updating " << get_name()
pidcontroller.cxx:129:        if ( _debug ) cout << "  input = " << y_n << " ref = " << r_n << endl;
pidcontroller.cxx:133:        if ( _debug ) cout << "  ep_n = " << ep_n;
pidcontroller.cxx:134:        if ( _debug ) cout << "  ep_n_1 = " << ep_n_1;
pidcontroller.cxx:138:        if ( _debug ) cout << " e_n = " << e_n;
pidcontroller.cxx:145:            if ( _debug ) cout << " ed_n = " << ed_n;
pidcontroller.cxx:149:            if ( _debug ) cout << " Tf = " << Tf;
pidcontroller.cxx:154:            if ( _debug ) cout << " edf_n = " << edf_n;
pidcontroller.cxx:167:          if ( _debug ) {
pidcontroller.cxx:179:            if ( _debug ) cout << " max saturation " << endl;
pidcontroller.cxx:182:            if ( _debug ) cout << " min saturation " << endl;
pidcontroller.cxx:187:        if ( _debug ) cout << "  output = " << u_n << endl;
pisimplecontroller.cxx:67:    if ( _debug ) cout << "Updating " << get_name() << endl;
pisimplecontroller.cxx:72:    if ( _debug ) cout << "input = " << y_n
pisimplecontroller.cxx:86:    if ( _debug ) cout << "prop_comp = " << prop_comp
pisimplecontroller.cxx:90:    if ( _debug ) cout << "output = " << clamped_output << endl;


Another issue is that the code uses std::cout directly and not the SG_LOG() mechanism. I would usggest to turn the debug variables into property objects and expose them via the property tree if enabled: http://wiki.flightgear.org/Howto:Use_Pr ... ee_Objects
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Flightgear plotter updated.

Postby kuifje09 » Sat May 25, 2013 8:26 pm

Hello Hooray, thanks again. I know t is possible to recompile flightgear to get those debug vars somewhere else.. I previously recompiled to get thos debug vars in some http format, Then the plotting routine read those and plotted a graph. That routine or better, program, was written in pyton I think.
Rather good, but to much steps to get to the graphs. Thas why I wrote the fgplot in xlib / motif. But for windows users they should have installed cygwin.
Not sure if it would work nicely then...

But to get back to my issue. The values getting into my fgplot-module is an issue. But I encounter another problem.
Maybe better to solve that first.
I wrote this little piece of code to plot a sine and a cosine, continuesly. But it slows fg down gradualy but continuesly.
from 12 fps to a standstill at the end. It plots very nicely but slows down, down down ....

When I stop ( via button ) framerate is back, then continue plotting, framerate drops instantly.

<off-topic> very sad fg is not multithreated, it runs on only 1 core on my dualcore </off-topic>

Code: Select all
var p = (2*math.pi)/360;
# var y = [] ; does not work ?
var y0 = 0;
var y1 = 0;
var x0 = 0;
var i = 0;
var dotPlot = func () {
   plot1.setColor(1,0.5,0.8);
   var y0 = math.sin(x0*p)*100+151;
   plot1.lineTo(i,y0);
   plot2.setColor(0,0.5,1.0);
   var y1 = math.cos(x0*p)*100+151;
   plot2.lineTo(i,y1);
   i+=1;
   x0+=1;
   if(x0>360)x0=0;
   clearsq(i+5);
   if( i >= 850 ){
     i=0;
     plot1.moveTo(i,y0);
     plot2.moveTo(i,y1);
   };
   # This routine should be looping while running is active.
   # But it may not becoming active in itself.
   # It must be restarted from "outside"
   if(getprop("/gui/fgplot/running") == 1)settimer(dotPlot,0.1) ;
   #settimer(dotPlot,0.1) ;
};

It does look alike the timer is not removed after it ran off, and I get every time a timer running extra, or the plotted line is replotted from the beginning each time I plot another point. ( You get what I mean ? )
I have a wrong assumption of how something works I think.?
kuifje09
 
Posts: 596
Joined: Tue May 17, 2011 9:51 pm

Re: Flightgear plotter updated.

Postby Hooray » Sat May 25, 2013 9:09 pm

I encounter another problem. Maybe better to solve that first.

I agree, changing the code to provide these debug values as properties would not be difficult - but the first step is definitely getting a graph working and coming up with a plotting widget that can be easily reused.

So can you please provide a complete, self-contained example that we can easily run and test - in order to reproduce the issue ?
Just upload your "fgplot.xml" somewhere, so that we can have a look - or post it here.

In the meantime, what you describe sounds like indeed you may have multiple timer instances running - to check if that's the case, either add a simple "print" statement to the top of your function, or increment/decrement a counter to see how often the function is running.

If there's only a single instance running, it's possible that your plotting routine needs to be optimized a little. We saw that when working with the airport-selection dialog and drawing the taxiways, which took more than 10 seconds for KNUQ at first - but which is now reasonably fast.

To see what the problem is, we need to look at your code and be able to reproduce the issue.

To prevent multiple loop instances, see: http://wiki.flightgear.org/Nasal_Loops#Loop_Identifiers
If you are running the latest code from git, you can also use the new maketimer() API instead: http://wiki.flightgear.org/List_of_Nasa ... 2.11.2B.29

very sad fg is not multithreated, it runs on only 1 core on my dualcore

While the main loop is indeed single-threaded, there are a bunch of systems that do make use of additional cores, see: http://wiki.flightgear.org/Howto:Activa ... PU_support

You can also run certain Nasal computations asynchronously using Nasal's "thread.newthread()" API: http://plausible.org/nasal/lib.html
However, care must be taken not to call ANY of the standard extension functions - i.e. ALL the FG APIs, including property tree access through getprop/setprop, props.nas etc.

The canvas itself is single-threaded currently, but we once talked about using OSG's multithreading support to update textures independently, and not just sequentially, while groups and nested canvases would still need to be updated in a serialized fashion, other groups and canvases could be updated in parallel.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Flightgear plotter updated.

Postby kuifje09 » Sun May 26, 2013 8:38 pm

Alright, did some readings and a few other tests, but no idea of what I do wrong.
This is an example code.
Code: Select all
<?xml version="1.0"?>
<!--

add to $FGHOME/Translations/en/menu.xml
direct under
<equipment>Equipment</equipment>

  <fgplot>Fgplot</fgplot>

add to $FGHOME/gui/menubar.xml
direct under
<name>equipment</name>

<item>
  <name>fgplot</name>
    <binding>
      <command>dialog-show</command>
         <dialog-name>fgplot</dialog-name>
    </binding>
<item>

Now you can choose from menubar in equipment fgplot.
-->

<PropertyList>
  <name>fgplot</name>
  <modal>false</modal>
  <!--layout>hbox</layout-->
  <resizable>false</resizable>
  <x>0</x> <!-- x runs to right -->
  <y>0</y> <!-- y runs to up -->
  <width>870</width>
  <height>310</height>
 
  <group>

    <!-- space for the butons and labels and the canvas -->
    <layout>hbox</layout>
    <!--halign>fill</halign-->
    <default-padding>5</default-padding>
    <!--empty><stretch>true</stretch></empty-->
 
    <text>
      <label>fgplot</label>
        <x>0</x>
        <y>280</y>
        <width>5</width>
        <height>25</height>
    </text>
 
    <button>
      <legend>></legend>
      <!--equal>true</equal-->
      <x>50</x>
      <y>285</y>
      <width>15</width>
      <height>15</height>
      <binding>
        <command>nasal</command>
           <script><![CDATA[
              var a = getprop("/gui/fgplot/running") or 0;
              if(a == 0){
                 setProps();
                 setprop("/gui/fgplot/running",1);
                 dotPlot();
              };]]>
           </script>
      </binding>
    </button>

    <button>
      <legend>-</legend>
      <!--equal>true</equal-->
      <x>70</x>
      <y>285</y>
      <width>15</width>
      <height>15</height>
      <binding>
        <command>nasal</command>
          <script>setprop("/gui/fgplot/running",0);</script>
      </binding>
    </button>

    <button>
      <legend>X</legend>
      <!--equal>true</equal-->
      <x>90</x>
      <y>285</y>
      <width>15</width>
      <height>15</height>
      <key>Esc</key>
      <binding>
        <command>nasal</command>
          <script>setprop("/gui/fgplot/running",0);</script>
      </binding>
      <binding>
        <command>dialog-close</command>
      </binding>
    </button>

  <canvas>
    <name>fgplot</name>
    <x>110</x> <!-- save space for buttons on the left -->
    <!--valign>fill</valign-->
    <!--halign>fill</halign-->
    <!--stretch>true</stretch-->
    <width>750</width>
    <height>301</height>
        <color>
                <alpha>0.5</alpha>
                <red>0.5</red>
                <green>0.5</green>
                <blue>0.5</blue>
        </color>

<!-- all the nasal coding belonging to canvas below -->
<nasal>     

   <open>
      setProps(); <!-- open does not respond ? -->
   </open>        <!-- props are set while start == >  is pressed -->

   <close>
   </close>


<load> <!-- when the fgplot is loaded == pressed equipment->fgplot -->
<![CDATA[

# you can add your canvas-specific code here
var my_canvas = canvas.get( cmdarg() ); # this will get a handle to the parent canvas:
 
var root = my_canvas.createGroup();

var graph = root.createChild("group");
 
var x_axis = graph.createChild("path", "x-axis")
.moveTo(0, 151)
.lineTo(850, 151)
.setColor(0.8,0.8,0.8)
.setStrokeLineWidth(1);
 
var y_axis = graph.createChild("path", "y-axis")
.moveTo(1, 0)
.lineTo(1, 301)
.setColor(0.8,0.8,0.8)
.setStrokeLineWidth(1);
 
var clearsq = func (i) {
   var tmp = graph.createChild("path", "data")
      .setStrokeLineWidth(1)
      .moveTo(i,0)
      .lineTo(i+5,0)
      .lineTo(i+5,301)
      .lineTo(i,301)
      .lineTo(i,0)
      .setColorFill(0,0,0)
      .close();
   var tmp = graph.createChild("path", "data")
      .setColor(0.8,0.8,0.8)
      .moveTo(i, 151)
      .lineTo(i+5, 151)
      .close();
};

var startover = func (s) {
   settimer(dotPlot(s),1);
};
 

var p = (2*math.pi)/360;
var y0 = 151;
var y1 = 151;
var x0 = 0;
var i = 0;
var dotPlot = func () {
   var plot1 = graph.createChild("path", "data");
   var plot2 = graph.createChild("path", "data");
# For debugging
#   print("i=",i," y0=",y0," y1=",y1);
   plot1.setColor(1,0.5,0.8);
   plot2.setColor(0,0.5,1.0);
   plot1.moveTo(i,y0);
   plot2.moveTo(i,y1);
   # this is|should be an external var
   # but its value is last after stop/start
   y0 = math.sin(x0*p)*100+151;
   y1 = math.cos(x0*p)*100+151;
   i+=1;
   plot1.lineTo(i,y0);
   plot2.lineTo(i,y1);
   plot1.close();
   plot2.close();
   x0+=1;
   if(x0>360)x0=0;
   if( i >= 850 ){
     i=0;
   };
   clearsq(i+1);
   # This routine should be looping while running is active.
   # But it may not becoming active in itself.
   # It must be restarted from "outside"
   if(getprop("/gui/fgplot/running") == 1)settimer(func{dotPlot()},0.01);
};

var setProps = func () {
   setprop("/gui/fgplot/transparent",0);
   setprop("/gui/fgplot/P-value",1);
   setprop("/gui/fgplot/I-value",1);
   setprop("/gui/fgplot/D-value",1);
   setprop("/gui/fgplot/In-value",1);
   setprop("/gui/fgplot/Ref-value",1);
   setprop("/gui/fgplot/Out-value",1);
   setprop("/gui/fgplot/running",0);
   setprop("/gui/fgplot/plot",0);
   print("Properties set");
   gui.popupTip("Properties set",3);
};

 
]]>
</load>
</nasal>
</canvas>
 
    <!--empty><stretch>true</stretch></empty-->
  </group>
</PropertyList>

This should be a part of the image of fgplot http://kuifje09.dyndns.org/_pics/FGplot.png
Image
kuifje09
 
Posts: 596
Joined: Tue May 17, 2011 9:51 pm

Re: Flightgear plotter updated.

Postby Hooray » Mon May 27, 2013 5:54 am

Image

I have briefly tested your fgplot dialog, your plotter works nicely here, and there don't seem to be multiple instances of the plotting loop (which is good!) - and yes, it is pretty slow. But that can surely be optimized (it is not even as slow as the taxiways at KNUQ used to be).
  • look at the resolution of the canvas and your view
  • look at the resolution of the data you are drawing (using *lines* for points)
  • then open the property browser and see all the lineTo paths added there (>=5000)
  • look at $FG_ROOT/Nasal/canvas/api.nas +600 for more suitable drawing primitives (change drawing granularity accordingly, i.e. sub pixel stuff probably isn't optimized away by the canvas, so just discard it yourself - Tom can probably tell you the lowest hanging fruits, or the C++ code would have to do some optimizations)
  • try to reduce the overhead of your plot() routine: (i.e. you are currently creating and closing two paths per call)
  • you are doing all the computations manually in Nasal, and don't seem to be using any canvas support for translating the image ?

You can benchmark your results using the built-in profiler: http://wiki.flightgear.org/Built-in_Profiler
Initial results can be also obtained by using Nasal's debug.benchmark() and the built-in system monitor (under debug).

I am sure that we will be able to optimize this further. Tom has developed a pretty powerful system here, and optimizing things will be also be useful for other efforts, like instruments, HUDs or the GUI.

In general, I would also stop drawing things step by step, and instead use Nasal classes for various elements and inheritance (axis, graph, plottable) - that way, you will directly be able to instantiate an arbitrary number of graphs, without any manual work. So we just need a simple plotting widget.

And again: I would suggest to use the Canvas subforum - most people will not expect this thread to be about the canvas :D
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Flightgear plotter updated.

Postby kuifje09 » Mon May 27, 2013 1:37 pm

Hi Hooray, Maybe I will stat this fgplot topic in a new thread in canvas. Seems a good idea.

On your findings :
"look at the resolution" flightgear is a virtual resulution system, it is considdered 1024x800 as I read somewhere.
So all resolutions I choose are converted somewhere? I think I don't understand what you try to say.
EDIT: There is indeed some strange behavior. I choose the right sizes ( just played a bit with height and width an x and y for the canvas ) but it never gets the sizes I expected. It is always a little more height and width. Easly seen when you chang the calulation value for Sin ans Cos from 100 to 150.
Which should perfectly fill-out the whole canvas but does not.

"property browser and >5000" First I cannot find the lineTo path in the tree... But that amount of paths is growing all the time I think? Might that be the problem drawing gets slower the more lines I have drawn. While I am thinking to draw just to pieces of 2 lines ( good become 6 lines ) a time.
So the number should be only 2 ( or 6 later on ) . That makes me indeed think the the graph is redrawn internaly each time. And that want work !

"the overhead of your plot() " I had also a version with the create and close outside the "loop" but that makes no difference at all.
It is just the more lines-points, the slower it becomes.

"canvas support for translating the image" Thats is all new for me and I have to study a bit to get familiar. But this is just about 2 lines ?

"I would also stop drawing things step by step" After this "proof of concept" is working the autopilot values will enter the graph for 6 line-points at a time. So it must work step by step.

Thanks anyway, I will see what I can find in the other "examples"
kuifje09
 
Posts: 596
Joined: Tue May 17, 2011 9:51 pm

Re: Flightgear plotter updated.

Postby Hooray » Mon May 27, 2013 2:07 pm

Don't worry about the current performance, your code is currently not at all optimized - we can certainly optimize the implementation. Like I said previously, the taxiways at KNUQ were MUCH worse, and it took only a couple of weeks to do some research, talk about possible optimizations and Tom quickly came up with some pretty good optimizations. So for now, I would suggest to improve the current implementation, and generalize it (using Nasal/OOP, i.e. a handful of classes to come up with the building blocks for a plotting widget). Next, we can do some real profiling using the profiling fgcommands, and then check if there are any low-hanging fruits.
Plotting a graph is going to be one of the simpler use-cases for the canvas, it will have to deal with much more sophisticated stuff, so it's a pretty safe bet to continue your work using the canvas.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Flightgear plotter updated.

Postby kuifje09 » Sat Jun 15, 2013 9:42 pm

For the continuing story, now fully xml/nasal. follow the link below.
[url]
viewtopic.php?f=71&t=20024&start=15
[/url]
kuifje09
 
Posts: 596
Joined: Tue May 17, 2011 9:51 pm

Previous

Return to Development

Who is online

Users browsing this forum: No registered users and 9 guests