<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.flightgear.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=ThomasS</id>
	<title>FlightGear wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.flightgear.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=ThomasS"/>
	<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/Special:Contributions/ThomasS"/>
	<updated>2026-05-09T08:04:21Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.6</generator>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Flughafen_K%C3%B6ln/Bonn&amp;diff=117729</id>
		<title>Flughafen Köln/Bonn</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Flughafen_K%C3%B6ln/Bonn&amp;diff=117729"/>
		<updated>2019-04-03T15:08:08Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* EDDK in the scenery objects database */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
{{infobox Airport&lt;br /&gt;
|name = Flughafen Köln / Bonn&lt;br /&gt;
|image = Fgfs-screen-002.png&lt;br /&gt;
|iata = CGN&lt;br /&gt;
|icao = EDDK&lt;br /&gt;
|type = Public&lt;br /&gt;
|city = Köln-Wahn&lt;br /&gt;
|scenerytile = &lt;br /&gt;
|runway= 06/24&lt;br /&gt;
|length= 2459 m &lt;br /&gt;
|material= Concrete/Asphalt &lt;br /&gt;
|runway2= 14R/32L&lt;br /&gt;
|length2= 1863 m&lt;br /&gt;
|material2= Concrete/Asphalt &lt;br /&gt;
|runway3= 14L/32R&lt;br /&gt;
|length3= 3815 m &lt;br /&gt;
|material3= Asphalt &lt;br /&gt;
|website = http://www.koeln-bonn-airport.de/index.php?lang=2&lt;br /&gt;
}}&lt;br /&gt;
'''Flughafen Köln / Bonn''' also known as '''Konrad Adenauer Airport''' is the airport serving Cologne and Bonn in Germany. It is the seventh largest airport in Germany and the second largest in terms of cargo operations. In FlightGear, it is very nicely modelled, with an 850 layout and terminal models, and more!The airport is one of the few 24 hour airports in Germany.&lt;br /&gt;
&lt;br /&gt;
== Custom Scenery (work in progress, Feb 2017) ==&lt;br /&gt;
https://github.com/mherweg/EDDK-fg-CustomScenery&lt;br /&gt;
http://www.23hq.com/laserman/album/28479990&lt;br /&gt;
&lt;br /&gt;
== Live Webcams ==&lt;br /&gt;
http://www.koeln-bonn-airport.de/nc/de/am-airport/airport-webcam.html?sword_list%5B0%5D=webcam&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Facilities ==&lt;br /&gt;
Köln / Bonn has two terminals directly beside each other and three runways: &lt;br /&gt;
=== Terminal One ===&lt;br /&gt;
Terminal One is the original 197s building, in the shape of a U with two star-shaped piers, B and C. There are 13 gates, of which ten have air bridges, and several remote stands. Germanwings, Lufthansa, and Austrian Airlines use Terminal One.&lt;br /&gt;
=== Terminal Two ===&lt;br /&gt;
Terminal Two is the newer terminal, to the north of Terminal One. It is a rectangular building designated as Pier D, with 8 air bridges and several remote stands. Airlines ther than Terminal One airlines use it.&lt;br /&gt;
=== Runway 06/24 ===&lt;br /&gt;
Runway 06/24 is 2459 m (8,068 ft) long and has a width of 45 m.&lt;br /&gt;
&lt;br /&gt;
=== Runway 14R/32L ===&lt;br /&gt;
&lt;br /&gt;
Runway 14R/32L is 1863 (6,112 ft) long and has a width of 45 m.&lt;br /&gt;
&lt;br /&gt;
=== Runway 14L/32R ===&lt;br /&gt;
&lt;br /&gt;
Runway 14L/32R is 3815 (12,516 ft) long and has a width of 60 m.&lt;br /&gt;
&lt;br /&gt;
== EDDK in the scenery objects database ==&lt;br /&gt;
As mentioned above user laserman created a nice custom scenery for EDDK. Some parts of that scenery found their way into the scenery object database and replaced existing generic buildings. So these will also be available for users not aware of the custom scenery. This is a documentation of those objects. The history of the EDDK custom scenery is available at the  [https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=31646 forum].&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Building !! Model Id !! Model file !! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| Terminal 1 ||  #3474621 || EDDK-Terminal1.xml || Texturing of some parts is still missing. Center of the model is the OSM line &amp;quot;Kaffee-Filter&amp;quot; (218043449), which is object &amp;quot;Vorfeldkontrolle&amp;quot; in the AC3D file.&lt;br /&gt;
|-&lt;br /&gt;
| Terminal 2 || || EDDK-Terminal2.ac || Uses a copy of the Terminal1 texture file. The correct object location (50.880773, 7.119698) appears to be too far into the grass on apron D, but it complies to its OSM location. The EDDK terrain of apron D apparently is not correct. Meanwhile it was moved completely to the grass for getting it out of the way to the old T2. This situation is waiting for someone with a good idea for solving it.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Removed objects ===&lt;br /&gt;
* Two occurences of &amp;quot;EFHK P3&amp;quot;. Replaced by new EDDK-Terminal1.&lt;br /&gt;
* Three occurences of &amp;quot;EGPH carpark&amp;quot;.Replaced by new EDDK-Terminal1.&lt;br /&gt;
* Three occurences of &amp;quot;small-glass-office-building&amp;quot; (#3286018, #3286019, #3286020). Replaced by new EDDK-Terminal1.&lt;br /&gt;
&lt;br /&gt;
== External link ==&lt;br /&gt;
* [http://www.koeln-bonn-airport.de/index.php Airport Homepage]&lt;br /&gt;
&lt;br /&gt;
[[Category:Airports in Germany]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Flughafen_K%C3%B6ln/Bonn&amp;diff=117721</id>
		<title>Flughafen Köln/Bonn</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Flughafen_K%C3%B6ln/Bonn&amp;diff=117721"/>
		<updated>2019-04-01T12:06:42Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* EDDK in the scenery objects database */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
{{infobox Airport&lt;br /&gt;
|name = Flughafen Köln / Bonn&lt;br /&gt;
|image = Fgfs-screen-002.png&lt;br /&gt;
|iata = CGN&lt;br /&gt;
|icao = EDDK&lt;br /&gt;
|type = Public&lt;br /&gt;
|city = Köln-Wahn&lt;br /&gt;
|scenerytile = &lt;br /&gt;
|runway= 06/24&lt;br /&gt;
|length= 2459 m &lt;br /&gt;
|material= Concrete/Asphalt &lt;br /&gt;
|runway2= 14R/32L&lt;br /&gt;
|length2= 1863 m&lt;br /&gt;
|material2= Concrete/Asphalt &lt;br /&gt;
|runway3= 14L/32R&lt;br /&gt;
|length3= 3815 m &lt;br /&gt;
|material3= Asphalt &lt;br /&gt;
|website = http://www.koeln-bonn-airport.de/index.php?lang=2&lt;br /&gt;
}}&lt;br /&gt;
'''Flughafen Köln / Bonn''' also known as '''Konrad Adenauer Airport''' is the airport serving Cologne and Bonn in Germany. It is the seventh largest airport in Germany and the second largest in terms of cargo operations. In FlightGear, it is very nicely modelled, with an 850 layout and terminal models, and more!The airport is one of the few 24 hour airports in Germany.&lt;br /&gt;
&lt;br /&gt;
== Custom Scenery (work in progress, Feb 2017) ==&lt;br /&gt;
https://github.com/mherweg/EDDK-fg-CustomScenery&lt;br /&gt;
http://www.23hq.com/laserman/album/28479990&lt;br /&gt;
&lt;br /&gt;
== Live Webcams ==&lt;br /&gt;
http://www.koeln-bonn-airport.de/nc/de/am-airport/airport-webcam.html?sword_list%5B0%5D=webcam&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Facilities ==&lt;br /&gt;
Köln / Bonn has two terminals directly beside each other and three runways: &lt;br /&gt;
=== Terminal One ===&lt;br /&gt;
Terminal One is the original 197s building, in the shape of a U with two star-shaped piers, B and C. There are 13 gates, of which ten have air bridges, and several remote stands. Germanwings, Lufthansa, and Austrian Airlines use Terminal One.&lt;br /&gt;
=== Terminal Two ===&lt;br /&gt;
Terminal Two is the newer terminal, to the north of Terminal One. It is a rectangular building designated as Pier D, with 8 air bridges and several remote stands. Airlines ther than Terminal One airlines use it.&lt;br /&gt;
=== Runway 06/24 ===&lt;br /&gt;
Runway 06/24 is 2459 m (8,068 ft) long and has a width of 45 m.&lt;br /&gt;
&lt;br /&gt;
=== Runway 14R/32L ===&lt;br /&gt;
&lt;br /&gt;
Runway 14R/32L is 1863 (6,112 ft) long and has a width of 45 m.&lt;br /&gt;
&lt;br /&gt;
=== Runway 14L/32R ===&lt;br /&gt;
&lt;br /&gt;
Runway 14L/32R is 3815 (12,516 ft) long and has a width of 60 m.&lt;br /&gt;
&lt;br /&gt;
== EDDK in the scenery objects database ==&lt;br /&gt;
As mentioned above user laserman created a nice custom scenery for EDDK. Some parts of that scenery found their way into the scenery object database and replaced existing generic buildings. So these will also be available for users not aware of the custom scenery. This is a documentation of those objects. The history of the EDDK custom scenery is available at the  [https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=31646 forum].&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Building !! Model Id !! Model file !! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| Terminal 1 ||  #3474621 || EDDK-Terminal1.xml || Texturing of some parts is still missing. Center of the model is the OSM line &amp;quot;Kaffee-Filter&amp;quot; (218043449), which is object &amp;quot;Vorfeldkontrolle&amp;quot; in the AC3D file.&lt;br /&gt;
|-&lt;br /&gt;
| Terminal 2 || || EDDK-Terminal2.ac || Uses a copy of the Terminal1 texture file. The object location appears to be too far into the grass on apron D, but it complies to its OSM location. The EDDK terrain of apron D apparently is not correct.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Removed objects ===&lt;br /&gt;
* Two occurences of &amp;quot;EFHK P3&amp;quot;. Replaced by new EDDK-Terminal1.&lt;br /&gt;
* Three occurences of &amp;quot;EGPH carpark&amp;quot;.Replaced by new EDDK-Terminal1.&lt;br /&gt;
* Three occurences of &amp;quot;small-glass-office-building&amp;quot; (#3286018, #3286019, #3286020). Replaced by new EDDK-Terminal1.&lt;br /&gt;
&lt;br /&gt;
== External link ==&lt;br /&gt;
* [http://www.koeln-bonn-airport.de/index.php Airport Homepage]&lt;br /&gt;
&lt;br /&gt;
[[Category:Airports in Germany]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Flughafen_K%C3%B6ln/Bonn&amp;diff=117720</id>
		<title>Flughafen Köln/Bonn</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Flughafen_K%C3%B6ln/Bonn&amp;diff=117720"/>
		<updated>2019-04-01T12:01:32Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Removed objects */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
{{infobox Airport&lt;br /&gt;
|name = Flughafen Köln / Bonn&lt;br /&gt;
|image = Fgfs-screen-002.png&lt;br /&gt;
|iata = CGN&lt;br /&gt;
|icao = EDDK&lt;br /&gt;
|type = Public&lt;br /&gt;
|city = Köln-Wahn&lt;br /&gt;
|scenerytile = &lt;br /&gt;
|runway= 06/24&lt;br /&gt;
|length= 2459 m &lt;br /&gt;
|material= Concrete/Asphalt &lt;br /&gt;
|runway2= 14R/32L&lt;br /&gt;
|length2= 1863 m&lt;br /&gt;
|material2= Concrete/Asphalt &lt;br /&gt;
|runway3= 14L/32R&lt;br /&gt;
|length3= 3815 m &lt;br /&gt;
|material3= Asphalt &lt;br /&gt;
|website = http://www.koeln-bonn-airport.de/index.php?lang=2&lt;br /&gt;
}}&lt;br /&gt;
'''Flughafen Köln / Bonn''' also known as '''Konrad Adenauer Airport''' is the airport serving Cologne and Bonn in Germany. It is the seventh largest airport in Germany and the second largest in terms of cargo operations. In FlightGear, it is very nicely modelled, with an 850 layout and terminal models, and more!The airport is one of the few 24 hour airports in Germany.&lt;br /&gt;
&lt;br /&gt;
== Custom Scenery (work in progress, Feb 2017) ==&lt;br /&gt;
https://github.com/mherweg/EDDK-fg-CustomScenery&lt;br /&gt;
http://www.23hq.com/laserman/album/28479990&lt;br /&gt;
&lt;br /&gt;
== Live Webcams ==&lt;br /&gt;
http://www.koeln-bonn-airport.de/nc/de/am-airport/airport-webcam.html?sword_list%5B0%5D=webcam&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Facilities ==&lt;br /&gt;
Köln / Bonn has two terminals directly beside each other and three runways: &lt;br /&gt;
=== Terminal One ===&lt;br /&gt;
Terminal One is the original 197s building, in the shape of a U with two star-shaped piers, B and C. There are 13 gates, of which ten have air bridges, and several remote stands. Germanwings, Lufthansa, and Austrian Airlines use Terminal One.&lt;br /&gt;
=== Terminal Two ===&lt;br /&gt;
Terminal Two is the newer terminal, to the north of Terminal One. It is a rectangular building designated as Pier D, with 8 air bridges and several remote stands. Airlines ther than Terminal One airlines use it.&lt;br /&gt;
=== Runway 06/24 ===&lt;br /&gt;
Runway 06/24 is 2459 m (8,068 ft) long and has a width of 45 m.&lt;br /&gt;
&lt;br /&gt;
=== Runway 14R/32L ===&lt;br /&gt;
&lt;br /&gt;
Runway 14R/32L is 1863 (6,112 ft) long and has a width of 45 m.&lt;br /&gt;
&lt;br /&gt;
=== Runway 14L/32R ===&lt;br /&gt;
&lt;br /&gt;
Runway 14L/32R is 3815 (12,516 ft) long and has a width of 60 m.&lt;br /&gt;
&lt;br /&gt;
== EDDK in the scenery objects database ==&lt;br /&gt;
As mentioned above user laserman created a nice custom scenery for EDDK. Some parts of that scenery found their way into the scenery object database and replaced existing generic buildings. So these will also be available for users not aware of the custom scenery. This is a documentation of those objects. The history of the EDDK custom scenery is available at the  [https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=31646 forum].&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Building !! Model file !! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| Terminal 1 || EDDK-Terminal1.xml || Texturing of some parts is still missing. Center of the model is the OSM line &amp;quot;Kaffee-Filter&amp;quot; (218043449), which is object &amp;quot;Vorfeldkontrolle&amp;quot; in the AC3D file.&lt;br /&gt;
|-&lt;br /&gt;
| Terminal 2 || EDDK-Terminal2.ac || Uses a copy of the Terminal1 texture file. The object location appears to be too far into the grass on apron D, but it complies to its OSM location. The EDDK terrain of apron D apparently is not correct.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Removed objects ===&lt;br /&gt;
* Two occurences of &amp;quot;EFHK P3&amp;quot;. Replaced by new EDDK-Terminal1.&lt;br /&gt;
* Three occurences of &amp;quot;EGPH carpark&amp;quot;.Replaced by new EDDK-Terminal1.&lt;br /&gt;
* Three occurences of &amp;quot;small-glass-office-building&amp;quot; (#3286018, #3286019, #3286020). Replaced by new EDDK-Terminal1.&lt;br /&gt;
&lt;br /&gt;
== External link ==&lt;br /&gt;
* [http://www.koeln-bonn-airport.de/index.php Airport Homepage]&lt;br /&gt;
&lt;br /&gt;
[[Category:Airports in Germany]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Ground_Services&amp;diff=117629</id>
		<title>Ground Services</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Ground_Services&amp;diff=117629"/>
		<updated>2019-03-19T13:53:27Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Known Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infobox subsystem&lt;br /&gt;
|image       = GroundServices-Title.png&lt;br /&gt;
|name        = Ground Services&lt;br /&gt;
|started     = 03/2017&lt;br /&gt;
|description = Moving ground service vehicles at airports&lt;br /&gt;
|status      = Under active development as of 03/2017&lt;br /&gt;
|maintainers = {{usr|ThomasS}}&lt;br /&gt;
|developers  = ThomasS&lt;br /&gt;
|topic-fgdata = https://github.com/thomass171/GroundServices (addon)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{See also|Ground Traffic Simulation Resources}}&lt;br /&gt;
&lt;br /&gt;
This article is about a prototype for a '''ground service module''' (addon) for FlightGear written in [[Nasal]]. Unlike some exisiting ground services which are part of various aircraft, it is intended to be generic and not dependant on specific aircrafts (though there will be dependencies from aircraft dimensions).&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
{{See also|Traffic Shader}}&lt;br /&gt;
{{See also|Road Traffic}}&lt;br /&gt;
&lt;br /&gt;
The addon currently moves ground vehicles along an airports taxiways and provides simple catering and fueling services.&lt;br /&gt;
It is written completely in Nasal and is derived/inspired from the existing AI subsystem and tanker.nas (except for the way vehicles are moving)&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=311651#p311651 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re:  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 2nd, 2017 &lt;br /&gt;
  |added  =  Jun 2nd, 2017 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
. &lt;br /&gt;
&lt;br /&gt;
After starting FG, GroundServices goes to &amp;quot;standby&amp;quot; mode, monitoring the distance of the main aircraft to the next airport. When the distance is below 3 nm (main.minairportrange), GroundService switches to &amp;quot;active&amp;quot; mode. It reads the corresponding groundnet.xml and ground vehicles are launched as defined in AI/groundservices.xml.&lt;br /&gt;
&amp;quot;initialcount&amp;quot; vehicles (scaled by airport size) of each type will be launched at their defined home location and move between the configured destinations (random groundnet nodes are used if nothing is configured).&lt;br /&gt;
When the distance to the airport exceeds 3 nm, GroundServices switches back to &amp;quot;standby&amp;quot; mode, removing all ground vehicles.&lt;br /&gt;
&lt;br /&gt;
The models included are&lt;br /&gt;
&lt;br /&gt;
* the standard Goldhofert pushback truck with aircraftspecific animations removed&lt;br /&gt;
* the followme car from FG Addon &lt;br /&gt;
* the fuel truck from Gabriels 737-800 branch&lt;br /&gt;
* the catering model https://scenery.flightgear.org/app.php?c=Models&amp;amp;a=view&amp;amp;id=6620&lt;br /&gt;
&lt;br /&gt;
The GUI provides the options to&lt;br /&gt;
* launch an additional vehicle (select in combo box and button &amp;quot;Launch&amp;quot;)&lt;br /&gt;
* launch catering and fuel service for an arrived aircraft&lt;br /&gt;
* visualize the groundnet (which is implemented quite inefficiently by multiple models for each length due to the lack of dynamic model scaling). The color of the groundnet lines should be yellow, but differs for some unknown reason (lighting effects?) from red to orange.&lt;br /&gt;
* toggle auto movement of vehicles and auto service&lt;br /&gt;
* open a canvas map which shows the location of the vehicles and service points&lt;br /&gt;
* write the state of each vehicle to the logfile&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
There are already existing ground service components in FG providing Pushback, FollowMe, Ramp Marshall and Jetways (maybe even more). Integrating these with the existing AI system appears straightforward. Routes for driving vehicles on the apron could be derived from groundnet.xml. &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=304670#p304670 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Ground services ! &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Feb 1st, 2017 &lt;br /&gt;
  |added  =  Feb 1st, 2017 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
The Nasal approach of tanker.nas however looks more comprehensive. Reading groundnet.xml from Nasal apparently isn't possible yet without doing explicit XML parsing. Though the airportinfo function in nasal provides parking and taxiway information, these might be derived from different sources than groundnet.xml.&lt;br /&gt;
&lt;br /&gt;
Having the groundnet.xml  information available in Nasal in combination with the logic in tanker.nas might provide a simple way for having vehicles moving on the apron.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=304670#p304670 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Ground services ! &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Feb 1st, 2017 &lt;br /&gt;
  |added  =  Feb 1st, 2017 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
{{See also|Airports with ground networks}}&lt;br /&gt;
GroundServices was developed and tested with FlightGear 2016.4.3, 2017.3.1 and EDDKs, EHAMs, EGLLs and EDDFs groundnet. As of release 0.3.0 it is a FlightGear addon and so requires at least FlightGear version 2017.3. There are no further known special requirements and it should also work with later FlightGear versions and airports that have a groundnet defined.&lt;br /&gt;
&lt;br /&gt;
The solution is based on the airports groundnet.xml. So for now you just have to make sure that your airports groundnet.xml is reasonable, meaning parking positions are at correct location and all connected to taxiways. Look at [https://github.com/thomass171/GroundServices/releases https://github.com/thomass171/GroundServices/releases] for releases.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=315223#p315223 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Ground services ! &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 28th, 2017 &lt;br /&gt;
  |added  =  Jul 28th, 2017 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Current Status ==&lt;br /&gt;
GroundServices currently moves ground vehicles along an airports taxiways and provides simple catering and fueling services.&lt;br /&gt;
Its just a prototype and still might contain bugs. There is a risk of null/nil pointer incidents. Indicator for this is when all vehicles stop moving.&lt;br /&gt;
&lt;br /&gt;
The catering and fueling services are composed of a catering vehicle approaching an aircrafts right front door and a fuel truck approaching the left wing. The approach destinations are calculated from the aircraft position and a defined door and wing position of the aircraft. Currently the implementation only uses a rough approximation of these positions, because there seem to be only a few aircraft models out there that have door positions defined. &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=315206#p315206 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re:  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 28th, 2017 &lt;br /&gt;
  |added  =  Jul 28th, 2017 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Furthermore, there seems to be no way to get information about an AI aircraft model from the property tree currently. However, jetways.nas seems to find the door positions even for AI aircrafts (issue added to roadmap).&lt;br /&gt;
&lt;br /&gt;
Known problems are (see also [https://github.com/thomass171/GroundServices/issues issue list]):&lt;br /&gt;
&lt;br /&gt;
*Ground Services doesn't work with scenery outside FG_HOME (solved in release v0.3.0)&lt;br /&gt;
*Vehicles appear twisting at some nodes when turning (partly solved in release v0.3.0)&lt;br /&gt;
&lt;br /&gt;
== Releases ==&lt;br /&gt;
The module is available [https://github.com/thomass171/GroundServices/releases here]. It is recommended to use the latest release 0.5.0 and install the addon from the zip archive.&lt;br /&gt;
&lt;br /&gt;
Changelog up to release 0.5.0&lt;br /&gt;
&lt;br /&gt;
v0.2.0 (August 2017):&lt;br /&gt;
* Fixes the problem of vehicles having wrong elevation when they were launched before the scenery was completely loaded.&lt;br /&gt;
* Uses position dependant elevation for visualized ground net segments instead of airport elevation.&lt;br /&gt;
* Fuel truck added&lt;br /&gt;
* Now finds a vehicle home position even for groundnets having inconsistent headings at parking positions&lt;br /&gt;
* Fixes several &amp;quot;non-objects have no members&amp;quot; problems.&lt;br /&gt;
* Delayed launch of initial vehicles&lt;br /&gt;
* preparation for AI traffic integration&lt;br /&gt;
&lt;br /&gt;
v0.3.0 (November 2017):&lt;br /&gt;
* Further fixes for correct elevation of vehicles&lt;br /&gt;
* Fix for airports with negative longitude (didn't work here)&lt;br /&gt;
* Service points and schedules are introduced. Service points let catering and fuel trucks approach aircrafts.&lt;br /&gt;
* Canvas map shows location of vehicles, service points and main aircraft&lt;br /&gt;
* Vehicles have varying speed (accelerate and brake)&lt;br /&gt;
* The module is an addon now&lt;br /&gt;
&lt;br /&gt;
v0.4.0 (April 2018):&lt;br /&gt;
* Adjustments for complying to new addon structure&lt;br /&gt;
&lt;br /&gt;
0.5.0 (June 2018):&lt;br /&gt;
* Additional adjustments for complying to new addon structure. No more manual installation required.&lt;br /&gt;
* Vehicles move at the outline of taxiways instead of on the center line. This reduces the number of visual collisions.&lt;br /&gt;
* Two 737 model (Air Canada and Air France) and one Cessna Citation are launched. The Cessna will just move around the groundnet while the 737 will move to some non occupied neighbor position of the current aircraft.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
As of release 0.3.0 this module is an addon and as of release 0.5.0 it fully complies to the FlightGear addon infrastructure available as of 2018.2.1. It is recommended to use at least release 0.5.0 of this addon with at least FlightGear 2018.2.1. &lt;br /&gt;
&lt;br /&gt;
The addon is installed just like any other addon as described in [[Addons]]. No manual steps are needed any more.&lt;br /&gt;
&lt;br /&gt;
== Running ==&lt;br /&gt;
After starting FG with the aircraft located on an airport that has a groundnet defined (I propose using ufo on EDDK for a first attempt) the vehicles will start moving from their home point immediately. In EDDK vehicles will move near the main terminal and should be easily visible. EHAM, EDDF and EGLL are considerably larger and have no home configured. In EHAM vehicles will start from cargo position R, which is in the south west of the airport. Move ufo near there (by PHI; thats very easy) for seeing the vehicles. &lt;br /&gt;
&lt;br /&gt;
If any problems occur, check FGs logfiles for nasal errors. In addition a logfile FG_HOME/groundservices.log is written by GroundService and can be checked for errors.&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
For having some nearby activity, two 737 models (Air Canada and Air France) will be launched after initialization (config parameter &amp;quot;delayfornearbyaircraft&amp;quot;). These will move to some non occupied neighbor position of the current aircraft and receive servicing.&lt;br /&gt;
&lt;br /&gt;
== Monitoring vehicles ==&lt;br /&gt;
&lt;br /&gt;
Its not easy to detect the current position of ground vehicles. Seeing them from your current view point is mere chance. &lt;br /&gt;
=== Phi ===&lt;br /&gt;
&lt;br /&gt;
 [[File:Phi-Vehicles.png|right|thumb|Ground vehicles displayed in Phi]]&lt;br /&gt;
&lt;br /&gt;
An option for monitoring vehicles is the map of [[Phi]]. This however requires two patches to the file Phi/topics/Map/AILayer.js in FG_ROOT. Near line 81 the type &amp;quot;gsvehicle&amp;quot; needs to added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
self.addData(self.aiPropsToGeoJson(data, [&lt;br /&gt;
  &amp;quot;tanker&amp;quot;,&amp;quot;gsvehicle&amp;quot;, &amp;quot;aircraft&amp;quot;, &amp;quot;multiplayer&amp;quot;, &amp;quot;carrier&amp;quot; ], self._map.getBounds()));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and near line 139 these models need to be considered:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
if (type == &amp;quot;gsvehicle&amp;quot;) {&lt;br /&gt;
    callsign = child.getNode(&amp;quot;id&amp;quot;).getValue();&lt;br /&gt;
} else {&lt;br /&gt;
    if (type == &amp;quot;carrier&amp;quot;) {&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Don't forget the closing curly brace a few lines beneath (not displayed here). Reload [[Phi]] in your browser and choose &amp;quot;Other Traffic&amp;quot; in the layer selection menu.&lt;br /&gt;
&lt;br /&gt;
=== Canvas Map ===&lt;br /&gt;
&lt;br /&gt;
[[File:Gs mapEDDF.PNG|right|thumb|Ground Services map in EDDF]]&lt;br /&gt;
&lt;br /&gt;
The map is opened by clicking the &amp;quot;Map&amp;quot; menu item in the Ground Services menu. It uses the following colored indicators for vehicles:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| &amp;lt;big style=&amp;quot;color: rgb(0, 255, 128);&amp;quot;&amp;gt;o&amp;lt;/big&amp;gt; || ground vehicle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big style=&amp;quot;color: rgb(200,0,240);&amp;quot;&amp;gt;o&amp;lt;/big&amp;gt; || active service point (arrived aircraft)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big style=&amp;quot;color: rgb(0, 255, 255);&amp;quot;&amp;gt;o&amp;lt;/big&amp;gt; || current aircraft&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Model Cockpit View ===&lt;br /&gt;
The addon [[Model Cockpit View]] lets cycle the view point through all AI cockpits. For using it with ground service vehicles, the phrase &amp;quot;gsvehicle&amp;quot; needs to be added manually to the code (main.nas):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  ~ ai.getChildren(&amp;quot;gsvehicle&amp;quot;)&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, the view point will be at (0,0,0), so the view point from a ground vehicle will be exactly on the ground below the vehicle. Though this might be useful for analysis purposes, a raised view point is more interesting. See [[Model Cockpit View]]  on how to change the view point.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
The main configuration file is AI/groundservices.xml. When no home position is defined for an airport, the first (or last) &lt;br /&gt;
parking node will be used as home.&lt;br /&gt;
&lt;br /&gt;
== Uninstall ==&lt;br /&gt;
Uninstallation is done by just deleting the addons directory and removing it from the addons option from the command line.&lt;br /&gt;
&lt;br /&gt;
== Implementation Notes ==&lt;br /&gt;
The groundnet information is stored in a graph data structure. &lt;br /&gt;
&lt;br /&gt;
For simplification, the coordinates are projected to a 2D xy coordinate system, where all calculations are executed (The projection currently is a too simple linear projection).&lt;br /&gt;
&lt;br /&gt;
Moving of vehicles is implemented by first finding a path along the graph (Graph.findPath()), which is quite simple due to Edsger Dijkstras preliminary work. The vehicles will move along&lt;br /&gt;
their defined path like a train on rails. They will allways be fixed at some specific position on some edge (class GraphPosition).&lt;br /&gt;
For accomplishing a smooth transition from one edge to the other, the graph not only allows line edges but also arc edges. So the shortest path found through the graph will be smoothed&lt;br /&gt;
(GraphUtils.createPathFromGraphPosition() and GraphUtils.createTransition()) by truncating line edges and connecting these by arc edges. These graph edges will be added temporarily to the graph and will be removed from the&lt;br /&gt;
graph when the vehicle reaches its destination. Smoothing the graph path is a quite complex process with many potential combinations (eg. short edges, small angles between edges, orientation of vehicles).  &lt;br /&gt;
Optimizing this process still is a work in progress.&lt;br /&gt;
&lt;br /&gt;
== Known Problems ==&lt;br /&gt;
Sometimes the errors&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
NasalSys.cxx:1204:Nasal runtime error: non-objects have no members&lt;br /&gt;
NasalSys.cxx:1216:  at /Users/thomas/Projekte/FlightGearGit/FGData/Nasal/canvas/api.nas, line 147&lt;br /&gt;
&lt;br /&gt;
NasalSys.cxx:1204:Nasal runtime error: MapStructure model not found&lt;br /&gt;
NasalSys.cxx:1216:  at /Users/thomas/Projekte/FlightGearGit/FGData/Nasal/canvas/MapStructure.nas, line 27&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
are logged to the FG log file. The reason is unclear.&lt;br /&gt;
&lt;br /&gt;
== Roadmap ==&lt;br /&gt;
The list of possible improvements is endless. The following are some of the ideas (without any order):&lt;br /&gt;
* The turning radius of vehicles at parking nodes is too small sometimes, which make vehicles turn unrealistically twisting {{pending}}&lt;br /&gt;
* Vehicles should  accelerate instead of just switching speed.  {{Progressbar|100}} {{done}}&lt;br /&gt;
* Vehicles shouldn't move on taxiways but on dedicated lanes. This requires either an extended version of groundnet.xml (newer versions of apt.dat might contain a groundnet for ground service vehicles) or some smart algorithm. In any case, a big challenge. {{pending}}&lt;br /&gt;
* Vehicles not using dedicated lanes (currently all) should move at the outline of taxiways which reduces the risk of collisions.  {{Progressbar|100}} {{done}}&lt;br /&gt;
* Make a fuel and catering vehicle approach parking AI aircraft  {{Progressbar|100}} {{done}}&lt;br /&gt;
* Vehicles should be animated, starting with a catering vehicle moving up its container. Unfortunately the current catering vehicle model doesn't allow animation.{{pending}}&lt;br /&gt;
* Animation of wheels. {{pending}}&lt;br /&gt;
* Check using ai.nas mentioned in [[Scripted_AI_Objects]]. {{pending}} (that's actually outdated meanwhile, [[Ground Services]] looks much more promising)&lt;br /&gt;
* Make it a Flightgear addon.  {{Progressbar|100}} {{done}}&lt;br /&gt;
* Add a canvas GUI for monitoring vehicles  {{Progressbar|100}} {{done}}&lt;br /&gt;
* Retrieve door positions from AI model like [[Howto:Animated jetways|animated jetways]] does. AI aircraft should contain a piece of nasal code that adds door information to the property tree when loaded. However, extending AI core code for saving model origin information to the property tree could still be useful, eg. for defining cockpit positions in addon [[Model Cockpit View]].  {{Progressbar|20}}&lt;br /&gt;
* Extend AI core code for saving departure/arrival information of AI aircrafts to the property tree. Thus arrived parking aircrafts can be detected for service more reliably. Such an extension might also be helpful for the [[Howto:Animated jetways|animated jetways]]. {{Progressbar|10}} {{pending}}&lt;br /&gt;
* Unify AI traffic categories for avoiding manual patches to [[Model Cockpit View]] and [[Phi]] by a Nasal registry for all kinds of AI/MP traffic, eg. AI.nas or Traffic.nas. &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=6&amp;amp;t=30735&amp;amp;p=323612&amp;amp;hilit=mapstructure.nas#p323588 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Ground services ! &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Dec 2nd, 2017 &lt;br /&gt;
  |added  =  Dec 2nd, 2017 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
}}&amp;lt;/ref&amp;gt; {{Progressbar|10}} {{pending}}&lt;br /&gt;
* Extend MapStructure.nas with a kind of layer registry for avoiding copying files into FG_ROOT. &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=6&amp;amp;t=30735&amp;amp;p=323612&amp;amp;hilit=mapstructure.nas#p323588 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Ground services ! &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Dec 2nd, 2017 &lt;br /&gt;
  |added  =  Dec 2nd, 2017 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
}}&amp;lt;/ref&amp;gt; . Latest tests show that no change to MapStructure.nas is required. The layer can just be added from the addon. Will be part of next release. {{Progressbar|100}} {{done}}&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
A followme vehicle on its way at EHAM.&lt;br /&gt;
&lt;br /&gt;
[[File:GroundServices-screen-007.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear add-ons]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Ground_Services&amp;diff=117628</id>
		<title>Ground Services</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Ground_Services&amp;diff=117628"/>
		<updated>2019-03-19T13:39:39Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Known problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infobox subsystem&lt;br /&gt;
|image       = GroundServices-Title.png&lt;br /&gt;
|name        = Ground Services&lt;br /&gt;
|started     = 03/2017&lt;br /&gt;
|description = Moving ground service vehicles at airports&lt;br /&gt;
|status      = Under active development as of 03/2017&lt;br /&gt;
|maintainers = {{usr|ThomasS}}&lt;br /&gt;
|developers  = ThomasS&lt;br /&gt;
|topic-fgdata = https://github.com/thomass171/GroundServices (addon)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{See also|Ground Traffic Simulation Resources}}&lt;br /&gt;
&lt;br /&gt;
This article is about a prototype for a '''ground service module''' (addon) for FlightGear written in [[Nasal]]. Unlike some exisiting ground services which are part of various aircraft, it is intended to be generic and not dependant on specific aircrafts (though there will be dependencies from aircraft dimensions).&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
{{See also|Traffic Shader}}&lt;br /&gt;
{{See also|Road Traffic}}&lt;br /&gt;
&lt;br /&gt;
The addon currently moves ground vehicles along an airports taxiways and provides simple catering and fueling services.&lt;br /&gt;
It is written completely in Nasal and is derived/inspired from the existing AI subsystem and tanker.nas (except for the way vehicles are moving)&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=311651#p311651 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re:  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 2nd, 2017 &lt;br /&gt;
  |added  =  Jun 2nd, 2017 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
. &lt;br /&gt;
&lt;br /&gt;
After starting FG, GroundServices goes to &amp;quot;standby&amp;quot; mode, monitoring the distance of the main aircraft to the next airport. When the distance is below 3 nm (main.minairportrange), GroundService switches to &amp;quot;active&amp;quot; mode. It reads the corresponding groundnet.xml and ground vehicles are launched as defined in AI/groundservices.xml.&lt;br /&gt;
&amp;quot;initialcount&amp;quot; vehicles (scaled by airport size) of each type will be launched at their defined home location and move between the configured destinations (random groundnet nodes are used if nothing is configured).&lt;br /&gt;
When the distance to the airport exceeds 3 nm, GroundServices switches back to &amp;quot;standby&amp;quot; mode, removing all ground vehicles.&lt;br /&gt;
&lt;br /&gt;
The models included are&lt;br /&gt;
&lt;br /&gt;
* the standard Goldhofert pushback truck with aircraftspecific animations removed&lt;br /&gt;
* the followme car from FG Addon &lt;br /&gt;
* the fuel truck from Gabriels 737-800 branch&lt;br /&gt;
* the catering model https://scenery.flightgear.org/app.php?c=Models&amp;amp;a=view&amp;amp;id=6620&lt;br /&gt;
&lt;br /&gt;
The GUI provides the options to&lt;br /&gt;
* launch an additional vehicle (select in combo box and button &amp;quot;Launch&amp;quot;)&lt;br /&gt;
* launch catering and fuel service for an arrived aircraft&lt;br /&gt;
* visualize the groundnet (which is implemented quite inefficiently by multiple models for each length due to the lack of dynamic model scaling). The color of the groundnet lines should be yellow, but differs for some unknown reason (lighting effects?) from red to orange.&lt;br /&gt;
* toggle auto movement of vehicles and auto service&lt;br /&gt;
* open a canvas map which shows the location of the vehicles and service points&lt;br /&gt;
* write the state of each vehicle to the logfile&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
There are already existing ground service components in FG providing Pushback, FollowMe, Ramp Marshall and Jetways (maybe even more). Integrating these with the existing AI system appears straightforward. Routes for driving vehicles on the apron could be derived from groundnet.xml. &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=304670#p304670 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Ground services ! &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Feb 1st, 2017 &lt;br /&gt;
  |added  =  Feb 1st, 2017 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
The Nasal approach of tanker.nas however looks more comprehensive. Reading groundnet.xml from Nasal apparently isn't possible yet without doing explicit XML parsing. Though the airportinfo function in nasal provides parking and taxiway information, these might be derived from different sources than groundnet.xml.&lt;br /&gt;
&lt;br /&gt;
Having the groundnet.xml  information available in Nasal in combination with the logic in tanker.nas might provide a simple way for having vehicles moving on the apron.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=304670#p304670 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Ground services ! &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Feb 1st, 2017 &lt;br /&gt;
  |added  =  Feb 1st, 2017 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
{{See also|Airports with ground networks}}&lt;br /&gt;
GroundServices was developed and tested with FlightGear 2016.4.3, 2017.3.1 and EDDKs, EHAMs, EGLLs and EDDFs groundnet. As of release 0.3.0 it is a FlightGear addon and so requires at least FlightGear version 2017.3. There are no further known special requirements and it should also work with later FlightGear versions and airports that have a groundnet defined.&lt;br /&gt;
&lt;br /&gt;
The solution is based on the airports groundnet.xml. So for now you just have to make sure that your airports groundnet.xml is reasonable, meaning parking positions are at correct location and all connected to taxiways. Look at [https://github.com/thomass171/GroundServices/releases https://github.com/thomass171/GroundServices/releases] for releases.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=315223#p315223 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Ground services ! &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 28th, 2017 &lt;br /&gt;
  |added  =  Jul 28th, 2017 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Current Status ==&lt;br /&gt;
GroundServices currently moves ground vehicles along an airports taxiways and provides simple catering and fueling services.&lt;br /&gt;
Its just a prototype and still might contain bugs. There is a risk of null/nil pointer incidents. Indicator for this is when all vehicles stop moving.&lt;br /&gt;
&lt;br /&gt;
The catering and fueling services are composed of a catering vehicle approaching an aircrafts right front door and a fuel truck approaching the left wing. The approach destinations are calculated from the aircraft position and a defined door and wing position of the aircraft. Currently the implementation only uses a rough approximation of these positions, because there seem to be only a few aircraft models out there that have door positions defined. &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=315206#p315206 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re:  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 28th, 2017 &lt;br /&gt;
  |added  =  Jul 28th, 2017 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Furthermore, there seems to be no way to get information about an AI aircraft model from the property tree currently. However, jetways.nas seems to find the door positions even for AI aircrafts (issue added to roadmap).&lt;br /&gt;
&lt;br /&gt;
Known problems are (see also [https://github.com/thomass171/GroundServices/issues issue list]):&lt;br /&gt;
&lt;br /&gt;
*Ground Services doesn't work with scenery outside FG_HOME (solved in release v0.3.0)&lt;br /&gt;
*Vehicles appear twisting at some nodes when turning (partly solved in release v0.3.0)&lt;br /&gt;
&lt;br /&gt;
== Releases ==&lt;br /&gt;
The module is available [https://github.com/thomass171/GroundServices/releases here]. It is recommended to use the latest release 0.5.0 and install the addon from the zip archive.&lt;br /&gt;
&lt;br /&gt;
Changelog up to release 0.5.0&lt;br /&gt;
&lt;br /&gt;
v0.2.0 (August 2017):&lt;br /&gt;
* Fixes the problem of vehicles having wrong elevation when they were launched before the scenery was completely loaded.&lt;br /&gt;
* Uses position dependant elevation for visualized ground net segments instead of airport elevation.&lt;br /&gt;
* Fuel truck added&lt;br /&gt;
* Now finds a vehicle home position even for groundnets having inconsistent headings at parking positions&lt;br /&gt;
* Fixes several &amp;quot;non-objects have no members&amp;quot; problems.&lt;br /&gt;
* Delayed launch of initial vehicles&lt;br /&gt;
* preparation for AI traffic integration&lt;br /&gt;
&lt;br /&gt;
v0.3.0 (November 2017):&lt;br /&gt;
* Further fixes for correct elevation of vehicles&lt;br /&gt;
* Fix for airports with negative longitude (didn't work here)&lt;br /&gt;
* Service points and schedules are introduced. Service points let catering and fuel trucks approach aircrafts.&lt;br /&gt;
* Canvas map shows location of vehicles, service points and main aircraft&lt;br /&gt;
* Vehicles have varying speed (accelerate and brake)&lt;br /&gt;
* The module is an addon now&lt;br /&gt;
&lt;br /&gt;
v0.4.0 (April 2018):&lt;br /&gt;
* Adjustments for complying to new addon structure&lt;br /&gt;
&lt;br /&gt;
0.5.0 (June 2018):&lt;br /&gt;
* Additional adjustments for complying to new addon structure. No more manual installation required.&lt;br /&gt;
* Vehicles move at the outline of taxiways instead of on the center line. This reduces the number of visual collisions.&lt;br /&gt;
* Two 737 model (Air Canada and Air France) and one Cessna Citation are launched. The Cessna will just move around the groundnet while the 737 will move to some non occupied neighbor position of the current aircraft.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
As of release 0.3.0 this module is an addon and as of release 0.5.0 it fully complies to the FlightGear addon infrastructure available as of 2018.2.1. It is recommended to use at least release 0.5.0 of this addon with at least FlightGear 2018.2.1. &lt;br /&gt;
&lt;br /&gt;
The addon is installed just like any other addon as described in [[Addons]]. No manual steps are needed any more.&lt;br /&gt;
&lt;br /&gt;
== Running ==&lt;br /&gt;
After starting FG with the aircraft located on an airport that has a groundnet defined (I propose using ufo on EDDK for a first attempt) the vehicles will start moving from their home point immediately. In EDDK vehicles will move near the main terminal and should be easily visible. EHAM, EDDF and EGLL are considerably larger and have no home configured. In EHAM vehicles will start from cargo position R, which is in the south west of the airport. Move ufo near there (by PHI; thats very easy) for seeing the vehicles. &lt;br /&gt;
&lt;br /&gt;
If any problems occur, check FGs logfiles for nasal errors. In addition a logfile FG_HOME/groundservices.log is written by GroundService and can be checked for errors.&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
For having some nearby activity, two 737 models (Air Canada and Air France) will be launched after initialization (config parameter &amp;quot;delayfornearbyaircraft&amp;quot;). These will move to some non occupied neighbor position of the current aircraft and receive servicing.&lt;br /&gt;
&lt;br /&gt;
== Monitoring vehicles ==&lt;br /&gt;
&lt;br /&gt;
Its not easy to detect the current position of ground vehicles. Seeing them from your current view point is mere chance. &lt;br /&gt;
=== Phi ===&lt;br /&gt;
&lt;br /&gt;
 [[File:Phi-Vehicles.png|right|thumb|Ground vehicles displayed in Phi]]&lt;br /&gt;
&lt;br /&gt;
An option for monitoring vehicles is the map of [[Phi]]. This however requires two patches to the file Phi/topics/Map/AILayer.js in FG_ROOT. Near line 81 the type &amp;quot;gsvehicle&amp;quot; needs to added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
self.addData(self.aiPropsToGeoJson(data, [&lt;br /&gt;
  &amp;quot;tanker&amp;quot;,&amp;quot;gsvehicle&amp;quot;, &amp;quot;aircraft&amp;quot;, &amp;quot;multiplayer&amp;quot;, &amp;quot;carrier&amp;quot; ], self._map.getBounds()));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and near line 139 these models need to be considered:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
if (type == &amp;quot;gsvehicle&amp;quot;) {&lt;br /&gt;
    callsign = child.getNode(&amp;quot;id&amp;quot;).getValue();&lt;br /&gt;
} else {&lt;br /&gt;
    if (type == &amp;quot;carrier&amp;quot;) {&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Don't forget the closing curly brace a few lines beneath (not displayed here). Reload [[Phi]] in your browser and choose &amp;quot;Other Traffic&amp;quot; in the layer selection menu.&lt;br /&gt;
&lt;br /&gt;
=== Canvas Map ===&lt;br /&gt;
&lt;br /&gt;
[[File:Gs mapEDDF.PNG|right|thumb|Ground Services map in EDDF]]&lt;br /&gt;
&lt;br /&gt;
The map is opened by clicking the &amp;quot;Map&amp;quot; menu item in the Ground Services menu. It uses the following colored indicators for vehicles:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| &amp;lt;big style=&amp;quot;color: rgb(0, 255, 128);&amp;quot;&amp;gt;o&amp;lt;/big&amp;gt; || ground vehicle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big style=&amp;quot;color: rgb(200,0,240);&amp;quot;&amp;gt;o&amp;lt;/big&amp;gt; || active service point (arrived aircraft)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big style=&amp;quot;color: rgb(0, 255, 255);&amp;quot;&amp;gt;o&amp;lt;/big&amp;gt; || current aircraft&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Model Cockpit View ===&lt;br /&gt;
The addon [[Model Cockpit View]] lets cycle the view point through all AI cockpits. For using it with ground service vehicles, the phrase &amp;quot;gsvehicle&amp;quot; needs to be added manually to the code (main.nas):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  ~ ai.getChildren(&amp;quot;gsvehicle&amp;quot;)&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, the view point will be at (0,0,0), so the view point from a ground vehicle will be exactly on the ground below the vehicle. Though this might be useful for analysis purposes, a raised view point is more interesting. See [[Model Cockpit View]]  on how to change the view point.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
The main configuration file is AI/groundservices.xml. When no home position is defined for an airport, the first (or last) &lt;br /&gt;
parking node will be used as home.&lt;br /&gt;
&lt;br /&gt;
== Uninstall ==&lt;br /&gt;
Uninstallation is done by just deleting the addons directory and removing it from the addons option from the command line.&lt;br /&gt;
&lt;br /&gt;
== Implementation Notes ==&lt;br /&gt;
The groundnet information is stored in a graph data structure. &lt;br /&gt;
&lt;br /&gt;
For simplification, the coordinates are projected to a 2D xy coordinate system, where all calculations are executed (The projection currently is a too simple linear projection).&lt;br /&gt;
&lt;br /&gt;
Moving of vehicles is implemented by first finding a path along the graph (Graph.findPath()), which is quite simple due to Edsger Dijkstras preliminary work. The vehicles will move along&lt;br /&gt;
their defined path like a train on rails. They will allways be fixed at some specific position on some edge (class GraphPosition).&lt;br /&gt;
For accomplishing a smooth transition from one edge to the other, the graph not only allows line edges but also arc edges. So the shortest path found through the graph will be smoothed&lt;br /&gt;
(GraphUtils.createPathFromGraphPosition() and GraphUtils.createTransition()) by truncating line edges and connecting these by arc edges. These graph edges will be added temporarily to the graph and will be removed from the&lt;br /&gt;
graph when the vehicle reaches its destination. Smoothing the graph path is a quite complex process with many potential combinations (eg. short edges, small angles between edges, orientation of vehicles).  &lt;br /&gt;
Optimizing this process still is a work in progress.&lt;br /&gt;
&lt;br /&gt;
== Known Problems ==&lt;br /&gt;
Sometimes the error &lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
NasalSys.cxx:1204:Nasal runtime error: non-objects have no members&lt;br /&gt;
NasalSys.cxx:1216:  at /Users/thomas/Projekte/FlightGearGit/FGData/Nasal/canvas/api.nas, line 147&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
is logged to the FG log file. The reason is unclear.&lt;br /&gt;
&lt;br /&gt;
== Roadmap ==&lt;br /&gt;
The list of possible improvements is endless. The following are some of the ideas (without any order):&lt;br /&gt;
* The turning radius of vehicles at parking nodes is too small sometimes, which make vehicles turn unrealistically twisting {{pending}}&lt;br /&gt;
* Vehicles should  accelerate instead of just switching speed.  {{Progressbar|100}} {{done}}&lt;br /&gt;
* Vehicles shouldn't move on taxiways but on dedicated lanes. This requires either an extended version of groundnet.xml (newer versions of apt.dat might contain a groundnet for ground service vehicles) or some smart algorithm. In any case, a big challenge. {{pending}}&lt;br /&gt;
* Vehicles not using dedicated lanes (currently all) should move at the outline of taxiways which reduces the risk of collisions.  {{Progressbar|100}} {{done}}&lt;br /&gt;
* Make a fuel and catering vehicle approach parking AI aircraft  {{Progressbar|100}} {{done}}&lt;br /&gt;
* Vehicles should be animated, starting with a catering vehicle moving up its container. Unfortunately the current catering vehicle model doesn't allow animation.{{pending}}&lt;br /&gt;
* Animation of wheels. {{pending}}&lt;br /&gt;
* Check using ai.nas mentioned in [[Scripted_AI_Objects]]. {{pending}} (that's actually outdated meanwhile, [[Ground Services]] looks much more promising)&lt;br /&gt;
* Make it a Flightgear addon.  {{Progressbar|100}} {{done}}&lt;br /&gt;
* Add a canvas GUI for monitoring vehicles  {{Progressbar|100}} {{done}}&lt;br /&gt;
* Retrieve door positions from AI model like [[Howto:Animated jetways|animated jetways]] does. AI aircraft should contain a piece of nasal code that adds door information to the property tree when loaded. However, extending AI core code for saving model origin information to the property tree could still be useful, eg. for defining cockpit positions in addon [[Model Cockpit View]].  {{Progressbar|20}}&lt;br /&gt;
* Extend AI core code for saving departure/arrival information of AI aircrafts to the property tree. Thus arrived parking aircrafts can be detected for service more reliably. Such an extension might also be helpful for the [[Howto:Animated jetways|animated jetways]]. {{Progressbar|10}} {{pending}}&lt;br /&gt;
* Unify AI traffic categories for avoiding manual patches to [[Model Cockpit View]] and [[Phi]] by a Nasal registry for all kinds of AI/MP traffic, eg. AI.nas or Traffic.nas. &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=6&amp;amp;t=30735&amp;amp;p=323612&amp;amp;hilit=mapstructure.nas#p323588 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Ground services ! &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Dec 2nd, 2017 &lt;br /&gt;
  |added  =  Dec 2nd, 2017 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
}}&amp;lt;/ref&amp;gt; {{Progressbar|10}} {{pending}}&lt;br /&gt;
* Extend MapStructure.nas with a kind of layer registry for avoiding copying files into FG_ROOT. &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=6&amp;amp;t=30735&amp;amp;p=323612&amp;amp;hilit=mapstructure.nas#p323588 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Ground services ! &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Dec 2nd, 2017 &lt;br /&gt;
  |added  =  Dec 2nd, 2017 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
}}&amp;lt;/ref&amp;gt; . Latest tests show that no change to MapStructure.nas is required. The layer can just be added from the addon. Will be part of next release. {{Progressbar|100}} {{done}}&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
A followme vehicle on its way at EHAM.&lt;br /&gt;
&lt;br /&gt;
[[File:GroundServices-screen-007.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear add-ons]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=117586</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=117586"/>
		<updated>2019-03-11T05:19:49Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Status as of January 2019 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
=== controlling objects ===&lt;br /&gt;
The AI subsystem just takes care of hooking the model animation properties into the &amp;quot;/ai/models&amp;quot; subtree. Main control is performed by a Nasal module by triggering model animations.&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
The existing solution in jetways.nas for controlling jetways will be retained. For not affecting readability and increaing the complexity of jetways.nas, the core jetway funtionality will be extracted into a separate module/addon that supports the new jetway definition.&lt;br /&gt;
&lt;br /&gt;
The existing jetway solution by ICAO.jetways.xml will not be affected.&lt;br /&gt;
&lt;br /&gt;
== Status as of January 2019 ==&lt;br /&gt;
Due to the overall complexity and the number of involved components a few sub projects are isolated. These sub projects are intended to be just generic multi purpose extensions to FlightGear, which might later be combined for achieving the &amp;quot;big jetway solution&amp;quot;. The sub projects are:&lt;br /&gt;
&lt;br /&gt;
1)  {{Progressbar|100}} {{done}} An additional FG-Command interface to the AI subsystem (AIManager aso.). This provides a way to let the AI subsystem create a new object by just executing a FG-Command. The object built uses a PagedLOD and respects two level of degree, if a low res model file is provided. By using FG-Command this interface will be available from several components like Nasal, ReaderWriterSTG, Websockets, telnet, aso. If the model loaded contains animations, the animation properties will be located below the node in /ai/models/. AIManager will tranform these objects like other AI objects, ie. adjust its position/orientation from the corresponding properties. Removing an object will also be triggered by an FG-Command.&lt;br /&gt;
&lt;br /&gt;
This can be tested from Nasal console with&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
    var position = geo.aircraft_position();&lt;br /&gt;
    var course = getprop(&amp;quot;/orientation/heading-deg&amp;quot;);&lt;br /&gt;
    position.apply_course_distance(course,300);&lt;br /&gt;
    var info = geodinfo(position.lat(), position.lon());    &lt;br /&gt;
    var alt = num(info[0]);&lt;br /&gt;
      &lt;br /&gt;
    fgcommand(&amp;quot;add-aiobject&amp;quot;, props.Node.new({&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;static&amp;quot;,&lt;br /&gt;
        &amp;quot;model&amp;quot;:&amp;quot;Models/Airport/Jetway/j_generic_s.xml&amp;quot;,&lt;br /&gt;
        &amp;quot;model-lowres&amp;quot;:&amp;quot;Models/Buildings/silo.ac&amp;quot;,&lt;br /&gt;
        &amp;quot;latitude&amp;quot;: position.lat(),&lt;br /&gt;
        &amp;quot;longitude&amp;quot;: position.lon(),        &lt;br /&gt;
        &amp;quot;altitude&amp;quot;: alt*M2FT,&lt;br /&gt;
        &amp;quot;search-order&amp;quot;: &amp;quot;DATA_ONLY&amp;quot;&lt;br /&gt;
    }));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The original idea of using a property tree based interface inspired by ModelMgr has been dismissed.&lt;br /&gt;
&lt;br /&gt;
2) {{pending}} A property tree based interface to the AI subsystem (AIManager) that lets drive AIManager animation properties in its update() routine depending on the tpf value. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. This feature is especially useful for avoiding update loops in Nasal.&lt;br /&gt;
&lt;br /&gt;
3) {{pending}} A new keyword OBJECT_AI (or similar) for STG files to let ReaderSTG use the above feature no 1) for placing objects.&lt;br /&gt;
&lt;br /&gt;
4) {{pending}} An extended interface to the scenery database.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Template:PropertyTree&amp;diff=117382</id>
		<title>Template:PropertyTree</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Template:PropertyTree&amp;diff=117382"/>
		<updated>2019-02-18T05:41:06Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{sidebar&lt;br /&gt;
| name	= PropertyTree&lt;br /&gt;
| title = Property Tree&lt;br /&gt;
| contentstyle= text-align: left;&lt;br /&gt;
&lt;br /&gt;
| content1 = &lt;br /&gt;
* [[Property Tree|Intro]]&lt;br /&gt;
* [[Property Tree/Explained|Explained]]&lt;br /&gt;
* [[Property Tree Performance]]&lt;br /&gt;
* [[Property browser]]&lt;br /&gt;
* [[PropertyList XML_File|PropertyList XML Files]]&lt;br /&gt;
* [[FlightGear configuration via XML|Configuration via XML]]&lt;br /&gt;
* [[FlightGear I/O Considerations]]&lt;br /&gt;
* [[Property Tree/Web Server|Built-in Web Server]]&lt;br /&gt;
* [[Telnet usage]]&lt;br /&gt;
* [[Logging properties]] (CSV)&lt;br /&gt;
* [[Generic protocol]] (XML configurable)&lt;br /&gt;
* [[Howto:Port I/O from Nasal]]&lt;br /&gt;
* [[Howto:Parsing binary data received via UDP in C]]&lt;br /&gt;
* [[Howto:Making HTTP Requests from Nasal|Web Service Interfacing]]&lt;br /&gt;
* [[Property Tree/Native Protocol Slaving|Slaving multiple instances]]&lt;br /&gt;
* [[Property Tree/Sockets|Native Protocols]] (C++)&lt;br /&gt;
* [[Aircraft properties reference]]&lt;br /&gt;
* [[Howto:Working with the Property Tree API|Property Tree C++ API]]&lt;br /&gt;
* [[Howto:Use Property Tree Objects]]&lt;br /&gt;
* [[Properties persistant between sessions]]&lt;br /&gt;
* [[Recommended Property Tree Enhancements|Property Tree Ideas]] (RFC)&lt;br /&gt;
* [[Json Properties]]&lt;br /&gt;
* [[Property Tree Future]]&lt;br /&gt;
}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{-}}&lt;br /&gt;
{{Informative template|1=&lt;br /&gt;
__NOTOC__&lt;br /&gt;
== Goal ==&lt;br /&gt;
This template is used on top of [[property tree]] related articles.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
Add this to the top of the article:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;{{PropertyTree}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Navigation templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Json_Properties&amp;diff=117381</id>
		<title>Json Properties</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Json_Properties&amp;diff=117381"/>
		<updated>2019-02-18T05:36:56Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Abstract ==&lt;br /&gt;
Beginning with the developer version 3.1 and the indroduction of the advanced internal web server, the access to internal properties via web services have been introduced. The properties are represented as [http://www.json.org/ JSON]. This Article contains the format description of JSON properties.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
This is an example of the /sim/time subtree:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;path&amp;quot;:	&amp;quot;/sim/time&amp;quot;,&lt;br /&gt;
	&amp;quot;name&amp;quot;:	&amp;quot;time&amp;quot;,&lt;br /&gt;
	&amp;quot;type&amp;quot;:	&amp;quot;-&amp;quot;,&lt;br /&gt;
	&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
	&amp;quot;nChildren&amp;quot;:	12,&lt;br /&gt;
	&amp;quot;children&amp;quot;:	[{&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/cur-time-override&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;cur-time-override&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;0&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;long&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/delta-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;delta-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;0.01666666667&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;double&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/warp&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;warp&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;-28320&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;int&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/warp-delta&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;warp-delta&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;0&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;int&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/delta-realtime-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;delta-realtime-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;0.01666666667&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;double&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/local-offset&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;local-offset&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;3600&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;int&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/utc&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;utc&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;-&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	8&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/real&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;real&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;-&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	7&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/elapsed-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;elapsed-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;7072.525&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;double&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/gmt&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;gmt&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;2014-03-27T13:25:10&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;string&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/gmt-string&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;gmt-string&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;13:25:10&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;string&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/sun-angle-rad&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;sun-angle-rad&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;0.9883239645&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;double&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
* JavaScript Object Notation (JSON), and the terms object, name, value, array, and number, are defined in [http://www.ietf.org/rfc/rfc4627.txt IETF RTC 4627].&lt;br /&gt;
* The key words &amp;quot;MUST&amp;quot;, &amp;quot;MUST NOT&amp;quot;, &amp;quot;REQUIRED&amp;quot;, &amp;quot;SHALL&amp;quot;, &amp;quot;SHALL NOT&amp;quot;, &amp;quot;SHOULD&amp;quot;, &amp;quot;SHOULD NOT&amp;quot;, &amp;quot;RECOMMENDED&amp;quot;, &amp;quot;MAY&amp;quot;, and &amp;quot;OPTIONAL&amp;quot; in this document are to be interpreted as described in [http://www.ietf.org/rfc/rfc2119.txt IETF RFC 2119].&lt;br /&gt;
&lt;br /&gt;
== Property Objects ==&lt;br /&gt;
A Property Object always consist of a single object. This object represents a single property node or a complete (sub) tree of nodes.&lt;br /&gt;
&lt;br /&gt;
* Each object must have a member with the name ''path''. The members value is a string naming the absolute path of the node in the property tree. Example: '''/engines/engine[1]'''&lt;br /&gt;
* Each object must have a member with the name ''name''. The members value is a string that determines the name of the node. Example: '''engine'''&lt;br /&gt;
* Each object may have a member with the name ''value''. The members value contains the property nodes value. The current server implementation returns property node values by using the getStringValue() function.&lt;br /&gt;
* Each object must have a member with the name ''type''. The members value must be on of &amp;quot;-&amp;quot; (for no type), &amp;quot;alias&amp;quot;, &amp;quot;bool&amp;quot;, &amp;quot;int&amp;quot;, &amp;quot;long&amp;quot;, &amp;quot;float&amp;quot;, &amp;quot;double&amp;quot;, &amp;quot;string&amp;quot;, &amp;quot;unspecified&amp;quot;, &amp;quot;extended&amp;quot;, &amp;quot;vec3d&amp;quot; or &amp;quot;vec4d&amp;quot;.&lt;br /&gt;
* Each object may have a member with the name ''index''. The members value determines the index of the node in the parents node. Example: For a node /engines/engine[1] this would be 1. A missing ''index'' attribute results in an index of 0 (zero).&lt;br /&gt;
* Each object may have a member with the name ''ts''. The members value represents the time when the server read node from the property tree. This is the time of /sim/time/elapsed-sec.&lt;br /&gt;
* Each object may have a member with the name ''nChildren''. The members value determines the number of children under this node. It is optional to actually display the children itself within the JSON object. &lt;br /&gt;
* Each object may have a member with the name ''children''. The members value is an array of JSON Property Objects.&lt;br /&gt;
&lt;br /&gt;
== Accessing the Property Tree ==&lt;br /&gt;
=== The web service ===&lt;br /&gt;
A simple web service provides read-only access to the property tree. This web service can be reached at the URL http://localhost:port/json&lt;br /&gt;
where port is the portnumber provided to the -httpd= startup option. Path elements following that URL are interpreted as a property path, so http://localhost:port/json/sim/time returnes the JSON representation of the property node /sim/time and its immediate children (see example above). &lt;br /&gt;
The service understands the following request parameters:&lt;br /&gt;
* i - if the request parameter i is set to 'y', the output will be indented to make it more readable by humans. If the parameter is missing or assigned any other value, the output will be compressed.&lt;br /&gt;
* t - if the request parameter t is set to 'y', the returned properties will be time stamped with the value of simulation time &lt;br /&gt;
* d - the recursion depth of the resulting tree. The default and minimum depth is implemented as 1 resulting in the node itself and - if existing - the immediate children of the node. A value of 2 would return the node itself, it's children and their children. A very high value combined with a request for the root node returns a complete dump of the property tree (use this with caution!)&lt;br /&gt;
&lt;br /&gt;
=== The /PropertyListener websocket ===&lt;br /&gt;
The property change listener websocket also sends property objects as change events for the subscribed nodes. The following is a simple HTML page that shows its usage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Sample on how to use a websocket PropertyListener.                --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Extracted from code in Phi.                                       --&amp;gt;&lt;br /&gt;
&amp;lt;!-- FlightGear must be started with HTTP server enabled on port 5701. --&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;GMT time in Flightgear: &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;myText&amp;quot; value=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Click the button to launch the property listener for property /sim/time/gmt.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;button onclick=&amp;quot;myFunction()&amp;quot;&amp;gt;Launch&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function myFunction() {&lt;br /&gt;
    var textfield = document.getElementById(&amp;quot;myText&amp;quot;);&lt;br /&gt;
    var ws = new WebSocket('ws://localhost:5701/PropertyListener')&lt;br /&gt;
    console.log('web socket readyState is ' + ws.readyState)&lt;br /&gt;
    ws.onopen = function (ev) {&lt;br /&gt;
      console.log('onopen')&lt;br /&gt;
      ws.send(JSON.stringify({&lt;br /&gt;
        command: 'addListener',&lt;br /&gt;
        node: 'sim/time/gmt'&lt;br /&gt;
      }))&lt;br /&gt;
    }&lt;br /&gt;
    ws.onmessage = function (ev) {&lt;br /&gt;
      try {&lt;br /&gt;
        var data = JSON.parse(ev.data)&lt;br /&gt;
        textfield.value = data.value&lt;br /&gt;
      } catch (e) {&lt;br /&gt;
        console.log('Exception in onmessage:' + e)&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    ws.onclose = function (ev) {&lt;br /&gt;
      var msg = 'Lost connection to FlightGear.'&lt;br /&gt;
      alert(msg)&lt;br /&gt;
    }&lt;br /&gt;
    ws.onerror = function (ev) {&lt;br /&gt;
      var msg = 'Error communicating with FlightGear.'&lt;br /&gt;
      alert(msg)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pitfalls ==&lt;br /&gt;
* calling http://localhost:port/json results in a 404 (Not found) error. Use http://localhost:port/json/ to access the root node.&lt;br /&gt;
* asking for a nonexistant node returns an empty object ''{}''&lt;br /&gt;
&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Json_Properties&amp;diff=117380</id>
		<title>Json Properties</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Json_Properties&amp;diff=117380"/>
		<updated>2019-02-18T05:36:30Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{PropertyTree}}&lt;br /&gt;
== Abstract ==&lt;br /&gt;
Beginning with the developer version 3.1 and the indroduction of the advanced internal web server, the access to internal properties via web services have been introduced. The properties are represented as [http://www.json.org/ JSON]. This Article contains the format description of JSON properties.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
This is an example of the /sim/time subtree:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;path&amp;quot;:	&amp;quot;/sim/time&amp;quot;,&lt;br /&gt;
	&amp;quot;name&amp;quot;:	&amp;quot;time&amp;quot;,&lt;br /&gt;
	&amp;quot;type&amp;quot;:	&amp;quot;-&amp;quot;,&lt;br /&gt;
	&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
	&amp;quot;nChildren&amp;quot;:	12,&lt;br /&gt;
	&amp;quot;children&amp;quot;:	[{&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/cur-time-override&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;cur-time-override&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;0&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;long&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/delta-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;delta-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;0.01666666667&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;double&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/warp&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;warp&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;-28320&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;int&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/warp-delta&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;warp-delta&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;0&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;int&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/delta-realtime-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;delta-realtime-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;0.01666666667&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;double&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/local-offset&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;local-offset&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;3600&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;int&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/utc&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;utc&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;-&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	8&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/real&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;real&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;-&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	7&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/elapsed-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;elapsed-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;7072.525&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;double&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/gmt&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;gmt&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;2014-03-27T13:25:10&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;string&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/gmt-string&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;gmt-string&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;13:25:10&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;string&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/sun-angle-rad&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;sun-angle-rad&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;0.9883239645&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;double&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
* JavaScript Object Notation (JSON), and the terms object, name, value, array, and number, are defined in [http://www.ietf.org/rfc/rfc4627.txt IETF RTC 4627].&lt;br /&gt;
* The key words &amp;quot;MUST&amp;quot;, &amp;quot;MUST NOT&amp;quot;, &amp;quot;REQUIRED&amp;quot;, &amp;quot;SHALL&amp;quot;, &amp;quot;SHALL NOT&amp;quot;, &amp;quot;SHOULD&amp;quot;, &amp;quot;SHOULD NOT&amp;quot;, &amp;quot;RECOMMENDED&amp;quot;, &amp;quot;MAY&amp;quot;, and &amp;quot;OPTIONAL&amp;quot; in this document are to be interpreted as described in [http://www.ietf.org/rfc/rfc2119.txt IETF RFC 2119].&lt;br /&gt;
&lt;br /&gt;
== Property Objects ==&lt;br /&gt;
A Property Object always consist of a single object. This object represents a single property node or a complete (sub) tree of nodes.&lt;br /&gt;
&lt;br /&gt;
* Each object must have a member with the name ''path''. The members value is a string naming the absolute path of the node in the property tree. Example: '''/engines/engine[1]'''&lt;br /&gt;
* Each object must have a member with the name ''name''. The members value is a string that determines the name of the node. Example: '''engine'''&lt;br /&gt;
* Each object may have a member with the name ''value''. The members value contains the property nodes value. The current server implementation returns property node values by using the getStringValue() function.&lt;br /&gt;
* Each object must have a member with the name ''type''. The members value must be on of &amp;quot;-&amp;quot; (for no type), &amp;quot;alias&amp;quot;, &amp;quot;bool&amp;quot;, &amp;quot;int&amp;quot;, &amp;quot;long&amp;quot;, &amp;quot;float&amp;quot;, &amp;quot;double&amp;quot;, &amp;quot;string&amp;quot;, &amp;quot;unspecified&amp;quot;, &amp;quot;extended&amp;quot;, &amp;quot;vec3d&amp;quot; or &amp;quot;vec4d&amp;quot;.&lt;br /&gt;
* Each object may have a member with the name ''index''. The members value determines the index of the node in the parents node. Example: For a node /engines/engine[1] this would be 1. A missing ''index'' attribute results in an index of 0 (zero).&lt;br /&gt;
* Each object may have a member with the name ''ts''. The members value represents the time when the server read node from the property tree. This is the time of /sim/time/elapsed-sec.&lt;br /&gt;
* Each object may have a member with the name ''nChildren''. The members value determines the number of children under this node. It is optional to actually display the children itself within the JSON object. &lt;br /&gt;
* Each object may have a member with the name ''children''. The members value is an array of JSON Property Objects.&lt;br /&gt;
&lt;br /&gt;
== Accessing the Property Tree ==&lt;br /&gt;
=== The web service ===&lt;br /&gt;
A simple web service provides read-only access to the property tree. This web service can be reached at the URL http://localhost:port/json&lt;br /&gt;
where port is the portnumber provided to the -httpd= startup option. Path elements following that URL are interpreted as a property path, so http://localhost:port/json/sim/time returnes the JSON representation of the property node /sim/time and its immediate children (see example above). &lt;br /&gt;
The service understands the following request parameters:&lt;br /&gt;
* i - if the request parameter i is set to 'y', the output will be indented to make it more readable by humans. If the parameter is missing or assigned any other value, the output will be compressed.&lt;br /&gt;
* t - if the request parameter t is set to 'y', the returned properties will be time stamped with the value of simulation time &lt;br /&gt;
* d - the recursion depth of the resulting tree. The default and minimum depth is implemented as 1 resulting in the node itself and - if existing - the immediate children of the node. A value of 2 would return the node itself, it's children and their children. A very high value combined with a request for the root node returns a complete dump of the property tree (use this with caution!)&lt;br /&gt;
&lt;br /&gt;
=== The /PropertyListener websocket ===&lt;br /&gt;
The property change listener websocket also sends property objects as change events for the subscribed nodes. The following is a simple HTML page that shows its usage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Sample on how to use a websocket PropertyListener.                --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Extracted from code in Phi.                                       --&amp;gt;&lt;br /&gt;
&amp;lt;!-- FlightGear must be started with HTTP server enabled on port 5701. --&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;GMT time in Flightgear: &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;myText&amp;quot; value=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Click the button to launch the property listener for property /sim/time/gmt.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;button onclick=&amp;quot;myFunction()&amp;quot;&amp;gt;Launch&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function myFunction() {&lt;br /&gt;
    var textfield = document.getElementById(&amp;quot;myText&amp;quot;);&lt;br /&gt;
    var ws = new WebSocket('ws://localhost:5701/PropertyListener')&lt;br /&gt;
    console.log('web socket readyState is ' + ws.readyState)&lt;br /&gt;
    ws.onopen = function (ev) {&lt;br /&gt;
      console.log('onopen')&lt;br /&gt;
      ws.send(JSON.stringify({&lt;br /&gt;
        command: 'addListener',&lt;br /&gt;
        node: 'sim/time/gmt'&lt;br /&gt;
      }))&lt;br /&gt;
    }&lt;br /&gt;
    ws.onmessage = function (ev) {&lt;br /&gt;
      try {&lt;br /&gt;
        var data = JSON.parse(ev.data)&lt;br /&gt;
        textfield.value = data.value&lt;br /&gt;
      } catch (e) {&lt;br /&gt;
        console.log('Exception in onmessage:' + e)&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    ws.onclose = function (ev) {&lt;br /&gt;
      var msg = 'Lost connection to FlightGear.'&lt;br /&gt;
      alert(msg)&lt;br /&gt;
    }&lt;br /&gt;
    ws.onerror = function (ev) {&lt;br /&gt;
      var msg = 'Error communicating with FlightGear.'&lt;br /&gt;
      alert(msg)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pitfalls ==&lt;br /&gt;
* calling http://localhost:port/json results in a 404 (Not found) error. Use http://localhost:port/json/ to access the root node.&lt;br /&gt;
* asking for a nonexistant node returns an empty object ''{}''&lt;br /&gt;
&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Json_Properties&amp;diff=117379</id>
		<title>Json Properties</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Json_Properties&amp;diff=117379"/>
		<updated>2019-02-18T05:26:06Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* The /PropertyListener websocket */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Abstract ==&lt;br /&gt;
Beginning with the developer version 3.1 and the indroduction of the advanced internal web server, the access to internal properties via web services have been introduced. The properties are represented as [http://www.json.org/ JSON]. This Article contains the format description of JSON properties.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
This is an example of the /sim/time subtree:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;path&amp;quot;:	&amp;quot;/sim/time&amp;quot;,&lt;br /&gt;
	&amp;quot;name&amp;quot;:	&amp;quot;time&amp;quot;,&lt;br /&gt;
	&amp;quot;type&amp;quot;:	&amp;quot;-&amp;quot;,&lt;br /&gt;
	&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
	&amp;quot;nChildren&amp;quot;:	12,&lt;br /&gt;
	&amp;quot;children&amp;quot;:	[{&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/cur-time-override&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;cur-time-override&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;0&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;long&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/delta-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;delta-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;0.01666666667&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;double&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/warp&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;warp&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;-28320&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;int&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/warp-delta&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;warp-delta&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;0&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;int&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/delta-realtime-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;delta-realtime-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;0.01666666667&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;double&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/local-offset&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;local-offset&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;3600&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;int&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/utc&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;utc&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;-&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	8&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/real&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;real&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;-&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	7&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/elapsed-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;elapsed-sec&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;7072.525&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;double&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/gmt&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;gmt&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;2014-03-27T13:25:10&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;string&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/gmt-string&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;gmt-string&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;13:25:10&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;string&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}, {&lt;br /&gt;
			&amp;quot;path&amp;quot;:	&amp;quot;/sim/time/sun-angle-rad&amp;quot;,&lt;br /&gt;
			&amp;quot;name&amp;quot;:	&amp;quot;sun-angle-rad&amp;quot;,&lt;br /&gt;
			&amp;quot;value&amp;quot;:	&amp;quot;0.9883239645&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;:	&amp;quot;double&amp;quot;,&lt;br /&gt;
			&amp;quot;index&amp;quot;:	0,&lt;br /&gt;
			&amp;quot;nChildren&amp;quot;:	0&lt;br /&gt;
		}]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
* JavaScript Object Notation (JSON), and the terms object, name, value, array, and number, are defined in [http://www.ietf.org/rfc/rfc4627.txt IETF RTC 4627].&lt;br /&gt;
* The key words &amp;quot;MUST&amp;quot;, &amp;quot;MUST NOT&amp;quot;, &amp;quot;REQUIRED&amp;quot;, &amp;quot;SHALL&amp;quot;, &amp;quot;SHALL NOT&amp;quot;, &amp;quot;SHOULD&amp;quot;, &amp;quot;SHOULD NOT&amp;quot;, &amp;quot;RECOMMENDED&amp;quot;, &amp;quot;MAY&amp;quot;, and &amp;quot;OPTIONAL&amp;quot; in this document are to be interpreted as described in [http://www.ietf.org/rfc/rfc2119.txt IETF RFC 2119].&lt;br /&gt;
&lt;br /&gt;
== Property Objects ==&lt;br /&gt;
A Property Object always consist of a single object. This object represents a single property node or a complete (sub) tree of nodes.&lt;br /&gt;
&lt;br /&gt;
* Each object must have a member with the name ''path''. The members value is a string naming the absolute path of the node in the property tree. Example: '''/engines/engine[1]'''&lt;br /&gt;
* Each object must have a member with the name ''name''. The members value is a string that determines the name of the node. Example: '''engine'''&lt;br /&gt;
* Each object may have a member with the name ''value''. The members value contains the property nodes value. The current server implementation returns property node values by using the getStringValue() function.&lt;br /&gt;
* Each object must have a member with the name ''type''. The members value must be on of &amp;quot;-&amp;quot; (for no type), &amp;quot;alias&amp;quot;, &amp;quot;bool&amp;quot;, &amp;quot;int&amp;quot;, &amp;quot;long&amp;quot;, &amp;quot;float&amp;quot;, &amp;quot;double&amp;quot;, &amp;quot;string&amp;quot;, &amp;quot;unspecified&amp;quot;, &amp;quot;extended&amp;quot;, &amp;quot;vec3d&amp;quot; or &amp;quot;vec4d&amp;quot;.&lt;br /&gt;
* Each object may have a member with the name ''index''. The members value determines the index of the node in the parents node. Example: For a node /engines/engine[1] this would be 1. A missing ''index'' attribute results in an index of 0 (zero).&lt;br /&gt;
* Each object may have a member with the name ''ts''. The members value represents the time when the server read node from the property tree. This is the time of /sim/time/elapsed-sec.&lt;br /&gt;
* Each object may have a member with the name ''nChildren''. The members value determines the number of children under this node. It is optional to actually display the children itself within the JSON object. &lt;br /&gt;
* Each object may have a member with the name ''children''. The members value is an array of JSON Property Objects.&lt;br /&gt;
&lt;br /&gt;
== Accessing the Property Tree ==&lt;br /&gt;
=== The web service ===&lt;br /&gt;
A simple web service provides read-only access to the property tree. This web service can be reached at the URL http://localhost:port/json&lt;br /&gt;
where port is the portnumber provided to the -httpd= startup option. Path elements following that URL are interpreted as a property path, so http://localhost:port/json/sim/time returnes the JSON representation of the property node /sim/time and its immediate children (see example above). &lt;br /&gt;
The service understands the following request parameters:&lt;br /&gt;
* i - if the request parameter i is set to 'y', the output will be indented to make it more readable by humans. If the parameter is missing or assigned any other value, the output will be compressed.&lt;br /&gt;
* t - if the request parameter t is set to 'y', the returned properties will be time stamped with the value of simulation time &lt;br /&gt;
* d - the recursion depth of the resulting tree. The default and minimum depth is implemented as 1 resulting in the node itself and - if existing - the immediate children of the node. A value of 2 would return the node itself, it's children and their children. A very high value combined with a request for the root node returns a complete dump of the property tree (use this with caution!)&lt;br /&gt;
&lt;br /&gt;
=== The /PropertyListener websocket ===&lt;br /&gt;
The property change listener websocket also sends property objects as change events for the subscribed nodes. The following is a simple HTML page that shows its usage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Sample on how to use a websocket PropertyListener.                --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Extracted from code in Phi.                                       --&amp;gt;&lt;br /&gt;
&amp;lt;!-- FlightGear must be started with HTTP server enabled on port 5701. --&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;GMT time in Flightgear: &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;myText&amp;quot; value=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Click the button to launch the property listener for property /sim/time/gmt.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;button onclick=&amp;quot;myFunction()&amp;quot;&amp;gt;Launch&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function myFunction() {&lt;br /&gt;
    var textfield = document.getElementById(&amp;quot;myText&amp;quot;);&lt;br /&gt;
    var ws = new WebSocket('ws://localhost:5701/PropertyListener')&lt;br /&gt;
    console.log('web socket readyState is ' + ws.readyState)&lt;br /&gt;
    ws.onopen = function (ev) {&lt;br /&gt;
      console.log('onopen')&lt;br /&gt;
      ws.send(JSON.stringify({&lt;br /&gt;
        command: 'addListener',&lt;br /&gt;
        node: 'sim/time/gmt'&lt;br /&gt;
      }))&lt;br /&gt;
    }&lt;br /&gt;
    ws.onmessage = function (ev) {&lt;br /&gt;
      try {&lt;br /&gt;
        var data = JSON.parse(ev.data)&lt;br /&gt;
        textfield.value = data.value&lt;br /&gt;
      } catch (e) {&lt;br /&gt;
        console.log('Exception in onmessage:' + e)&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    ws.onclose = function (ev) {&lt;br /&gt;
      var msg = 'Lost connection to FlightGear.'&lt;br /&gt;
      alert(msg)&lt;br /&gt;
    }&lt;br /&gt;
    ws.onerror = function (ev) {&lt;br /&gt;
      var msg = 'Error communicating with FlightGear.'&lt;br /&gt;
      alert(msg)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pitfalls ==&lt;br /&gt;
* calling http://localhost:port/json results in a 404 (Not found) error. Use http://localhost:port/json/ to access the root node.&lt;br /&gt;
* asking for a nonexistant node returns an empty object ''{}''&lt;br /&gt;
&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117175</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117175"/>
		<updated>2019-01-23T06:53:25Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas textures via httpd &lt;br /&gt;
|status = Available as of 2018.3.1 (still might cause stability problems) &lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
This solution was created roughly by:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
There are possible alternative solutions for rendering canvases on a remote system, that remove the rendering load from the main flightgear process. These might be based on Nasal, Javascript, Python, etc.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One currently available solution is [[FGQCanvas]], created by James.&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
http://localhost:5701/screenshot?canvasindex=4&amp;amp;type=png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 4 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 4 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout). For the 777-200 canvas index 4 is the ND, 5 the MFD. PFD seems not to use Canvas.&lt;br /&gt;
&lt;br /&gt;
=== Sample Showcase CanvasView.html ===&lt;br /&gt;
The following showcase HTML snippet  CanvasView.html shows the main instruments of Soitanens 737 (and its branches) with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load. The script contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/screenshot?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussion ==&lt;br /&gt;
The forum thread for discussing this feature is https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;start=15.&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117174</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117174"/>
		<updated>2019-01-23T06:53:05Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Available as of 2018.3.1 (still might cause stability problems) &lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
This solution was created roughly by:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
There are possible alternative solutions for rendering canvases on a remote system, that remove the rendering load from the main flightgear process. These might be based on Nasal, Javascript, Python, etc.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One currently available solution is [[FGQCanvas]], created by James.&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
http://localhost:5701/screenshot?canvasindex=4&amp;amp;type=png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 4 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 4 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout). For the 777-200 canvas index 4 is the ND, 5 the MFD. PFD seems not to use Canvas.&lt;br /&gt;
&lt;br /&gt;
=== Sample Showcase CanvasView.html ===&lt;br /&gt;
The following showcase HTML snippet  CanvasView.html shows the main instruments of Soitanens 737 (and its branches) with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load. The script contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/screenshot?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussion ==&lt;br /&gt;
The forum thread for discussing this feature is https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;start=15.&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117173</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117173"/>
		<updated>2019-01-23T06:51:58Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: &amp;quot;unstable&amp;quot; removed and state set to &amp;quot;available&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Available as of 2018.3.1&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
This solution was created roughly by:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
There are possible alternative solutions for rendering canvases on a remote system, that remove the rendering load from the main flightgear process. These might be based on Nasal, Javascript, Python, etc.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One currently available solution is [[FGQCanvas]], created by James.&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
http://localhost:5701/screenshot?canvasindex=4&amp;amp;type=png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 4 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 4 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout). For the 777-200 canvas index 4 is the ND, 5 the MFD. PFD seems not to use Canvas.&lt;br /&gt;
&lt;br /&gt;
=== Sample Showcase CanvasView.html ===&lt;br /&gt;
The following showcase HTML snippet  CanvasView.html shows the main instruments of Soitanens 737 (and its branches) with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load. The script contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/screenshot?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussion ==&lt;br /&gt;
The forum thread for discussing this feature is https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;start=15.&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117172</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117172"/>
		<updated>2019-01-23T06:47:20Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Sample Showcase CanvasView.html */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Under active development as of 10/2016&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
This solution was created roughly by:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
There are possible alternative solutions for rendering canvases on a remote system, that remove the rendering load from the main flightgear process. These might be based on Nasal, Javascript, Python, etc.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One currently available solution is [[FGQCanvas]], created by James.&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
http://localhost:5701/screenshot?canvasindex=4&amp;amp;type=png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 4 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 4 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout). For the 777-200 canvas index 4 is the ND, 5 the MFD. PFD seems not to use Canvas.&lt;br /&gt;
&lt;br /&gt;
=== Sample Showcase CanvasView.html ===&lt;br /&gt;
The following showcase HTML snippet  CanvasView.html shows the main instruments of Soitanens 737 (and its branches) with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load. The script contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/screenshot?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussion ==&lt;br /&gt;
The forum thread for discussing this feature is https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;start=15.&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117171</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117171"/>
		<updated>2019-01-23T06:42:10Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Sample Showcase CanvasView.html */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Under active development as of 10/2016&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
This solution was created roughly by:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
There are possible alternative solutions for rendering canvases on a remote system, that remove the rendering load from the main flightgear process. These might be based on Nasal, Javascript, Python, etc.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One currently available solution is [[FGQCanvas]], created by James.&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
http://localhost:5701/screenshot?canvasindex=4&amp;amp;type=png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 4 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 4 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout). For the 777-200 canvas index 4 is the ND, 5 the MFD. PFD seems not to use Canvas.&lt;br /&gt;
&lt;br /&gt;
=== Sample Showcase CanvasView.html ===&lt;br /&gt;
The following showcase script CanvasView.html shows the main instruments of Soitanens 737 with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load.&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/screenshot?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussion ==&lt;br /&gt;
The forum thread for discussing this feature is https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;start=15.&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117170</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117170"/>
		<updated>2019-01-23T06:35:20Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Using */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Under active development as of 10/2016&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
This solution was created roughly by:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
There are possible alternative solutions for rendering canvases on a remote system, that remove the rendering load from the main flightgear process. These might be based on Nasal, Javascript, Python, etc.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One currently available solution is [[FGQCanvas]], created by James.&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
http://localhost:5701/screenshot?canvasindex=4&amp;amp;type=png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 4 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 4 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout). For the 777-200 canvas index 4 is the ND, 5 the MFD. PFD seems not to use Canvas.&lt;br /&gt;
&lt;br /&gt;
=== Sample Showcase CanvasView.html ===&lt;br /&gt;
The following showcase script CanvasView.html shows the main instruments of Soitanens 737 with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load.&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //alert(url);&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussion ==&lt;br /&gt;
The forum thread for discussing this feature is https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;start=15.&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117164</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117164"/>
		<updated>2019-01-21T07:40:13Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Alternatives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Under active development as of 10/2016&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
This solution was created roughly by:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
There are possible alternative solutions for rendering canvases on a remote system, that remove the rendering load from the main flightgear process. These might be based on Nasal, Javascript, Python, etc.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One currently available solution is [[FGQCanvas]], created by James.&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
localhost:5701/canvasimage?type=png&amp;amp;canvasindex=0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 0 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 0 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout).&lt;br /&gt;
&lt;br /&gt;
=== Sample Showcase CanvasView.html ===&lt;br /&gt;
The following showcase script CanvasView.html shows the main instruments of Soitanens 737 with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load.&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //alert(url);&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussion ==&lt;br /&gt;
The forum thread for discussing this feature is https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;start=15.&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117163</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117163"/>
		<updated>2019-01-21T07:37:28Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Comments */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Under active development as of 10/2016&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
This solution was created roughly by:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
There are possible alternative solutions for rendering canvases on a remote system, that remove the rendering load from the main flightgear process. These might be based on Nasal, Javascript, Python, etc.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One currently available solution is ..., created by James.&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
localhost:5701/canvasimage?type=png&amp;amp;canvasindex=0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 0 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 0 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout).&lt;br /&gt;
&lt;br /&gt;
=== Sample Showcase CanvasView.html ===&lt;br /&gt;
The following showcase script CanvasView.html shows the main instruments of Soitanens 737 with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load.&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //alert(url);&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussion ==&lt;br /&gt;
The forum thread for discussing this feature is https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;start=15.&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117162</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117162"/>
		<updated>2019-01-21T07:34:40Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Using */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Under active development as of 10/2016&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
This solution was created roughly by:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
There are possible alternative solutions for rendering canvases on a remote system, that remove the rendering load from the main flightgear process. These might be based on Nasal, Javascript, Python, etc.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One currently available solution is ..., created by James.&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
localhost:5701/canvasimage?type=png&amp;amp;canvasindex=0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 0 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 0 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout).&lt;br /&gt;
&lt;br /&gt;
=== Sample Showcase CanvasView.html ===&lt;br /&gt;
The following showcase script CanvasView.html shows the main instruments of Soitanens 737 with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load.&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //alert(url);&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
The forum thread for discussing this feature is ...&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117161</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117161"/>
		<updated>2019-01-21T07:31:09Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Under active development as of 10/2016&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
This solution was created roughly by:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
There are possible alternative solutions for rendering canvases on a remote system, that remove the rendering load from the main flightgear process. These might be based on Nasal, Javascript, Python, etc.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One currently available solution is ..., created by James.&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
localhost:5701/canvasimage?type=png&amp;amp;canvasindex=0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 0 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 0 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout).&lt;br /&gt;
&lt;br /&gt;
=== Sample Showcase CanvasView.html ===&lt;br /&gt;
The following showcase script CanvasView.html shows the main instruments of Soitanens 737 with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load.&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //alert(url);&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117160</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117160"/>
		<updated>2019-01-21T07:21:52Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Patches */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Under active development as of 10/2016&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
What I did now roughly is:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
This works so far and I can grab ND images from my browser by http like a screenshot. And as you mentioned before, there are latencies and it isn't efficient. Just creating the PNG image from OSG takes up to 100ms. Using an uncomressed bitmap format like tiff results in 3MB image sies. Assuming a frame rate of 5 will be sufficient for displaying smooth instruments (which I doubt) this results in 15 image creations per second (for Captains PFD, ND and Eicas). &lt;br /&gt;
&lt;br /&gt;
However, it is working and I will use this approach for my first setup and for some long running tests for checking for memory leaks and other problems. Probably there will be some fine tuning required. &lt;br /&gt;
And in the meantime I keep thinking about an external canvas drawing solution. Maybe I'll pursue the Nasal/Javascript approach, though my personal favorite is a Nasal/generic approach which allows implementing drawing in any environment like JavaScript/Python/Java aso.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
localhost:5701/canvasimage?type=png&amp;amp;canvasindex=0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 0 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 0 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout).&lt;br /&gt;
&lt;br /&gt;
=== Sample Showcase CanvasView.html ===&lt;br /&gt;
The following showcase script CanvasView.html shows the main instruments of Soitanens 737 with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load.&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //alert(url);&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117159</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117159"/>
		<updated>2019-01-21T07:21:40Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Base Package */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Under active development as of 10/2016&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
What I did now roughly is:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
This works so far and I can grab ND images from my browser by http like a screenshot. And as you mentioned before, there are latencies and it isn't efficient. Just creating the PNG image from OSG takes up to 100ms. Using an uncomressed bitmap format like tiff results in 3MB image sies. Assuming a frame rate of 5 will be sufficient for displaying smooth instruments (which I doubt) this results in 15 image creations per second (for Captains PFD, ND and Eicas). &lt;br /&gt;
&lt;br /&gt;
However, it is working and I will use this approach for my first setup and for some long running tests for checking for memory leaks and other problems. Probably there will be some fine tuning required. &lt;br /&gt;
And in the meantime I keep thinking about an external canvas drawing solution. Maybe I'll pursue the Nasal/Javascript approach, though my personal favorite is a Nasal/generic approach which allows implementing drawing in any environment like JavaScript/Python/Java aso.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Patches ==&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
localhost:5701/canvasimage?type=png&amp;amp;canvasindex=0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 0 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 0 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout).&lt;br /&gt;
&lt;br /&gt;
=== Sample Showcase CanvasView.html ===&lt;br /&gt;
The following showcase script CanvasView.html shows the main instruments of Soitanens 737 with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load.&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //alert(url);&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117158</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117158"/>
		<updated>2019-01-21T07:19:44Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Using */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Under active development as of 10/2016&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
What I did now roughly is:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
This works so far and I can grab ND images from my browser by http like a screenshot. And as you mentioned before, there are latencies and it isn't efficient. Just creating the PNG image from OSG takes up to 100ms. Using an uncomressed bitmap format like tiff results in 3MB image sies. Assuming a frame rate of 5 will be sufficient for displaying smooth instruments (which I doubt) this results in 15 image creations per second (for Captains PFD, ND and Eicas). &lt;br /&gt;
&lt;br /&gt;
However, it is working and I will use this approach for my first setup and for some long running tests for checking for memory leaks and other problems. Probably there will be some fine tuning required. &lt;br /&gt;
And in the meantime I keep thinking about an external canvas drawing solution. Maybe I'll pursue the Nasal/Javascript approach, though my personal favorite is a Nasal/generic approach which allows implementing drawing in any environment like JavaScript/Python/Java aso.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Patches ==&lt;br /&gt;
=== Base Package ===&lt;br /&gt;
CanvasView.html&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. Also, you need to edit httpd-settings.xml to add a corresponding canvasimage handler there. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //alert(url);&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
localhost:5701/canvasimage?type=png&amp;amp;canvasindex=0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 0 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 0 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout).&lt;br /&gt;
&lt;br /&gt;
=== Sample Showcase CanvasView.html ===&lt;br /&gt;
The following showcase script CanvasView.html shows the main instruments of Soitanens 737 with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load.&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //alert(url);&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117157</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117157"/>
		<updated>2019-01-21T07:19:06Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Sample Showcase */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Under active development as of 10/2016&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
What I did now roughly is:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
This works so far and I can grab ND images from my browser by http like a screenshot. And as you mentioned before, there are latencies and it isn't efficient. Just creating the PNG image from OSG takes up to 100ms. Using an uncomressed bitmap format like tiff results in 3MB image sies. Assuming a frame rate of 5 will be sufficient for displaying smooth instruments (which I doubt) this results in 15 image creations per second (for Captains PFD, ND and Eicas). &lt;br /&gt;
&lt;br /&gt;
However, it is working and I will use this approach for my first setup and for some long running tests for checking for memory leaks and other problems. Probably there will be some fine tuning required. &lt;br /&gt;
And in the meantime I keep thinking about an external canvas drawing solution. Maybe I'll pursue the Nasal/Javascript approach, though my personal favorite is a Nasal/generic approach which allows implementing drawing in any environment like JavaScript/Python/Java aso.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Patches ==&lt;br /&gt;
=== Base Package ===&lt;br /&gt;
CanvasView.html&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. Also, you need to edit httpd-settings.xml to add a corresponding canvasimage handler there. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //alert(url);&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Add the line&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;canvasimage&amp;gt;/canvasimage&amp;lt;/canvasimage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
to the uri handler defined in file FG_ROOT/httpd-settings.xml &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;uri-handler&amp;gt;&lt;br /&gt;
                &amp;lt;screenshot&amp;gt;/screenshot&amp;lt;/screenshot&amp;gt;&lt;br /&gt;
                &amp;lt;property&amp;gt;/props/&amp;lt;/property&amp;gt;&lt;br /&gt;
                &amp;lt;json&amp;gt;/json/&amp;lt;/json&amp;gt;&lt;br /&gt;
                &amp;lt;pkg&amp;gt;/pkg/&amp;lt;/pkg&amp;gt;&lt;br /&gt;
                &amp;lt;flighthistory&amp;gt;/flighthistory/&amp;lt;/flighthistory&amp;gt;&lt;br /&gt;
                &amp;lt;run&amp;gt;/run.cgi&amp;lt;/run&amp;gt;&lt;br /&gt;
                &amp;lt;navdb&amp;gt;/navdb&amp;lt;/navdb&amp;gt;&lt;br /&gt;
                &amp;lt;canvasimage&amp;gt;/canvasimage&amp;lt;/canvasimage&amp;gt;&lt;br /&gt;
        &amp;lt;/uri-handler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
localhost:5701/canvasimage?type=png&amp;amp;canvasindex=0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 0 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 0 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout).&lt;br /&gt;
&lt;br /&gt;
=== Sample Showcase CanvasView.html ===&lt;br /&gt;
The following showcase script CanvasView.html shows the main instruments of Soitanens 737 with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load.&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //alert(url);&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117156</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117156"/>
		<updated>2019-01-21T07:16:25Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Using */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Under active development as of 10/2016&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
What I did now roughly is:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
This works so far and I can grab ND images from my browser by http like a screenshot. And as you mentioned before, there are latencies and it isn't efficient. Just creating the PNG image from OSG takes up to 100ms. Using an uncomressed bitmap format like tiff results in 3MB image sies. Assuming a frame rate of 5 will be sufficient for displaying smooth instruments (which I doubt) this results in 15 image creations per second (for Captains PFD, ND and Eicas). &lt;br /&gt;
&lt;br /&gt;
However, it is working and I will use this approach for my first setup and for some long running tests for checking for memory leaks and other problems. Probably there will be some fine tuning required. &lt;br /&gt;
And in the meantime I keep thinking about an external canvas drawing solution. Maybe I'll pursue the Nasal/Javascript approach, though my personal favorite is a Nasal/generic approach which allows implementing drawing in any environment like JavaScript/Python/Java aso.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Patches ==&lt;br /&gt;
=== Base Package ===&lt;br /&gt;
CanvasView.html&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. Also, you need to edit httpd-settings.xml to add a corresponding canvasimage handler there. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //alert(url);&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Add the line&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;canvasimage&amp;gt;/canvasimage&amp;lt;/canvasimage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
to the uri handler defined in file FG_ROOT/httpd-settings.xml &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;uri-handler&amp;gt;&lt;br /&gt;
                &amp;lt;screenshot&amp;gt;/screenshot&amp;lt;/screenshot&amp;gt;&lt;br /&gt;
                &amp;lt;property&amp;gt;/props/&amp;lt;/property&amp;gt;&lt;br /&gt;
                &amp;lt;json&amp;gt;/json/&amp;lt;/json&amp;gt;&lt;br /&gt;
                &amp;lt;pkg&amp;gt;/pkg/&amp;lt;/pkg&amp;gt;&lt;br /&gt;
                &amp;lt;flighthistory&amp;gt;/flighthistory/&amp;lt;/flighthistory&amp;gt;&lt;br /&gt;
                &amp;lt;run&amp;gt;/run.cgi&amp;lt;/run&amp;gt;&lt;br /&gt;
                &amp;lt;navdb&amp;gt;/navdb&amp;lt;/navdb&amp;gt;&lt;br /&gt;
                &amp;lt;canvasimage&amp;gt;/canvasimage&amp;lt;/canvasimage&amp;gt;&lt;br /&gt;
        &amp;lt;/uri-handler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
localhost:5701/canvasimage?type=png&amp;amp;canvasindex=0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 0 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 0 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout).&lt;br /&gt;
&lt;br /&gt;
=== Sample Showcase ===&lt;br /&gt;
The following showcase script CanvasView.html shows the main instruments of Soitanens 737 with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load.&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117155</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117155"/>
		<updated>2019-01-21T07:13:41Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Building */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Under active development as of 10/2016&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
What I did now roughly is:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
This works so far and I can grab ND images from my browser by http like a screenshot. And as you mentioned before, there are latencies and it isn't efficient. Just creating the PNG image from OSG takes up to 100ms. Using an uncomressed bitmap format like tiff results in 3MB image sies. Assuming a frame rate of 5 will be sufficient for displaying smooth instruments (which I doubt) this results in 15 image creations per second (for Captains PFD, ND and Eicas). &lt;br /&gt;
&lt;br /&gt;
However, it is working and I will use this approach for my first setup and for some long running tests for checking for memory leaks and other problems. Probably there will be some fine tuning required. &lt;br /&gt;
And in the meantime I keep thinking about an external canvas drawing solution. Maybe I'll pursue the Nasal/Javascript approach, though my personal favorite is a Nasal/generic approach which allows implementing drawing in any environment like JavaScript/Python/Java aso.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Patches ==&lt;br /&gt;
=== Base Package ===&lt;br /&gt;
CanvasView.html&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. Also, you need to edit httpd-settings.xml to add a corresponding canvasimage handler there. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //alert(url);&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Add the line&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;canvasimage&amp;gt;/canvasimage&amp;lt;/canvasimage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
to the uri handler defined in file FG_ROOT/httpd-settings.xml &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;uri-handler&amp;gt;&lt;br /&gt;
                &amp;lt;screenshot&amp;gt;/screenshot&amp;lt;/screenshot&amp;gt;&lt;br /&gt;
                &amp;lt;property&amp;gt;/props/&amp;lt;/property&amp;gt;&lt;br /&gt;
                &amp;lt;json&amp;gt;/json/&amp;lt;/json&amp;gt;&lt;br /&gt;
                &amp;lt;pkg&amp;gt;/pkg/&amp;lt;/pkg&amp;gt;&lt;br /&gt;
                &amp;lt;flighthistory&amp;gt;/flighthistory/&amp;lt;/flighthistory&amp;gt;&lt;br /&gt;
                &amp;lt;run&amp;gt;/run.cgi&amp;lt;/run&amp;gt;&lt;br /&gt;
                &amp;lt;navdb&amp;gt;/navdb&amp;lt;/navdb&amp;gt;&lt;br /&gt;
                &amp;lt;canvasimage&amp;gt;/canvasimage&amp;lt;/canvasimage&amp;gt;&lt;br /&gt;
        &amp;lt;/uri-handler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
localhost:5701/canvasimage?type=png&amp;amp;canvasindex=0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 0 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 0 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout).&lt;br /&gt;
&lt;br /&gt;
The showcase script CanvasView.html shows the main instruments of Soitanens 737 with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load.&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117154</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117154"/>
		<updated>2019-01-21T07:11:51Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* FlightGear */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Under active development as of 10/2016&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
What I did now roughly is:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
This works so far and I can grab ND images from my browser by http like a screenshot. And as you mentioned before, there are latencies and it isn't efficient. Just creating the PNG image from OSG takes up to 100ms. Using an uncomressed bitmap format like tiff results in 3MB image sies. Assuming a frame rate of 5 will be sufficient for displaying smooth instruments (which I doubt) this results in 15 image creations per second (for Captains PFD, ND and Eicas). &lt;br /&gt;
&lt;br /&gt;
However, it is working and I will use this approach for my first setup and for some long running tests for checking for memory leaks and other problems. Probably there will be some fine tuning required. &lt;br /&gt;
And in the meantime I keep thinking about an external canvas drawing solution. Maybe I'll pursue the Nasal/Javascript approach, though my personal favorite is a Nasal/generic approach which allows implementing drawing in any environment like JavaScript/Python/Java aso.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Patches ==&lt;br /&gt;
=== Base Package ===&lt;br /&gt;
CanvasView.html&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. Also, you need to edit httpd-settings.xml to add a corresponding canvasimage handler there. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //alert(url);&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Building ==&lt;br /&gt;
&lt;br /&gt;
* Download and extract the latest attached tar archive (https://sourceforge.net/projects/remote-canvas-for-flightgear). It contains the patches listed above,&lt;br /&gt;
* Copy the simgear and flightgear subfolders over your existing source tree.&lt;br /&gt;
* Run the platform specific make for building FG.&lt;br /&gt;
* Copy the resulting fgfs executable to your FlightGears installation bin directory '''after''' saving the existing.&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Add the line&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;canvasimage&amp;gt;/canvasimage&amp;lt;/canvasimage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
to the uri handler defined in file FG_ROOT/httpd-settings.xml &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;uri-handler&amp;gt;&lt;br /&gt;
                &amp;lt;screenshot&amp;gt;/screenshot&amp;lt;/screenshot&amp;gt;&lt;br /&gt;
                &amp;lt;property&amp;gt;/props/&amp;lt;/property&amp;gt;&lt;br /&gt;
                &amp;lt;json&amp;gt;/json/&amp;lt;/json&amp;gt;&lt;br /&gt;
                &amp;lt;pkg&amp;gt;/pkg/&amp;lt;/pkg&amp;gt;&lt;br /&gt;
                &amp;lt;flighthistory&amp;gt;/flighthistory/&amp;lt;/flighthistory&amp;gt;&lt;br /&gt;
                &amp;lt;run&amp;gt;/run.cgi&amp;lt;/run&amp;gt;&lt;br /&gt;
                &amp;lt;navdb&amp;gt;/navdb&amp;lt;/navdb&amp;gt;&lt;br /&gt;
                &amp;lt;canvasimage&amp;gt;/canvasimage&amp;lt;/canvasimage&amp;gt;&lt;br /&gt;
        &amp;lt;/uri-handler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
localhost:5701/canvasimage?type=png&amp;amp;canvasindex=0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 0 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 0 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout).&lt;br /&gt;
&lt;br /&gt;
The showcase script CanvasView.html shows the main instruments of Soitanens 737 with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load.&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117153</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117153"/>
		<updated>2019-01-21T07:11:18Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* SimGear */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Under active development as of 10/2016&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
What I did now roughly is:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
This works so far and I can grab ND images from my browser by http like a screenshot. And as you mentioned before, there are latencies and it isn't efficient. Just creating the PNG image from OSG takes up to 100ms. Using an uncomressed bitmap format like tiff results in 3MB image sies. Assuming a frame rate of 5 will be sufficient for displaying smooth instruments (which I doubt) this results in 15 image creations per second (for Captains PFD, ND and Eicas). &lt;br /&gt;
&lt;br /&gt;
However, it is working and I will use this approach for my first setup and for some long running tests for checking for memory leaks and other problems. Probably there will be some fine tuning required. &lt;br /&gt;
And in the meantime I keep thinking about an external canvas drawing solution. Maybe I'll pursue the Nasal/Javascript approach, though my personal favorite is a Nasal/generic approach which allows implementing drawing in any environment like JavaScript/Python/Java aso.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Patches ==&lt;br /&gt;
=== FlightGear ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;diff&amp;quot;&amp;gt;&lt;br /&gt;
diff --git a/src/Canvas/canvas_mgr.cxx b/src/Canvas/canvas_mgr.cxx&lt;br /&gt;
index 6646b77..5316543 100644&lt;br /&gt;
--- a/src/Canvas/canvas_mgr.cxx&lt;br /&gt;
+++ b/src/Canvas/canvas_mgr.cxx&lt;br /&gt;
@@ -64,7 +64,7 @@ CanvasMgr::CanvasMgr():&lt;br /&gt;
     fgGetNode(&amp;quot;/sim/signals/model-reinit&amp;quot;, true)&lt;br /&gt;
   )&lt;br /&gt;
 {&lt;br /&gt;
-&lt;br /&gt;
+ SG_LOG(SG_GENERAL, SG_ALERT, &amp;quot;CanvasMgr() constructor invoked&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
diff --git a/src/Network/http/CMakeLists.txt b/src/Network/http/CMakeLists.txt&lt;br /&gt;
index 9e913d0..1a099cb 100644&lt;br /&gt;
--- a/src/Network/http/CMakeLists.txt&lt;br /&gt;
+++ b/src/Network/http/CMakeLists.txt&lt;br /&gt;
@@ -3,6 +3,7 @@ include(FlightGearComponent)&lt;br /&gt;
 set(SOURCES&lt;br /&gt;
 	httpd.cxx&lt;br /&gt;
 	ScreenshotUriHandler.cxx&lt;br /&gt;
+	CanvasImageUriHandler.cxx&lt;br /&gt;
 	PropertyUriHandler.cxx&lt;br /&gt;
 	JsonUriHandler.cxx&lt;br /&gt;
     FlightHistoryUriHandler.cxx&lt;br /&gt;
@@ -19,6 +20,7 @@ set(HEADERS&lt;br /&gt;
 	urihandler.hxx&lt;br /&gt;
 	httpd.hxx&lt;br /&gt;
 	ScreenshotUriHandler.hxx&lt;br /&gt;
+	CanvasImageUriHandler.hxx&lt;br /&gt;
 	PropertyUriHandler.hxx&lt;br /&gt;
 	JsonUriHandler.hxx&lt;br /&gt;
     FlightHistoryUriHandler.hxx&lt;br /&gt;
diff --git a/src/Network/http/CanvasImageUriHandler.cxx b/src/Network/http/CanvasImageUriHandler.cxx&lt;br /&gt;
new file mode 100644&lt;br /&gt;
index 0000000..7cd5a0e&lt;br /&gt;
--- /dev/null&lt;br /&gt;
+++ b/src/Network/http/CanvasImageUriHandler.cxx&lt;br /&gt;
@@ -0,0 +1,335 @@&lt;br /&gt;
+// CanvasImageUriHandler.cxx -- Provide canvasimages via http&lt;br /&gt;
+//&lt;br /&gt;
+// Started by Curtis Olson, started June 2001.&lt;br /&gt;
+// osg support written by James Turner&lt;br /&gt;
+// Ported to new httpd infrastructure by Torsten Dreyer&lt;br /&gt;
+// Derived from ScreenshotUrihandler originally by Torsten Dreyer)&lt;br /&gt;
+//&lt;br /&gt;
+// This program is free software; you can redistribute it and/or&lt;br /&gt;
+// modify it under the terms of the GNU General Public License as&lt;br /&gt;
+// published by the Free Software Foundation; either version 2 of the&lt;br /&gt;
+// License, or (at your option) any later version.&lt;br /&gt;
+//&lt;br /&gt;
+// This program is distributed in the hope that it will be useful, but&lt;br /&gt;
+// WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU&lt;br /&gt;
+// General Public License for more details.&lt;br /&gt;
+//&lt;br /&gt;
+// You should have received a copy of the GNU General Public License&lt;br /&gt;
+// along with this program; if not, write to the Free Software&lt;br /&gt;
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.&lt;br /&gt;
+&lt;br /&gt;
+#include &amp;quot;CanvasImageUriHandler.hxx&amp;quot;&lt;br /&gt;
+&lt;br /&gt;
+#ifdef _WIN32&lt;br /&gt;
+#include &amp;lt;windows.h&amp;gt;&lt;br /&gt;
+#endif&lt;br /&gt;
+#include &amp;lt;osgDB/Registry&amp;gt;&lt;br /&gt;
+#include &amp;lt;osgDB/ReaderWriter&amp;gt;&lt;br /&gt;
+#include &amp;lt;osgUtil/SceneView&amp;gt;&lt;br /&gt;
+#include &amp;lt;osgViewer/Viewer&amp;gt;&lt;br /&gt;
+&lt;br /&gt;
+#include &amp;lt;Canvas/canvas_mgr.hxx&amp;gt;&lt;br /&gt;
+#include &amp;lt;simgear/canvas/Canvas.hxx&amp;gt;&lt;br /&gt;
+&lt;br /&gt;
+#include &amp;lt;simgear/threads/SGQueue.hxx&amp;gt;&lt;br /&gt;
+#include &amp;lt;simgear/structure/Singleton.hxx&amp;gt;&lt;br /&gt;
+#include &amp;lt;Main/globals.hxx&amp;gt;&lt;br /&gt;
+#include &amp;lt;Viewer/renderer.hxx&amp;gt;&lt;br /&gt;
+&lt;br /&gt;
+#include &amp;lt;queue&amp;gt;&lt;br /&gt;
+#include &amp;lt;boost/lexical_cast.hpp&amp;gt;&lt;br /&gt;
+&lt;br /&gt;
+using std::string;&lt;br /&gt;
+using std::vector;&lt;br /&gt;
+using std::list;&lt;br /&gt;
+&lt;br /&gt;
+namespace sc = simgear::canvas;&lt;br /&gt;
+&lt;br /&gt;
+namespace flightgear {&lt;br /&gt;
+    namespace http {&lt;br /&gt;
+&lt;br /&gt;
+        ///////////////////////////////////////////////////////////////////////////&lt;br /&gt;
+&lt;br /&gt;
+        class StringReadyListener {&lt;br /&gt;
+        public:&lt;br /&gt;
+            virtual void stringReady(const std::string &amp;amp;) = 0;&lt;br /&gt;
+&lt;br /&gt;
+            virtual ~StringReadyListener() {&lt;br /&gt;
+            }&lt;br /&gt;
+        };&lt;br /&gt;
+&lt;br /&gt;
+        struct ImageCompressionTask {&lt;br /&gt;
+            StringReadyListener * stringReadyListener;&lt;br /&gt;
+            string format;&lt;br /&gt;
+            osg::ref_ptr&amp;lt;osg::Image&amp;gt; image;&lt;br /&gt;
+&lt;br /&gt;
+            ImageCompressionTask() {&lt;br /&gt;
+                stringReadyListener = NULL;&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            ImageCompressionTask(const ImageCompressionTask &amp;amp; other) {&lt;br /&gt;
+                stringReadyListener = other.stringReadyListener;&lt;br /&gt;
+                format = other.format;&lt;br /&gt;
+                image = other.image;&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            ImageCompressionTask &amp;amp; operator=(const ImageCompressionTask &amp;amp; other) {&lt;br /&gt;
+                stringReadyListener = other.stringReadyListener;&lt;br /&gt;
+                format = other.format;&lt;br /&gt;
+                image = other.image;&lt;br /&gt;
+                return *this;&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+        };&lt;br /&gt;
+        //TODO reuse from screenshoturihandler&lt;br /&gt;
+&lt;br /&gt;
+        class ImageCompressorCI : public OpenThreads::Thread {&lt;br /&gt;
+        public:&lt;br /&gt;
+&lt;br /&gt;
+            ImageCompressorCI() {&lt;br /&gt;
+            }&lt;br /&gt;
+            virtual void run();&lt;br /&gt;
+            void addTask(ImageCompressionTask &amp;amp; task);&lt;br /&gt;
+        private:&lt;br /&gt;
+            typedef SGBlockingQueue&amp;lt;ImageCompressionTask&amp;gt; TaskList;&lt;br /&gt;
+            TaskList _tasks;&lt;br /&gt;
+        };&lt;br /&gt;
+&lt;br /&gt;
+        typedef simgear::Singleton&amp;lt;ImageCompressorCI&amp;gt; ImageCompressorCISingleton;&lt;br /&gt;
+&lt;br /&gt;
+        void ImageCompressorCI::run() {&lt;br /&gt;
+            osg::ref_ptr&amp;lt;osgDB::ReaderWriter::Options&amp;gt; options = new osgDB::ReaderWriter::Options(&amp;quot;JPEG_QUALITY 80 PNG_COMPRESSION 9&amp;quot;);&lt;br /&gt;
+&lt;br /&gt;
+            SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;ImageCompressorCI is running&amp;quot;);&lt;br /&gt;
+            for (;;) {&lt;br /&gt;
+                ImageCompressionTask task = _tasks.pop();&lt;br /&gt;
+                SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;ImageCompressorCI has an image&amp;quot;);&lt;br /&gt;
+&lt;br /&gt;
+                if (NULL != task.stringReadyListener) {&lt;br /&gt;
+                    SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;ImageCompressorCI checking for writer for &amp;quot; &amp;lt;&amp;lt; task.format);&lt;br /&gt;
+                    osgDB::ReaderWriter* writer = osgDB::Registry::instance()-&amp;gt;getReaderWriterForExtension(task.format);&lt;br /&gt;
+                    if (!writer)&lt;br /&gt;
+                        continue;&lt;br /&gt;
+&lt;br /&gt;
+                    SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;ImageCompressorCI compressing to &amp;quot; &amp;lt;&amp;lt; task.format);&lt;br /&gt;
+                    std::stringstream outputStream;&lt;br /&gt;
+                    osgDB::ReaderWriter::WriteResult wr;&lt;br /&gt;
+                    wr = writer-&amp;gt;writeImage(*task.image, outputStream, options);&lt;br /&gt;
+&lt;br /&gt;
+                    if (wr.success()) {&lt;br /&gt;
+                        SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;ImageCompressorCI compressed to  &amp;quot; &amp;lt;&amp;lt; task.format);&lt;br /&gt;
+                        task.stringReadyListener-&amp;gt;stringReady(outputStream.str());&lt;br /&gt;
+                    }&lt;br /&gt;
+                    SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;ImageCompressorCI done for this image&amp;quot; &amp;lt;&amp;lt; task.format);&lt;br /&gt;
+&lt;br /&gt;
+                }&lt;br /&gt;
+            }&lt;br /&gt;
+            SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;ImageCompressorCI exiting&amp;quot;);&lt;br /&gt;
+        }&lt;br /&gt;
+&lt;br /&gt;
+        void ImageCompressorCI::addTask(ImageCompressionTask &amp;amp; task) {&lt;br /&gt;
+            _tasks.push(task);&lt;br /&gt;
+        }&lt;br /&gt;
+&lt;br /&gt;
+&lt;br /&gt;
+        ///////////////////////////////////////////////////////////////////////////&lt;br /&gt;
+&lt;br /&gt;
+        class CanvasImageRequest : public ConnectionData, public simgear::canvas::CanvasImageReadyListener, StringReadyListener {&lt;br /&gt;
+        public:&lt;br /&gt;
+            ImageCompressionTask *currenttask=NULL;&lt;br /&gt;
+            sc::CanvasPtr canvas;&lt;br /&gt;
+&lt;br /&gt;
+            CanvasImageRequest(const string &amp;amp; window, const string &amp;amp; type, int canvasindex, bool stream)&lt;br /&gt;
+            : _type(type), _stream(stream) {&lt;br /&gt;
+                SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;CanvasImageRequest: \n&amp;quot;);&lt;br /&gt;
+                &lt;br /&gt;
+                if (NULL == osgDB::Registry::instance()-&amp;gt;getReaderWriterForExtension(_type))&lt;br /&gt;
+                    throw sg_format_exception(&amp;quot;Unsupported image type: &amp;quot; + type, type);&lt;br /&gt;
+&lt;br /&gt;
+                CanvasMgr* canvas_mgr = static_cast&amp;lt;CanvasMgr*&amp;gt; (globals-&amp;gt;get_subsystem(&amp;quot;Canvas&amp;quot;));&lt;br /&gt;
+                if (!canvas_mgr) {&lt;br /&gt;
+                    SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;CanvasImage:CanvasMgr not found\n&amp;quot;);&lt;br /&gt;
+                } else {&lt;br /&gt;
+                    canvas = canvas_mgr-&amp;gt;getCanvas(canvasindex);&lt;br /&gt;
+                    if (!canvas) {&lt;br /&gt;
+                        SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;CanvasImage:Canvas not found\n&amp;quot;);&lt;br /&gt;
+                    } else {&lt;br /&gt;
+                        SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;CanvasImage:Canvas found\n&amp;quot;);&lt;br /&gt;
+                        //SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;CanvasImageRequest: found camera %d. width=%d, height=%d\n&amp;quot;, camera, canvas-&amp;gt;getSizeX(), canvas-&amp;gt;getSizeY());&lt;br /&gt;
+&lt;br /&gt;
+                        SGConstPropertyNode_ptr canvasnode = canvas-&amp;gt;getProps();&lt;br /&gt;
+                        if (canvasnode) {&lt;br /&gt;
+                            const char *canvasname = canvasnode-&amp;gt;getStringValue(&amp;quot;name&amp;quot;);&lt;br /&gt;
+                            if (canvasname) {&lt;br /&gt;
+                                SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;CanvasImageRequest: node=%s(%s)\n&amp;quot;);//, canvasnode-&amp;gt;getDisplayName().c_str(), canvasname);&lt;br /&gt;
+                            }&lt;br /&gt;
+                        }&lt;br /&gt;
+&lt;br /&gt;
+                        canvas-&amp;gt;subscribe(this);&lt;br /&gt;
+                    }&lt;br /&gt;
+                }&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            // Assumption: when unsubscribe returns,there might just be a compressor thread running,&lt;br /&gt;
+            // causing a crash when the deconstructor finishes. Rare, but might happen. Just wait to be sure.&lt;br /&gt;
+            virtual ~CanvasImageRequest() {&lt;br /&gt;
+                if (currenttask){&lt;br /&gt;
+                    SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;canvasimage task running&amp;quot;);&lt;br /&gt;
+#ifdef _WIN32&lt;br /&gt;
+                    Sleep(15000);&lt;br /&gt;
+#else&lt;br /&gt;
+                     sleep(15);&lt;br /&gt;
+#endif&lt;br /&gt;
+                }&lt;br /&gt;
+&lt;br /&gt;
+                if (canvas){&lt;br /&gt;
+                    canvas-&amp;gt;unsubscribe(this);&lt;br /&gt;
+                }&lt;br /&gt;
+                //_canvasimageCallback-&amp;gt;unsubscribe(this);&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            virtual void imageReady(osg::ref_ptr&amp;lt;osg::Image&amp;gt; rawImage) {&lt;br /&gt;
+                SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;CanvasImage:imageReady&amp;quot;);&lt;br /&gt;
+                // called from a rendering thread, not from the main loop&lt;br /&gt;
+                ImageCompressionTask task;&lt;br /&gt;
+                currenttask = &amp;amp;task;&lt;br /&gt;
+                task.image = rawImage;&lt;br /&gt;
+                task.format = _type;&lt;br /&gt;
+                task.stringReadyListener = this;&lt;br /&gt;
+                ImageCompressorCISingleton::instance()-&amp;gt;addTask(task);&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            void requestCanvasImage() {&lt;br /&gt;
+            //    _canvasimageCallback-&amp;gt;subscribe(this);&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            mutable OpenThreads::Mutex _lock;&lt;br /&gt;
+&lt;br /&gt;
+            virtual void stringReady(const string &amp;amp; s) {&lt;br /&gt;
+                SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;CanvasImage:stringReady&amp;quot;);&lt;br /&gt;
+                &lt;br /&gt;
+                // called from the compressor thread&lt;br /&gt;
+                OpenThreads::ScopedLock&amp;lt;OpenThreads::Mutex&amp;gt; lock(_lock);&lt;br /&gt;
+                _compressedData = s;&lt;br /&gt;
+                // allow destructor&lt;br /&gt;
+                currenttask = NULL;&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            string getCanvasImage() {&lt;br /&gt;
+                string reply;&lt;br /&gt;
+                {&lt;br /&gt;
+                    // called from the main loop&lt;br /&gt;
+                    OpenThreads::ScopedLock&amp;lt;OpenThreads::Mutex&amp;gt; lock(_lock);&lt;br /&gt;
+                    reply = _compressedData;&lt;br /&gt;
+                    _compressedData.clear();&lt;br /&gt;
+                }&lt;br /&gt;
+                return reply;&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            bool isStream() const {&lt;br /&gt;
+                return _stream;&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            const string &amp;amp; getType() const {&lt;br /&gt;
+                return _type;&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+        private:&lt;br /&gt;
+            string _type;&lt;br /&gt;
+            bool _stream;&lt;br /&gt;
+            string _compressedData;&lt;br /&gt;
+            //CanvasImageCallback * _canvasimageCallback;&lt;br /&gt;
+        };&lt;br /&gt;
+&lt;br /&gt;
+        CanvasImageUriHandler::CanvasImageUriHandler(const char * uri)&lt;br /&gt;
+        : URIHandler(uri) {&lt;br /&gt;
+        }&lt;br /&gt;
+&lt;br /&gt;
+        CanvasImageUriHandler::~CanvasImageUriHandler() {&lt;br /&gt;
+            ImageCompressorCISingleton::instance()-&amp;gt;cancel();&lt;br /&gt;
+            //ImageCompressorSingleton::instance()-&amp;gt;join();&lt;br /&gt;
+        }&lt;br /&gt;
+&lt;br /&gt;
+        const static string KEY(&amp;quot;CanvasImageUriHandler::CanvasImageRequest&amp;quot;);&lt;br /&gt;
+#define BOUNDARY &amp;quot;--fgfs-canvasimage-boundary&amp;quot;&lt;br /&gt;
+&lt;br /&gt;
+        bool CanvasImageUriHandler::handleGetRequest(const HTTPRequest &amp;amp; request, HTTPResponse &amp;amp; response, Connection * connection) {&lt;br /&gt;
+            if (!ImageCompressorCISingleton::instance()-&amp;gt;isRunning())&lt;br /&gt;
+                ImageCompressorCISingleton::instance()-&amp;gt;start();&lt;br /&gt;
+&lt;br /&gt;
+            string type = request.RequestVariables.get(&amp;quot;type&amp;quot;);&lt;br /&gt;
+            if (type.empty()) type = &amp;quot;jpg&amp;quot;;&lt;br /&gt;
+&lt;br /&gt;
+            string canvasindex = request.RequestVariables.get(&amp;quot;canvasindex&amp;quot;);&lt;br /&gt;
+            if (canvasindex.empty()) canvasindex = &amp;quot;0&amp;quot;;&lt;br /&gt;
+            &lt;br /&gt;
+            //  string camera = request.RequestVariables.get(&amp;quot;camera&amp;quot;);&lt;br /&gt;
+            string window = request.RequestVariables.get(&amp;quot;window&amp;quot;);&lt;br /&gt;
+&lt;br /&gt;
+            bool stream = (false == request.RequestVariables.get(&amp;quot;stream&amp;quot;).empty());&lt;br /&gt;
+&lt;br /&gt;
+            SGSharedPtr&amp;lt;CanvasImageRequest&amp;gt; canvasimageRequest;&lt;br /&gt;
+            try {&lt;br /&gt;
+                SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;new CanvasImageRequest(&amp;quot; &amp;lt;&amp;lt; window &amp;lt;&amp;lt; &amp;quot;,&amp;quot; &amp;lt;&amp;lt; type &amp;lt;&amp;lt; &amp;quot;,&amp;quot; &amp;lt;&amp;lt; stream &amp;lt;&amp;lt; &amp;quot;)&amp;quot;);&lt;br /&gt;
+                canvasimageRequest = new CanvasImageRequest(window, type, atoi(canvasindex.c_str()),stream);&lt;br /&gt;
+            } catch (sg_format_exception &amp;amp; ex) {&lt;br /&gt;
+                SG_LOG(SG_NETWORK, SG_INFO, ex.getFormattedMessage());&lt;br /&gt;
+                response.Header[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/plain&amp;quot;;&lt;br /&gt;
+                response.StatusCode = 410;&lt;br /&gt;
+                response.Content = ex.getFormattedMessage();&lt;br /&gt;
+                return true;&lt;br /&gt;
+            } catch (sg_error &amp;amp; ex) {&lt;br /&gt;
+                SG_LOG(SG_NETWORK, SG_INFO, ex.getFormattedMessage());&lt;br /&gt;
+                response.Header[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/plain&amp;quot;;&lt;br /&gt;
+                response.StatusCode = 500;&lt;br /&gt;
+                response.Content = ex.getFormattedMessage();&lt;br /&gt;
+                return true;&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            if (false == stream) {&lt;br /&gt;
+                response.Header[&amp;quot;Content-Type&amp;quot;] = string(&amp;quot;image/&amp;quot;).append(type);&lt;br /&gt;
+                response.Header[&amp;quot;Content-Disposition&amp;quot;] = string(&amp;quot;inline; filename=\&amp;quot;fgfs-canvasimage.&amp;quot;).append(type).append(&amp;quot;\&amp;quot;&amp;quot;);&lt;br /&gt;
+            } else {&lt;br /&gt;
+                response.Header[&amp;quot;Content-Type&amp;quot;] = string(&amp;quot;multipart/x-mixed-replace; boundary=&amp;quot; BOUNDARY);&lt;br /&gt;
+&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            connection-&amp;gt;put(KEY, canvasimageRequest);&lt;br /&gt;
+            return false; // call me again thru poll&lt;br /&gt;
+        }&lt;br /&gt;
+&lt;br /&gt;
+        bool CanvasImageUriHandler::poll(Connection * connection) {&lt;br /&gt;
+&lt;br /&gt;
+            SGSharedPtr&amp;lt;ConnectionData&amp;gt; data = connection-&amp;gt;get(KEY);&lt;br /&gt;
+            CanvasImageRequest * canvasimageRequest = dynamic_cast&amp;lt;CanvasImageRequest*&amp;gt; (data.get());&lt;br /&gt;
+            if (NULL == canvasimageRequest) return true; // Should not happen, kill the connection&lt;br /&gt;
+&lt;br /&gt;
+            const string &amp;amp; canvasimage = canvasimageRequest-&amp;gt;getCanvasImage();&lt;br /&gt;
+            if (canvasimage.empty()) {&lt;br /&gt;
+                SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;No canvasimage available.&amp;quot;);&lt;br /&gt;
+                return false; // not ready yet, call again.&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;CanvasImage is ready, size=&amp;quot; &amp;lt;&amp;lt; canvasimage.size());&lt;br /&gt;
+&lt;br /&gt;
+            if (canvasimageRequest-&amp;gt;isStream()) {&lt;br /&gt;
+                string s(BOUNDARY &amp;quot;\r\nContent-Type: image/&amp;quot;);&lt;br /&gt;
+                s.append(canvasimageRequest-&amp;gt;getType()).append(&amp;quot;\r\nContent-Length:&amp;quot;);&lt;br /&gt;
+                s += boost::lexical_cast&amp;lt;string&amp;gt;(canvasimage.size());&lt;br /&gt;
+                s += &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
+                connection-&amp;gt;write(s.c_str(), s.length());&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            connection-&amp;gt;write(canvasimage.data(), canvasimage.size());&lt;br /&gt;
+&lt;br /&gt;
+            /* unknown purpose&lt;br /&gt;
+            if (canvasimageRequest-&amp;gt;isStream()) {&lt;br /&gt;
+                canvasimageRequest-&amp;gt;requestCanvasImage();&lt;br /&gt;
+                // continue until user closes connection&lt;br /&gt;
+                return false;&lt;br /&gt;
+            }&lt;br /&gt;
+            */&lt;br /&gt;
+&lt;br /&gt;
+            // single canvasimage, send terminating chunk&lt;br /&gt;
+            connection-&amp;gt;remove(KEY);&lt;br /&gt;
+            connection-&amp;gt;write(&amp;quot;&amp;quot;, 0);&lt;br /&gt;
+            return true; // done.&lt;br /&gt;
+        }&lt;br /&gt;
+&lt;br /&gt;
+    } // namespace http&lt;br /&gt;
+} // namespace flightgear&lt;br /&gt;
+&lt;br /&gt;
diff --git a/src/Network/http/CanvasImageUriHandler.hxx b/src/Network/http/CanvasImageUriHandler.hxx&lt;br /&gt;
new file mode 100644&lt;br /&gt;
index 0000000..f50be37&lt;br /&gt;
--- /dev/null&lt;br /&gt;
+++ b/src/Network/http/CanvasImageUriHandler.hxx&lt;br /&gt;
@@ -0,0 +1,40 @@&lt;br /&gt;
+// CanvasImageUriHandler.hxx -- Provide canvasimages via http&lt;br /&gt;
+//&lt;br /&gt;
+// Written by Torsten Dreyer, started April 2014.&lt;br /&gt;
+//&lt;br /&gt;
+// Copyright (C) 2014  Torsten Dreyer&lt;br /&gt;
+// derived from ScreenshotUrihandler by ThomasS&lt;br /&gt;
+// This program is free software; you can redistribute it and/or&lt;br /&gt;
+// modify it under the terms of the GNU General Public License as&lt;br /&gt;
+// published by the Free Software Foundation; either version 2 of the&lt;br /&gt;
+// License, or (at your option) any later version.&lt;br /&gt;
+//&lt;br /&gt;
+// This program is distributed in the hope that it will be useful, but&lt;br /&gt;
+// WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU&lt;br /&gt;
+// General Public License for more details.&lt;br /&gt;
+//&lt;br /&gt;
+// You should have received a copy of the GNU General Public License&lt;br /&gt;
+// along with this program; if not, write to the Free Software&lt;br /&gt;
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.&lt;br /&gt;
+&lt;br /&gt;
+#ifndef __FG_CANVASIMAGE_URI_HANDLER_HXX&lt;br /&gt;
+#define __FG_CANVASIMAGE_URI_HANDLER_HXX&lt;br /&gt;
+&lt;br /&gt;
+#include &amp;quot;urihandler.hxx&amp;quot;&lt;br /&gt;
+&lt;br /&gt;
+namespace flightgear {&lt;br /&gt;
+namespace http {&lt;br /&gt;
+&lt;br /&gt;
+class CanvasImageUriHandler : public URIHandler {&lt;br /&gt;
+public:&lt;br /&gt;
+  CanvasImageUriHandler( const char * uri = &amp;quot;/canvasimage/&amp;quot; );&lt;br /&gt;
+  ~CanvasImageUriHandler();&lt;br /&gt;
+  virtual bool handleGetRequest( const HTTPRequest &amp;amp; request, HTTPResponse &amp;amp; response, Connection * connection );&lt;br /&gt;
+  virtual bool poll( Connection * connection );&lt;br /&gt;
+};&lt;br /&gt;
+&lt;br /&gt;
+} // namespace http&lt;br /&gt;
+} // namespace flightgear&lt;br /&gt;
+&lt;br /&gt;
+#endif //#define __FG_CANVASIMAGE_URI_HANDLER_HXX&lt;br /&gt;
diff --git a/src/Network/http/httpd.cxx b/src/Network/http/httpd.cxx&lt;br /&gt;
index 358b247..3bfff3a 100644&lt;br /&gt;
--- a/src/Network/http/httpd.cxx&lt;br /&gt;
+++ b/src/Network/http/httpd.cxx&lt;br /&gt;
@@ -22,6 +22,7 @@&lt;br /&gt;
 #include &amp;quot;HTTPRequest.hxx&amp;quot;&lt;br /&gt;
 #include &amp;quot;PropertyChangeWebsocket.hxx&amp;quot;&lt;br /&gt;
 #include &amp;quot;ScreenshotUriHandler.hxx&amp;quot;&lt;br /&gt;
+#include &amp;quot;CanvasImageUriHandler.hxx&amp;quot;&lt;br /&gt;
 #include &amp;quot;PropertyUriHandler.hxx&amp;quot;&lt;br /&gt;
 #include &amp;quot;JsonUriHandler.hxx&amp;quot;&lt;br /&gt;
 #include &amp;quot;FlightHistoryUriHandler.hxx&amp;quot;&lt;br /&gt;
@@ -443,6 +444,11 @@ void MongooseHttpd::init()&lt;br /&gt;
       _uriHandler.push_back(new flightgear::http::ScreenshotUriHandler(uri));&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
+if ((uri = n-&amp;gt;getStringValue(&amp;quot;canvasimage&amp;quot;))[0] != 0) {&lt;br /&gt;
+      SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;httpd: adding canvasimage uri handler at &amp;quot; &amp;lt;&amp;lt; uri);&lt;br /&gt;
+      _uriHandler.push_back(new flightgear::http::CanvasImageUriHandler(uri));&lt;br /&gt;
+    }&lt;br /&gt;
+&lt;br /&gt;
     if ((uri = n-&amp;gt;getStringValue(&amp;quot;property&amp;quot;))[0] != 0) {&lt;br /&gt;
       SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;httpd: adding property uri handler at &amp;quot; &amp;lt;&amp;lt; uri);&lt;br /&gt;
       _uriHandler.push_back(new flightgear::http::PropertyUriHandler(uri));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Base Package ===&lt;br /&gt;
CanvasView.html&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. Also, you need to edit httpd-settings.xml to add a corresponding canvasimage handler there. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //alert(url);&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Building ==&lt;br /&gt;
&lt;br /&gt;
* Download and extract the latest attached tar archive (https://sourceforge.net/projects/remote-canvas-for-flightgear). It contains the patches listed above,&lt;br /&gt;
* Copy the simgear and flightgear subfolders over your existing source tree.&lt;br /&gt;
* Run the platform specific make for building FG.&lt;br /&gt;
* Copy the resulting fgfs executable to your FlightGears installation bin directory '''after''' saving the existing.&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Add the line&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;canvasimage&amp;gt;/canvasimage&amp;lt;/canvasimage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
to the uri handler defined in file FG_ROOT/httpd-settings.xml &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;uri-handler&amp;gt;&lt;br /&gt;
                &amp;lt;screenshot&amp;gt;/screenshot&amp;lt;/screenshot&amp;gt;&lt;br /&gt;
                &amp;lt;property&amp;gt;/props/&amp;lt;/property&amp;gt;&lt;br /&gt;
                &amp;lt;json&amp;gt;/json/&amp;lt;/json&amp;gt;&lt;br /&gt;
                &amp;lt;pkg&amp;gt;/pkg/&amp;lt;/pkg&amp;gt;&lt;br /&gt;
                &amp;lt;flighthistory&amp;gt;/flighthistory/&amp;lt;/flighthistory&amp;gt;&lt;br /&gt;
                &amp;lt;run&amp;gt;/run.cgi&amp;lt;/run&amp;gt;&lt;br /&gt;
                &amp;lt;navdb&amp;gt;/navdb&amp;lt;/navdb&amp;gt;&lt;br /&gt;
                &amp;lt;canvasimage&amp;gt;/canvasimage&amp;lt;/canvasimage&amp;gt;&lt;br /&gt;
        &amp;lt;/uri-handler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
localhost:5701/canvasimage?type=png&amp;amp;canvasindex=0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 0 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 0 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout).&lt;br /&gt;
&lt;br /&gt;
The showcase script CanvasView.html shows the main instruments of Soitanens 737 with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load.&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117152</id>
		<title>Read canvas image by HTTP</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Read_canvas_image_by_HTTP&amp;diff=117152"/>
		<updated>2019-01-21T07:09:34Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Status (10/2016) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image = Canvas-ND-served-via-httpd.png&lt;br /&gt;
|name = Canvas/HTTP Server&lt;br /&gt;
|started= 10/2016 &lt;br /&gt;
|description = Serving Canvas texturues via httpd &lt;br /&gt;
|status = Under active development as of 10/2016&lt;br /&gt;
|developers =  ThomasS (since 10/2016) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Multi-instance Canvas use}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:ND-Dialog-with-DisplayMode-support.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
There are situations, e.g., for home cockpit builders &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296448#p296448 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 10th, 2016 &lt;br /&gt;
  |added  =  Oct 10th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;, where it is useful to display instruments like a [[PFD]], [[ND]], EICAS or any [[MFD]] externally from the FlightGear 3D main window in a separate window or on a separate monitor, computer or a mobile device &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=214980#p214980 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Need to Create a Standalone PFD &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; deena102 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 18th, 2014 &lt;br /&gt;
  |added  =  Jul 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199428#p199428 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: TQ/Panel for FG made with Kivy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; pommesschranke &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 31st, 2014 &lt;br /&gt;
  |added  =  Jan 31st, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=169150#p169150 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: using FGpanel to display various instruments and electri &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; someguy &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 23rd, 2012 &lt;br /&gt;
  |added  =  Oct 23rd, 2012 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Many of these avionics/graphics are created by FlightGear's 2D drawing [[Canvas]] system internally. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition there, are a number of other use-cases where being able to obtain a Canvas from fgfs using a network protocol like http may be desirable (e.g. imagine getting a tilemap based on actual scenery from FlightGear &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203495#p203495 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 17th, 2014 &lt;br /&gt;
  |added  =  Mar 17th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;) &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=192817#p192817 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; How to simulate capturing an image using a camera &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; roy111 &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 29th, 2013 &lt;br /&gt;
  |added  =  Oct 29th, 2013 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=219105#p219105 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; FGWebPanel aka FGPanel 2.0 or: FGPanel goes html &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Torsten &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Sep 22nd, 2014 &lt;br /&gt;
  |added  =  Sep 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article provides a patch to FlightGear for downloading any canvas image from a running FlightGear process by HTTP by serializing it to a raster image and serving that via the built-in mongoose based httpd server &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=213146#p213146 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Serializing a  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 22nd, 2014 &lt;br /&gt;
  |added  =  Jun 22nd, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=203550#p203550 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Atlas still in use ? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 18th, 2014 &lt;br /&gt;
  |added  =  Mar 18th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This could be considered the groundwork needed for more sophisticated use-cases such as e.g. actually streaming a live video of a certain MFD to a browser.&lt;br /&gt;
&lt;br /&gt;
An additional option for displaying canvas images on remote computer is [[FGQCanvas]], which doesn't require to patch the core FlightGear code.&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
a modern biz jet will need to be able to display certain MFDs - fgpanel is not too useful for that (unless you are primarily dealing with steam gauges) - the most useful search terms for the forum/wiki will be '''Phi''' and '''FGCanvas''' - the latter of which is a special startup mode of FlightGear itself that can render Canvas based MFDs in a separate instance.&lt;br /&gt;
&lt;br /&gt;
If you don't need fancy MFDs, you could probably use fgfs standalone and/or fgpanel. Phi has the lowest barrier to entry probably for people familiar with HTML and JavaScript, i.e. you don't even need to know much about fgfs.&lt;br /&gt;
The Canvas stuff will really only be needed if you want to render things like the 747 PFD/ND or CDU in a distributed fashion, i.e. using multiple independent displays.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=287810#p287810 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Instruments on a second monitor &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 6th, 2016 &lt;br /&gt;
  |added  =  Jun 6th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should be aware of glass cockpit related efforts, especially Canvas - most airliners and jets will sooner or later benefit from being ported to Canvas, e.g. to use Gijs' NavDisplay framework, or at least Philosopher's MapStructure framework for mapping purposes.&lt;br /&gt;
&lt;br /&gt;
Thus, if this is also about the actual display itself, people should be aware of related canvas efforts, especially FGCanvas: [[FGCanvas]]&lt;br /&gt;
&lt;br /&gt;
The my mid-term plan involves supporting a standalone mode for all Canvas-based glass instruments, including the ND, but also other instruments like the PFD, EICAS, CDU or EFB. This may sound like a lot of work, but it's  mainlyy a matter of introducing a a few helper classes and ensuring that people actually adopt and use those.&lt;br /&gt;
&lt;br /&gt;
In the long-term, we really want to support distributed FlightGear setups like those at FSWeekend/LinuxTag, where multiple computers may be used to run a single simulator session - including properly synchronized glass instruments like the PFD/ND etc. This would also help improve the multiplayer experience, especially dual-pilot setups etc.&lt;br /&gt;
Regarding a pure panel with switches, kobs and buttons, we'd prefer something like that to be aircraft-agnostic, i.e. just consist of property-mapped controls that can be individually assigned, so that this could be reused for other MFDs, not just the ND - but also the PFD or EFB.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=211984#p211984 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: computer2cockpit &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 7th, 2014 &lt;br /&gt;
  |added  =  Jun 7th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's the long-term plan to eventually port FGPanel back into FG and come up with some sort of &amp;quot;FGCanvas&amp;quot; mode, where Canvas-based displays could be run in a separate &amp;quot;standalone&amp;quot; mode and interface to the main/master FG instance.&lt;br /&gt;
&lt;br /&gt;
I don't think that the Canvas system currently builds against just OpenGL ES - but it should be possible to identify problematic use-cases and make the Canvas support OpenGL ES by setting some OSG traits accordingly - at some point, i.e. 12+ months from now&lt;br /&gt;
In general, it pays off to unify things - otherwise, there's lots of duplication and re-invention involved.&lt;br /&gt;
&lt;br /&gt;
Technically, we could definitely run an OpenGL ES-based Canvas on a mobile device, we just need people interested in pursuing this and playing with it - as well as report any issues/showstoppers&lt;br /&gt;
Such an integrated solution would also make it possible to show any canvas texture (instrument, dialog/window, MFD etc) on external devices:&lt;br /&gt;
&lt;br /&gt;
[[File:Navigation display centered MAP mode.png|250px]]&lt;br /&gt;
&lt;br /&gt;
[[FGCanvas]]&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=199081#p199081 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt;  &amp;amp; OpenGL ES (Rasberry PI, Android etc) &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Hooray &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jan 28th, 2014 &lt;br /&gt;
  |added  =  Jan 28th, 2014 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
What I did now roughly is:&lt;br /&gt;
*adding a DrawCallback to the canvas camera&lt;br /&gt;
*attach an image to the canvas camera&lt;br /&gt;
*duplicate Torstens http ScreenshotUriHandler to a CanvasImageUriHandler that subscribes to the callback in the canvas camera&lt;br /&gt;
&lt;br /&gt;
This works so far and I can grab ND images from my browser by http like a screenshot. And as you mentioned before, there are latencies and it isn't efficient. Just creating the PNG image from OSG takes up to 100ms. Using an uncomressed bitmap format like tiff results in 3MB image sies. Assuming a frame rate of 5 will be sufficient for displaying smooth instruments (which I doubt) this results in 15 image creations per second (for Captains PFD, ND and Eicas). &lt;br /&gt;
&lt;br /&gt;
However, it is working and I will use this approach for my first setup and for some long running tests for checking for memory leaks and other problems. Probably there will be some fine tuning required. &lt;br /&gt;
And in the meantime I keep thinking about an external canvas drawing solution. Maybe I'll pursue the Nasal/Javascript approach, though my personal favorite is a Nasal/generic approach which allows implementing drawing in any environment like JavaScript/Python/Java aso.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=296627#p296627 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Canvas remote drawing &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Oct 14th, 2016 &lt;br /&gt;
  |added  =  Oct 14th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Canvas-in-firefox.png|Screenshot showing a Canvas camera rendered to an image streamed to FireFox&lt;br /&gt;
Map-canvas dialog streamed via httpd.png|Canvas Map dialog streamed to FireFox&lt;br /&gt;
Pui2canvas dialog served via httpd.png|FlightGear [[PUI]] XML dialog rendered via [[Pui2canvas]] and streamed to FireFox&lt;br /&gt;
Canvas-ND-served-via-httpd.png|Screenshot showing a FlightGear [[PUI]] GUI dialog with two independent [[NavDisplay]] instances streamed to FireFox&lt;br /&gt;
Screenshot-streaming.png|Screenshot showing [[Canvas]] MFDs streamed to Firefox&amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297413#p297413&amp;lt;/ref&amp;gt;&lt;br /&gt;
Canvas-ND-live-streaming-via-httpd.png|Screenshot showing a single Canvas texture ([[NavDisplay]]) streamed to firefox via httpd at 2hz &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=30642&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Status (1/2019) ==&lt;br /&gt;
This feature was merged into the official 2018.3.1 release. It works so far. However, there are latencies and the solution isn't efficient. Just creating the PNG image from OSG takes up to 100ms.&lt;br /&gt;
For the time being, this should still be considered a &amp;quot;proof-of-concept&amp;quot; that may go through more iterations of optmizations. Integrating it into 2018.3.1 makes it possible to explore a number of opportunities to optimize the whole thing for different use-cases and solicit community feedback. Special attention might be required with situations where the canvas and/or the connection are shut down, but also to support [[Reset &amp;amp; re-init]] without causing a race  condition.&lt;br /&gt;
&lt;br /&gt;
{{Note|In its current form, the streaming capability &amp;lt;ref&amp;gt;https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;p=297716#p297716&amp;lt;/ref&amp;gt; is available but might overburden the flightgear process, depending on the number of canvases displayed. Its recommended not to use the streaming feature but to refresh the canvas from the browser. If any instability of FlightGear occurs, the remote canvas feature should be disabled for checking whether it is the reason.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
== Patches ==&lt;br /&gt;
=== SimGear ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;diff&amp;quot;&amp;gt;&lt;br /&gt;
--- /simgear/simgear/canvas/Canvas.hxx	2016-05-17 02:40:01.297701130 +0200&lt;br /&gt;
+++ canvas/Canvas.hxx	2016-10-19 16:46:47.000000000 +0200&lt;br /&gt;
@@ -44,6 +44,14 @@&lt;br /&gt;
   class CanvasMgr;&lt;br /&gt;
   class MouseEvent;&lt;br /&gt;
 &lt;br /&gt;
+  class CanvasImageReadyListener {&lt;br /&gt;
+  public:&lt;br /&gt;
+    virtual void imageReady(osg::ref_ptr&amp;lt;osg::Image&amp;gt;) = 0;&lt;br /&gt;
+    virtual ~CanvasImageReadyListener()&lt;br /&gt;
+    {&lt;br /&gt;
+    }&lt;br /&gt;
+  };&lt;br /&gt;
+&lt;br /&gt;
   /**&lt;br /&gt;
    * Canvas to draw onto (to an off-screen render target).&lt;br /&gt;
    */&lt;br /&gt;
@@ -162,6 +170,9 @@&lt;br /&gt;
 &lt;br /&gt;
       void update(double delta_time_sec);&lt;br /&gt;
 &lt;br /&gt;
+      int subscribe(CanvasImageReadyListener * subscriber);&lt;br /&gt;
+      int unsubscribe(CanvasImageReadyListener * subscriber);&lt;br /&gt;
+&lt;br /&gt;
       bool addEventListener(const std::string&amp;amp; type, const EventListener&amp;amp; cb);&lt;br /&gt;
       bool dispatchEvent(const EventPtr&amp;amp; event);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;diff&amp;quot;&amp;gt;&lt;br /&gt;
--- /simgear/simgear/canvas/Canvas.cxx	2016-05-17 02:40:01.297701130 +0200&lt;br /&gt;
+++ Canvas.cxx	2016-10-20 08:04:14.000000000 +0200&lt;br /&gt;
@@ -37,6 +37,66 @@&lt;br /&gt;
 {&lt;br /&gt;
 namespace canvas&lt;br /&gt;
 {&lt;br /&gt;
+  class CanvasImageCallback : public osg::Camera::DrawCallback {&lt;br /&gt;
+  public:&lt;br /&gt;
+  osg::Image *_rawImage;&lt;br /&gt;
+&lt;br /&gt;
+  CanvasImageCallback(osg::Image *rawImage)&lt;br /&gt;
+  : _min_delta_tick(1.0 / 8.0) {&lt;br /&gt;
+    _previousFrameTick = osg::Timer::instance()-&amp;gt;tick();&lt;br /&gt;
+    _rawImage = rawImage;&lt;br /&gt;
+  }&lt;br /&gt;
+&lt;br /&gt;
+  virtual void operator()(osg::RenderInfo&amp;amp; renderInfo/*const osg::Camera&amp;amp; camera*/) const {&lt;br /&gt;
+    osg::Timer_t n = osg::Timer::instance()-&amp;gt;tick();&lt;br /&gt;
+    double dt = osg::Timer::instance()-&amp;gt;delta_s(_previousFrameTick, n);&lt;br /&gt;
+    if (dt &amp;lt; _min_delta_tick)&lt;br /&gt;
+      return;&lt;br /&gt;
+    _previousFrameTick = n;&lt;br /&gt;
+&lt;br /&gt;
+    bool hasSubscribers = false;&lt;br /&gt;
+    {&lt;br /&gt;
+      OpenThreads::ScopedLock&amp;lt;OpenThreads::Mutex&amp;gt; lock(_lock);&lt;br /&gt;
+      hasSubscribers = !_subscribers.empty();&lt;br /&gt;
+    }&lt;br /&gt;
+    if (hasSubscribers) {&lt;br /&gt;
+      //Make sure image can be overwritten by next frame while it is still returned to the client&lt;br /&gt;
+      osg::Image* image = new osg::Image(*_rawImage, osg::CopyOp::DEEP_COPY_ALL);&lt;br /&gt;
+      {&lt;br /&gt;
+        OpenThreads::ScopedLock&amp;lt;OpenThreads::Mutex&amp;gt; lock(_lock);&lt;br /&gt;
+        while (!_subscribers.empty()) {&lt;br /&gt;
+          try {&lt;br /&gt;
+            SG_LOG(SG_GENERAL,SG_INFO,&amp;quot;CanvasImageCallback image ready for subscriber&amp;quot;);&lt;br /&gt;
+            CanvasImageReadyListener *subs = _subscribers.back();&lt;br /&gt;
+            if (subs){&lt;br /&gt;
+              subs-&amp;gt;imageReady(image);&lt;br /&gt;
+            }else{&lt;br /&gt;
+              SG_LOG(SG_GENERAL,SG_WARN,&amp;quot;CanvasImageCallback subscriber null&amp;quot;);&lt;br /&gt;
+            }&lt;br /&gt;
+          } catch (...) { }&lt;br /&gt;
+          _subscribers.pop_back();&lt;br /&gt;
+        }&lt;br /&gt;
+      }&lt;br /&gt;
+    }&lt;br /&gt;
+  }&lt;br /&gt;
+&lt;br /&gt;
+  void subscribe(CanvasImageReadyListener * subscriber) {&lt;br /&gt;
+    OpenThreads::ScopedLock&amp;lt;OpenThreads::Mutex&amp;gt; lock(_lock);&lt;br /&gt;
+    _subscribers.push_back(subscriber);&lt;br /&gt;
+  }&lt;br /&gt;
+&lt;br /&gt;
+  void unsubscribe(CanvasImageReadyListener * subscriber) {&lt;br /&gt;
+    OpenThreads::ScopedLock&amp;lt;OpenThreads::Mutex&amp;gt; lock(_lock);&lt;br /&gt;
+    _subscribers.remove(subscriber);&lt;br /&gt;
+  }&lt;br /&gt;
+&lt;br /&gt;
+  private:&lt;br /&gt;
+    mutable list&amp;lt;CanvasImageReadyListener*&amp;gt; _subscribers;&lt;br /&gt;
+    mutable OpenThreads::Mutex _lock;&lt;br /&gt;
+    mutable double _previousFrameTick;&lt;br /&gt;
+    double _min_delta_tick;&lt;br /&gt;
+  };&lt;br /&gt;
+&lt;br /&gt;
 &lt;br /&gt;
   //----------------------------------------------------------------------------&lt;br /&gt;
   Canvas::CullCallback::CullCallback(const CanvasWeakPtr&amp;amp; canvas):&lt;br /&gt;
@@ -251,6 +311,22 @@&lt;br /&gt;
 &lt;br /&gt;
       osg::Camera* camera = _texture.getCamera();&lt;br /&gt;
 &lt;br /&gt;
+      const char *canvasname = _node-&amp;gt;getStringValue(&amp;quot;name&amp;quot;);&lt;br /&gt;
+      int rendertoimage = _node-&amp;gt;getBoolValue(&amp;quot;rendertoimage&amp;quot;);&lt;br /&gt;
+      if (camera &amp;amp;&amp;amp; rendertoimage &amp;amp;&amp;amp; canvasname) {&lt;br /&gt;
+        SG_LOG(SG_GENERAL,SG_INFO,&amp;quot;rendertoimage of canvas &amp;quot;&amp;lt;&amp;lt;  rendertoimage);&lt;br /&gt;
+&lt;br /&gt;
+        CanvasImageCallback *_screenshotCallback = dynamic_cast&amp;lt;CanvasImageCallback*&amp;gt; (camera-&amp;gt;getFinalDrawCallback());&lt;br /&gt;
+        if (!_screenshotCallback) {&lt;br /&gt;
+          osg::Image* shot = new osg::Image();&lt;br /&gt;
+          shot-&amp;gt;allocateImage(getSizeX(), getSizeY(), 24, GL_RGB, GL_UNSIGNED_BYTE);&lt;br /&gt;
+          camera-&amp;gt;attach(osg::Camera::COLOR_BUFFER, shot);&lt;br /&gt;
+          camera-&amp;gt;setFinalDrawCallback(new CanvasImageCallback(shot));&lt;br /&gt;
+          SG_LOG(SG_GENERAL,SG_INFO,&amp;quot;attached&amp;quot;);&lt;br /&gt;
+        }&lt;br /&gt;
+      }&lt;br /&gt;
+&lt;br /&gt;
+&lt;br /&gt;
       // TODO Allow custom render order? For now just keep in order with&lt;br /&gt;
       //      property tree.&lt;br /&gt;
       camera-&amp;gt;setRenderOrder(osg::Camera::PRE_RENDER, _node-&amp;gt;getIndex());&lt;br /&gt;
@@ -350,6 +426,36 @@&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
+  int Canvas::subscribe(CanvasImageReadyListener * subscriber) {&lt;br /&gt;
+    if (!_node-&amp;gt;getBoolValue(&amp;quot;rendertoimage&amp;quot;)) {&lt;br /&gt;
+      SG_LOG(SG_GENERAL,SG_INFO,&amp;quot;Setting rendertoimage&amp;quot;);&lt;br /&gt;
+      _node-&amp;gt;addChild(&amp;quot;rendertoimage&amp;quot;, 0)-&amp;gt;setBoolValue(1);&lt;br /&gt;
+      setStatusFlags(STATUS_DIRTY, true);&lt;br /&gt;
+    }&lt;br /&gt;
+&lt;br /&gt;
+    osg::Camera* camera = _texture.getCamera();&lt;br /&gt;
+    SG_LOG(SG_GENERAL,SG_INFO,&amp;quot;Canvas: subscribe to camera &amp;quot;&amp;lt;&amp;lt; camera);&lt;br /&gt;
+    CanvasImageCallback *_screenshotCallback = dynamic_cast&amp;lt;CanvasImageCallback*&amp;gt; (camera-&amp;gt;getFinalDrawCallback());&lt;br /&gt;
+    if (_screenshotCallback) {&lt;br /&gt;
+      SG_LOG(SG_GENERAL,SG_INFO,&amp;quot;Canvas: really subscribe to camera &amp;quot;);&lt;br /&gt;
+      _screenshotCallback-&amp;gt;subscribe(subscriber);&lt;br /&gt;
+      // TODO: check: Is this the correct way to ensure the canvas will be available?&lt;br /&gt;
+      enableRendering(true);&lt;br /&gt;
+    }&lt;br /&gt;
+    return 0;&lt;br /&gt;
+  }&lt;br /&gt;
+&lt;br /&gt;
+  int Canvas::unsubscribe(CanvasImageReadyListener * subscriber) {&lt;br /&gt;
+    osg::Camera* camera = _texture.getCamera();&lt;br /&gt;
+    SG_LOG(SG_GENERAL,SG_INFO,&amp;quot;CanvasImage: unsubscribe from camera &amp;quot;&amp;lt;&amp;lt; camera);&lt;br /&gt;
+    CanvasImageCallback *cb = dynamic_cast&amp;lt;CanvasImageCallback*&amp;gt; (camera-&amp;gt;getFinalDrawCallback());&lt;br /&gt;
+    if (cb) {&lt;br /&gt;
+      SG_LOG(SG_GENERAL,SG_INFO,&amp;quot;CanvasImage: unsubscribe &amp;quot;);&lt;br /&gt;
+      cb-&amp;gt;unsubscribe(subscriber);&lt;br /&gt;
+    }&lt;br /&gt;
+    return 0;&lt;br /&gt;
+  }&lt;br /&gt;
+&lt;br /&gt;
   //----------------------------------------------------------------------------&lt;br /&gt;
   bool Canvas::addEventListener( const std::string&amp;amp; type,&lt;br /&gt;
                                  const EventListener&amp;amp; cb )&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== FlightGear ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;diff&amp;quot;&amp;gt;&lt;br /&gt;
diff --git a/src/Canvas/canvas_mgr.cxx b/src/Canvas/canvas_mgr.cxx&lt;br /&gt;
index 6646b77..5316543 100644&lt;br /&gt;
--- a/src/Canvas/canvas_mgr.cxx&lt;br /&gt;
+++ b/src/Canvas/canvas_mgr.cxx&lt;br /&gt;
@@ -64,7 +64,7 @@ CanvasMgr::CanvasMgr():&lt;br /&gt;
     fgGetNode(&amp;quot;/sim/signals/model-reinit&amp;quot;, true)&lt;br /&gt;
   )&lt;br /&gt;
 {&lt;br /&gt;
-&lt;br /&gt;
+ SG_LOG(SG_GENERAL, SG_ALERT, &amp;quot;CanvasMgr() constructor invoked&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 //----------------------------------------------------------------------------&lt;br /&gt;
diff --git a/src/Network/http/CMakeLists.txt b/src/Network/http/CMakeLists.txt&lt;br /&gt;
index 9e913d0..1a099cb 100644&lt;br /&gt;
--- a/src/Network/http/CMakeLists.txt&lt;br /&gt;
+++ b/src/Network/http/CMakeLists.txt&lt;br /&gt;
@@ -3,6 +3,7 @@ include(FlightGearComponent)&lt;br /&gt;
 set(SOURCES&lt;br /&gt;
 	httpd.cxx&lt;br /&gt;
 	ScreenshotUriHandler.cxx&lt;br /&gt;
+	CanvasImageUriHandler.cxx&lt;br /&gt;
 	PropertyUriHandler.cxx&lt;br /&gt;
 	JsonUriHandler.cxx&lt;br /&gt;
     FlightHistoryUriHandler.cxx&lt;br /&gt;
@@ -19,6 +20,7 @@ set(HEADERS&lt;br /&gt;
 	urihandler.hxx&lt;br /&gt;
 	httpd.hxx&lt;br /&gt;
 	ScreenshotUriHandler.hxx&lt;br /&gt;
+	CanvasImageUriHandler.hxx&lt;br /&gt;
 	PropertyUriHandler.hxx&lt;br /&gt;
 	JsonUriHandler.hxx&lt;br /&gt;
     FlightHistoryUriHandler.hxx&lt;br /&gt;
diff --git a/src/Network/http/CanvasImageUriHandler.cxx b/src/Network/http/CanvasImageUriHandler.cxx&lt;br /&gt;
new file mode 100644&lt;br /&gt;
index 0000000..7cd5a0e&lt;br /&gt;
--- /dev/null&lt;br /&gt;
+++ b/src/Network/http/CanvasImageUriHandler.cxx&lt;br /&gt;
@@ -0,0 +1,335 @@&lt;br /&gt;
+// CanvasImageUriHandler.cxx -- Provide canvasimages via http&lt;br /&gt;
+//&lt;br /&gt;
+// Started by Curtis Olson, started June 2001.&lt;br /&gt;
+// osg support written by James Turner&lt;br /&gt;
+// Ported to new httpd infrastructure by Torsten Dreyer&lt;br /&gt;
+// Derived from ScreenshotUrihandler originally by Torsten Dreyer)&lt;br /&gt;
+//&lt;br /&gt;
+// This program is free software; you can redistribute it and/or&lt;br /&gt;
+// modify it under the terms of the GNU General Public License as&lt;br /&gt;
+// published by the Free Software Foundation; either version 2 of the&lt;br /&gt;
+// License, or (at your option) any later version.&lt;br /&gt;
+//&lt;br /&gt;
+// This program is distributed in the hope that it will be useful, but&lt;br /&gt;
+// WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU&lt;br /&gt;
+// General Public License for more details.&lt;br /&gt;
+//&lt;br /&gt;
+// You should have received a copy of the GNU General Public License&lt;br /&gt;
+// along with this program; if not, write to the Free Software&lt;br /&gt;
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.&lt;br /&gt;
+&lt;br /&gt;
+#include &amp;quot;CanvasImageUriHandler.hxx&amp;quot;&lt;br /&gt;
+&lt;br /&gt;
+#ifdef _WIN32&lt;br /&gt;
+#include &amp;lt;windows.h&amp;gt;&lt;br /&gt;
+#endif&lt;br /&gt;
+#include &amp;lt;osgDB/Registry&amp;gt;&lt;br /&gt;
+#include &amp;lt;osgDB/ReaderWriter&amp;gt;&lt;br /&gt;
+#include &amp;lt;osgUtil/SceneView&amp;gt;&lt;br /&gt;
+#include &amp;lt;osgViewer/Viewer&amp;gt;&lt;br /&gt;
+&lt;br /&gt;
+#include &amp;lt;Canvas/canvas_mgr.hxx&amp;gt;&lt;br /&gt;
+#include &amp;lt;simgear/canvas/Canvas.hxx&amp;gt;&lt;br /&gt;
+&lt;br /&gt;
+#include &amp;lt;simgear/threads/SGQueue.hxx&amp;gt;&lt;br /&gt;
+#include &amp;lt;simgear/structure/Singleton.hxx&amp;gt;&lt;br /&gt;
+#include &amp;lt;Main/globals.hxx&amp;gt;&lt;br /&gt;
+#include &amp;lt;Viewer/renderer.hxx&amp;gt;&lt;br /&gt;
+&lt;br /&gt;
+#include &amp;lt;queue&amp;gt;&lt;br /&gt;
+#include &amp;lt;boost/lexical_cast.hpp&amp;gt;&lt;br /&gt;
+&lt;br /&gt;
+using std::string;&lt;br /&gt;
+using std::vector;&lt;br /&gt;
+using std::list;&lt;br /&gt;
+&lt;br /&gt;
+namespace sc = simgear::canvas;&lt;br /&gt;
+&lt;br /&gt;
+namespace flightgear {&lt;br /&gt;
+    namespace http {&lt;br /&gt;
+&lt;br /&gt;
+        ///////////////////////////////////////////////////////////////////////////&lt;br /&gt;
+&lt;br /&gt;
+        class StringReadyListener {&lt;br /&gt;
+        public:&lt;br /&gt;
+            virtual void stringReady(const std::string &amp;amp;) = 0;&lt;br /&gt;
+&lt;br /&gt;
+            virtual ~StringReadyListener() {&lt;br /&gt;
+            }&lt;br /&gt;
+        };&lt;br /&gt;
+&lt;br /&gt;
+        struct ImageCompressionTask {&lt;br /&gt;
+            StringReadyListener * stringReadyListener;&lt;br /&gt;
+            string format;&lt;br /&gt;
+            osg::ref_ptr&amp;lt;osg::Image&amp;gt; image;&lt;br /&gt;
+&lt;br /&gt;
+            ImageCompressionTask() {&lt;br /&gt;
+                stringReadyListener = NULL;&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            ImageCompressionTask(const ImageCompressionTask &amp;amp; other) {&lt;br /&gt;
+                stringReadyListener = other.stringReadyListener;&lt;br /&gt;
+                format = other.format;&lt;br /&gt;
+                image = other.image;&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            ImageCompressionTask &amp;amp; operator=(const ImageCompressionTask &amp;amp; other) {&lt;br /&gt;
+                stringReadyListener = other.stringReadyListener;&lt;br /&gt;
+                format = other.format;&lt;br /&gt;
+                image = other.image;&lt;br /&gt;
+                return *this;&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+        };&lt;br /&gt;
+        //TODO reuse from screenshoturihandler&lt;br /&gt;
+&lt;br /&gt;
+        class ImageCompressorCI : public OpenThreads::Thread {&lt;br /&gt;
+        public:&lt;br /&gt;
+&lt;br /&gt;
+            ImageCompressorCI() {&lt;br /&gt;
+            }&lt;br /&gt;
+            virtual void run();&lt;br /&gt;
+            void addTask(ImageCompressionTask &amp;amp; task);&lt;br /&gt;
+        private:&lt;br /&gt;
+            typedef SGBlockingQueue&amp;lt;ImageCompressionTask&amp;gt; TaskList;&lt;br /&gt;
+            TaskList _tasks;&lt;br /&gt;
+        };&lt;br /&gt;
+&lt;br /&gt;
+        typedef simgear::Singleton&amp;lt;ImageCompressorCI&amp;gt; ImageCompressorCISingleton;&lt;br /&gt;
+&lt;br /&gt;
+        void ImageCompressorCI::run() {&lt;br /&gt;
+            osg::ref_ptr&amp;lt;osgDB::ReaderWriter::Options&amp;gt; options = new osgDB::ReaderWriter::Options(&amp;quot;JPEG_QUALITY 80 PNG_COMPRESSION 9&amp;quot;);&lt;br /&gt;
+&lt;br /&gt;
+            SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;ImageCompressorCI is running&amp;quot;);&lt;br /&gt;
+            for (;;) {&lt;br /&gt;
+                ImageCompressionTask task = _tasks.pop();&lt;br /&gt;
+                SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;ImageCompressorCI has an image&amp;quot;);&lt;br /&gt;
+&lt;br /&gt;
+                if (NULL != task.stringReadyListener) {&lt;br /&gt;
+                    SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;ImageCompressorCI checking for writer for &amp;quot; &amp;lt;&amp;lt; task.format);&lt;br /&gt;
+                    osgDB::ReaderWriter* writer = osgDB::Registry::instance()-&amp;gt;getReaderWriterForExtension(task.format);&lt;br /&gt;
+                    if (!writer)&lt;br /&gt;
+                        continue;&lt;br /&gt;
+&lt;br /&gt;
+                    SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;ImageCompressorCI compressing to &amp;quot; &amp;lt;&amp;lt; task.format);&lt;br /&gt;
+                    std::stringstream outputStream;&lt;br /&gt;
+                    osgDB::ReaderWriter::WriteResult wr;&lt;br /&gt;
+                    wr = writer-&amp;gt;writeImage(*task.image, outputStream, options);&lt;br /&gt;
+&lt;br /&gt;
+                    if (wr.success()) {&lt;br /&gt;
+                        SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;ImageCompressorCI compressed to  &amp;quot; &amp;lt;&amp;lt; task.format);&lt;br /&gt;
+                        task.stringReadyListener-&amp;gt;stringReady(outputStream.str());&lt;br /&gt;
+                    }&lt;br /&gt;
+                    SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;ImageCompressorCI done for this image&amp;quot; &amp;lt;&amp;lt; task.format);&lt;br /&gt;
+&lt;br /&gt;
+                }&lt;br /&gt;
+            }&lt;br /&gt;
+            SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;ImageCompressorCI exiting&amp;quot;);&lt;br /&gt;
+        }&lt;br /&gt;
+&lt;br /&gt;
+        void ImageCompressorCI::addTask(ImageCompressionTask &amp;amp; task) {&lt;br /&gt;
+            _tasks.push(task);&lt;br /&gt;
+        }&lt;br /&gt;
+&lt;br /&gt;
+&lt;br /&gt;
+        ///////////////////////////////////////////////////////////////////////////&lt;br /&gt;
+&lt;br /&gt;
+        class CanvasImageRequest : public ConnectionData, public simgear::canvas::CanvasImageReadyListener, StringReadyListener {&lt;br /&gt;
+        public:&lt;br /&gt;
+            ImageCompressionTask *currenttask=NULL;&lt;br /&gt;
+            sc::CanvasPtr canvas;&lt;br /&gt;
+&lt;br /&gt;
+            CanvasImageRequest(const string &amp;amp; window, const string &amp;amp; type, int canvasindex, bool stream)&lt;br /&gt;
+            : _type(type), _stream(stream) {&lt;br /&gt;
+                SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;CanvasImageRequest: \n&amp;quot;);&lt;br /&gt;
+                &lt;br /&gt;
+                if (NULL == osgDB::Registry::instance()-&amp;gt;getReaderWriterForExtension(_type))&lt;br /&gt;
+                    throw sg_format_exception(&amp;quot;Unsupported image type: &amp;quot; + type, type);&lt;br /&gt;
+&lt;br /&gt;
+                CanvasMgr* canvas_mgr = static_cast&amp;lt;CanvasMgr*&amp;gt; (globals-&amp;gt;get_subsystem(&amp;quot;Canvas&amp;quot;));&lt;br /&gt;
+                if (!canvas_mgr) {&lt;br /&gt;
+                    SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;CanvasImage:CanvasMgr not found\n&amp;quot;);&lt;br /&gt;
+                } else {&lt;br /&gt;
+                    canvas = canvas_mgr-&amp;gt;getCanvas(canvasindex);&lt;br /&gt;
+                    if (!canvas) {&lt;br /&gt;
+                        SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;CanvasImage:Canvas not found\n&amp;quot;);&lt;br /&gt;
+                    } else {&lt;br /&gt;
+                        SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;CanvasImage:Canvas found\n&amp;quot;);&lt;br /&gt;
+                        //SG_LOG(SG_NETWORK, SG_DEBUG, &amp;quot;CanvasImageRequest: found camera %d. width=%d, height=%d\n&amp;quot;, camera, canvas-&amp;gt;getSizeX(), canvas-&amp;gt;getSizeY());&lt;br /&gt;
+&lt;br /&gt;
+                        SGConstPropertyNode_ptr canvasnode = canvas-&amp;gt;getProps();&lt;br /&gt;
+                        if (canvasnode) {&lt;br /&gt;
+                            const char *canvasname = canvasnode-&amp;gt;getStringValue(&amp;quot;name&amp;quot;);&lt;br /&gt;
+                            if (canvasname) {&lt;br /&gt;
+                                SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;CanvasImageRequest: node=%s(%s)\n&amp;quot;);//, canvasnode-&amp;gt;getDisplayName().c_str(), canvasname);&lt;br /&gt;
+                            }&lt;br /&gt;
+                        }&lt;br /&gt;
+&lt;br /&gt;
+                        canvas-&amp;gt;subscribe(this);&lt;br /&gt;
+                    }&lt;br /&gt;
+                }&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            // Assumption: when unsubscribe returns,there might just be a compressor thread running,&lt;br /&gt;
+            // causing a crash when the deconstructor finishes. Rare, but might happen. Just wait to be sure.&lt;br /&gt;
+            virtual ~CanvasImageRequest() {&lt;br /&gt;
+                if (currenttask){&lt;br /&gt;
+                    SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;canvasimage task running&amp;quot;);&lt;br /&gt;
+#ifdef _WIN32&lt;br /&gt;
+                    Sleep(15000);&lt;br /&gt;
+#else&lt;br /&gt;
+                     sleep(15);&lt;br /&gt;
+#endif&lt;br /&gt;
+                }&lt;br /&gt;
+&lt;br /&gt;
+                if (canvas){&lt;br /&gt;
+                    canvas-&amp;gt;unsubscribe(this);&lt;br /&gt;
+                }&lt;br /&gt;
+                //_canvasimageCallback-&amp;gt;unsubscribe(this);&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            virtual void imageReady(osg::ref_ptr&amp;lt;osg::Image&amp;gt; rawImage) {&lt;br /&gt;
+                SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;CanvasImage:imageReady&amp;quot;);&lt;br /&gt;
+                // called from a rendering thread, not from the main loop&lt;br /&gt;
+                ImageCompressionTask task;&lt;br /&gt;
+                currenttask = &amp;amp;task;&lt;br /&gt;
+                task.image = rawImage;&lt;br /&gt;
+                task.format = _type;&lt;br /&gt;
+                task.stringReadyListener = this;&lt;br /&gt;
+                ImageCompressorCISingleton::instance()-&amp;gt;addTask(task);&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            void requestCanvasImage() {&lt;br /&gt;
+            //    _canvasimageCallback-&amp;gt;subscribe(this);&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            mutable OpenThreads::Mutex _lock;&lt;br /&gt;
+&lt;br /&gt;
+            virtual void stringReady(const string &amp;amp; s) {&lt;br /&gt;
+                SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;CanvasImage:stringReady&amp;quot;);&lt;br /&gt;
+                &lt;br /&gt;
+                // called from the compressor thread&lt;br /&gt;
+                OpenThreads::ScopedLock&amp;lt;OpenThreads::Mutex&amp;gt; lock(_lock);&lt;br /&gt;
+                _compressedData = s;&lt;br /&gt;
+                // allow destructor&lt;br /&gt;
+                currenttask = NULL;&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            string getCanvasImage() {&lt;br /&gt;
+                string reply;&lt;br /&gt;
+                {&lt;br /&gt;
+                    // called from the main loop&lt;br /&gt;
+                    OpenThreads::ScopedLock&amp;lt;OpenThreads::Mutex&amp;gt; lock(_lock);&lt;br /&gt;
+                    reply = _compressedData;&lt;br /&gt;
+                    _compressedData.clear();&lt;br /&gt;
+                }&lt;br /&gt;
+                return reply;&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            bool isStream() const {&lt;br /&gt;
+                return _stream;&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            const string &amp;amp; getType() const {&lt;br /&gt;
+                return _type;&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+        private:&lt;br /&gt;
+            string _type;&lt;br /&gt;
+            bool _stream;&lt;br /&gt;
+            string _compressedData;&lt;br /&gt;
+            //CanvasImageCallback * _canvasimageCallback;&lt;br /&gt;
+        };&lt;br /&gt;
+&lt;br /&gt;
+        CanvasImageUriHandler::CanvasImageUriHandler(const char * uri)&lt;br /&gt;
+        : URIHandler(uri) {&lt;br /&gt;
+        }&lt;br /&gt;
+&lt;br /&gt;
+        CanvasImageUriHandler::~CanvasImageUriHandler() {&lt;br /&gt;
+            ImageCompressorCISingleton::instance()-&amp;gt;cancel();&lt;br /&gt;
+            //ImageCompressorSingleton::instance()-&amp;gt;join();&lt;br /&gt;
+        }&lt;br /&gt;
+&lt;br /&gt;
+        const static string KEY(&amp;quot;CanvasImageUriHandler::CanvasImageRequest&amp;quot;);&lt;br /&gt;
+#define BOUNDARY &amp;quot;--fgfs-canvasimage-boundary&amp;quot;&lt;br /&gt;
+&lt;br /&gt;
+        bool CanvasImageUriHandler::handleGetRequest(const HTTPRequest &amp;amp; request, HTTPResponse &amp;amp; response, Connection * connection) {&lt;br /&gt;
+            if (!ImageCompressorCISingleton::instance()-&amp;gt;isRunning())&lt;br /&gt;
+                ImageCompressorCISingleton::instance()-&amp;gt;start();&lt;br /&gt;
+&lt;br /&gt;
+            string type = request.RequestVariables.get(&amp;quot;type&amp;quot;);&lt;br /&gt;
+            if (type.empty()) type = &amp;quot;jpg&amp;quot;;&lt;br /&gt;
+&lt;br /&gt;
+            string canvasindex = request.RequestVariables.get(&amp;quot;canvasindex&amp;quot;);&lt;br /&gt;
+            if (canvasindex.empty()) canvasindex = &amp;quot;0&amp;quot;;&lt;br /&gt;
+            &lt;br /&gt;
+            //  string camera = request.RequestVariables.get(&amp;quot;camera&amp;quot;);&lt;br /&gt;
+            string window = request.RequestVariables.get(&amp;quot;window&amp;quot;);&lt;br /&gt;
+&lt;br /&gt;
+            bool stream = (false == request.RequestVariables.get(&amp;quot;stream&amp;quot;).empty());&lt;br /&gt;
+&lt;br /&gt;
+            SGSharedPtr&amp;lt;CanvasImageRequest&amp;gt; canvasimageRequest;&lt;br /&gt;
+            try {&lt;br /&gt;
+                SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;new CanvasImageRequest(&amp;quot; &amp;lt;&amp;lt; window &amp;lt;&amp;lt; &amp;quot;,&amp;quot; &amp;lt;&amp;lt; type &amp;lt;&amp;lt; &amp;quot;,&amp;quot; &amp;lt;&amp;lt; stream &amp;lt;&amp;lt; &amp;quot;)&amp;quot;);&lt;br /&gt;
+                canvasimageRequest = new CanvasImageRequest(window, type, atoi(canvasindex.c_str()),stream);&lt;br /&gt;
+            } catch (sg_format_exception &amp;amp; ex) {&lt;br /&gt;
+                SG_LOG(SG_NETWORK, SG_INFO, ex.getFormattedMessage());&lt;br /&gt;
+                response.Header[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/plain&amp;quot;;&lt;br /&gt;
+                response.StatusCode = 410;&lt;br /&gt;
+                response.Content = ex.getFormattedMessage();&lt;br /&gt;
+                return true;&lt;br /&gt;
+            } catch (sg_error &amp;amp; ex) {&lt;br /&gt;
+                SG_LOG(SG_NETWORK, SG_INFO, ex.getFormattedMessage());&lt;br /&gt;
+                response.Header[&amp;quot;Content-Type&amp;quot;] = &amp;quot;text/plain&amp;quot;;&lt;br /&gt;
+                response.StatusCode = 500;&lt;br /&gt;
+                response.Content = ex.getFormattedMessage();&lt;br /&gt;
+                return true;&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            if (false == stream) {&lt;br /&gt;
+                response.Header[&amp;quot;Content-Type&amp;quot;] = string(&amp;quot;image/&amp;quot;).append(type);&lt;br /&gt;
+                response.Header[&amp;quot;Content-Disposition&amp;quot;] = string(&amp;quot;inline; filename=\&amp;quot;fgfs-canvasimage.&amp;quot;).append(type).append(&amp;quot;\&amp;quot;&amp;quot;);&lt;br /&gt;
+            } else {&lt;br /&gt;
+                response.Header[&amp;quot;Content-Type&amp;quot;] = string(&amp;quot;multipart/x-mixed-replace; boundary=&amp;quot; BOUNDARY);&lt;br /&gt;
+&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            connection-&amp;gt;put(KEY, canvasimageRequest);&lt;br /&gt;
+            return false; // call me again thru poll&lt;br /&gt;
+        }&lt;br /&gt;
+&lt;br /&gt;
+        bool CanvasImageUriHandler::poll(Connection * connection) {&lt;br /&gt;
+&lt;br /&gt;
+            SGSharedPtr&amp;lt;ConnectionData&amp;gt; data = connection-&amp;gt;get(KEY);&lt;br /&gt;
+            CanvasImageRequest * canvasimageRequest = dynamic_cast&amp;lt;CanvasImageRequest*&amp;gt; (data.get());&lt;br /&gt;
+            if (NULL == canvasimageRequest) return true; // Should not happen, kill the connection&lt;br /&gt;
+&lt;br /&gt;
+            const string &amp;amp; canvasimage = canvasimageRequest-&amp;gt;getCanvasImage();&lt;br /&gt;
+            if (canvasimage.empty()) {&lt;br /&gt;
+                SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;No canvasimage available.&amp;quot;);&lt;br /&gt;
+                return false; // not ready yet, call again.&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;CanvasImage is ready, size=&amp;quot; &amp;lt;&amp;lt; canvasimage.size());&lt;br /&gt;
+&lt;br /&gt;
+            if (canvasimageRequest-&amp;gt;isStream()) {&lt;br /&gt;
+                string s(BOUNDARY &amp;quot;\r\nContent-Type: image/&amp;quot;);&lt;br /&gt;
+                s.append(canvasimageRequest-&amp;gt;getType()).append(&amp;quot;\r\nContent-Length:&amp;quot;);&lt;br /&gt;
+                s += boost::lexical_cast&amp;lt;string&amp;gt;(canvasimage.size());&lt;br /&gt;
+                s += &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
+                connection-&amp;gt;write(s.c_str(), s.length());&lt;br /&gt;
+            }&lt;br /&gt;
+&lt;br /&gt;
+            connection-&amp;gt;write(canvasimage.data(), canvasimage.size());&lt;br /&gt;
+&lt;br /&gt;
+            /* unknown purpose&lt;br /&gt;
+            if (canvasimageRequest-&amp;gt;isStream()) {&lt;br /&gt;
+                canvasimageRequest-&amp;gt;requestCanvasImage();&lt;br /&gt;
+                // continue until user closes connection&lt;br /&gt;
+                return false;&lt;br /&gt;
+            }&lt;br /&gt;
+            */&lt;br /&gt;
+&lt;br /&gt;
+            // single canvasimage, send terminating chunk&lt;br /&gt;
+            connection-&amp;gt;remove(KEY);&lt;br /&gt;
+            connection-&amp;gt;write(&amp;quot;&amp;quot;, 0);&lt;br /&gt;
+            return true; // done.&lt;br /&gt;
+        }&lt;br /&gt;
+&lt;br /&gt;
+    } // namespace http&lt;br /&gt;
+} // namespace flightgear&lt;br /&gt;
+&lt;br /&gt;
diff --git a/src/Network/http/CanvasImageUriHandler.hxx b/src/Network/http/CanvasImageUriHandler.hxx&lt;br /&gt;
new file mode 100644&lt;br /&gt;
index 0000000..f50be37&lt;br /&gt;
--- /dev/null&lt;br /&gt;
+++ b/src/Network/http/CanvasImageUriHandler.hxx&lt;br /&gt;
@@ -0,0 +1,40 @@&lt;br /&gt;
+// CanvasImageUriHandler.hxx -- Provide canvasimages via http&lt;br /&gt;
+//&lt;br /&gt;
+// Written by Torsten Dreyer, started April 2014.&lt;br /&gt;
+//&lt;br /&gt;
+// Copyright (C) 2014  Torsten Dreyer&lt;br /&gt;
+// derived from ScreenshotUrihandler by ThomasS&lt;br /&gt;
+// This program is free software; you can redistribute it and/or&lt;br /&gt;
+// modify it under the terms of the GNU General Public License as&lt;br /&gt;
+// published by the Free Software Foundation; either version 2 of the&lt;br /&gt;
+// License, or (at your option) any later version.&lt;br /&gt;
+//&lt;br /&gt;
+// This program is distributed in the hope that it will be useful, but&lt;br /&gt;
+// WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU&lt;br /&gt;
+// General Public License for more details.&lt;br /&gt;
+//&lt;br /&gt;
+// You should have received a copy of the GNU General Public License&lt;br /&gt;
+// along with this program; if not, write to the Free Software&lt;br /&gt;
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.&lt;br /&gt;
+&lt;br /&gt;
+#ifndef __FG_CANVASIMAGE_URI_HANDLER_HXX&lt;br /&gt;
+#define __FG_CANVASIMAGE_URI_HANDLER_HXX&lt;br /&gt;
+&lt;br /&gt;
+#include &amp;quot;urihandler.hxx&amp;quot;&lt;br /&gt;
+&lt;br /&gt;
+namespace flightgear {&lt;br /&gt;
+namespace http {&lt;br /&gt;
+&lt;br /&gt;
+class CanvasImageUriHandler : public URIHandler {&lt;br /&gt;
+public:&lt;br /&gt;
+  CanvasImageUriHandler( const char * uri = &amp;quot;/canvasimage/&amp;quot; );&lt;br /&gt;
+  ~CanvasImageUriHandler();&lt;br /&gt;
+  virtual bool handleGetRequest( const HTTPRequest &amp;amp; request, HTTPResponse &amp;amp; response, Connection * connection );&lt;br /&gt;
+  virtual bool poll( Connection * connection );&lt;br /&gt;
+};&lt;br /&gt;
+&lt;br /&gt;
+} // namespace http&lt;br /&gt;
+} // namespace flightgear&lt;br /&gt;
+&lt;br /&gt;
+#endif //#define __FG_CANVASIMAGE_URI_HANDLER_HXX&lt;br /&gt;
diff --git a/src/Network/http/httpd.cxx b/src/Network/http/httpd.cxx&lt;br /&gt;
index 358b247..3bfff3a 100644&lt;br /&gt;
--- a/src/Network/http/httpd.cxx&lt;br /&gt;
+++ b/src/Network/http/httpd.cxx&lt;br /&gt;
@@ -22,6 +22,7 @@&lt;br /&gt;
 #include &amp;quot;HTTPRequest.hxx&amp;quot;&lt;br /&gt;
 #include &amp;quot;PropertyChangeWebsocket.hxx&amp;quot;&lt;br /&gt;
 #include &amp;quot;ScreenshotUriHandler.hxx&amp;quot;&lt;br /&gt;
+#include &amp;quot;CanvasImageUriHandler.hxx&amp;quot;&lt;br /&gt;
 #include &amp;quot;PropertyUriHandler.hxx&amp;quot;&lt;br /&gt;
 #include &amp;quot;JsonUriHandler.hxx&amp;quot;&lt;br /&gt;
 #include &amp;quot;FlightHistoryUriHandler.hxx&amp;quot;&lt;br /&gt;
@@ -443,6 +444,11 @@ void MongooseHttpd::init()&lt;br /&gt;
       _uriHandler.push_back(new flightgear::http::ScreenshotUriHandler(uri));&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
+if ((uri = n-&amp;gt;getStringValue(&amp;quot;canvasimage&amp;quot;))[0] != 0) {&lt;br /&gt;
+      SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;httpd: adding canvasimage uri handler at &amp;quot; &amp;lt;&amp;lt; uri);&lt;br /&gt;
+      _uriHandler.push_back(new flightgear::http::CanvasImageUriHandler(uri));&lt;br /&gt;
+    }&lt;br /&gt;
+&lt;br /&gt;
     if ((uri = n-&amp;gt;getStringValue(&amp;quot;property&amp;quot;))[0] != 0) {&lt;br /&gt;
       SG_LOG(SG_NETWORK, SG_INFO, &amp;quot;httpd: adding property uri handler at &amp;quot; &amp;lt;&amp;lt; uri);&lt;br /&gt;
       _uriHandler.push_back(new flightgear::http::PropertyUriHandler(uri));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Base Package ===&lt;br /&gt;
CanvasView.html&lt;br /&gt;
&lt;br /&gt;
{{Note|For the time being, the following HTML snippet is specific to Soitanen's 737, and contains hard-coded assumptions such as the name/index of the canvas textures to download from fgfs}. Also, you need to edit httpd-settings.xml to add a corresponding canvasimage handler there. For a Canvas to become available for streaming, set the &amp;lt;code&amp;gt;rendertoimage&amp;lt;/code&amp;gt; flag accordingly and assign a name to the top-level canvas.}} &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;!-- See Flightgear wiki for information--&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;Canvas View&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;select id=&amp;quot;sizebox&amp;quot; onChange=&amp;quot;setSize();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;256&amp;quot; selected=&amp;quot;selected&amp;quot;&amp;gt;256&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;512&amp;quot;&amp;gt;512&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;768&amp;quot;&amp;gt;768&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptPFD&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptND&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
    &amp;lt;row&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;UpperEICAS&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;img id=&amp;quot;CptCDU&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/row&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var refreshinterval=500;&lt;br /&gt;
var instruments = [&amp;quot;CptPFD&amp;quot;,&amp;quot;CptND&amp;quot;,&amp;quot;UpperEICAS&amp;quot;,&amp;quot;CptCDU&amp;quot;];&lt;br /&gt;
var canvasindex = [];&lt;br /&gt;
canvasindex[&amp;quot;CptPFD&amp;quot;] = 3;&lt;br /&gt;
canvasindex[&amp;quot;CptND&amp;quot;] = 5;&lt;br /&gt;
canvasindex[&amp;quot;UpperEICAS&amp;quot;] = 4;&lt;br /&gt;
canvasindex[&amp;quot;CptCDU&amp;quot;] = 2;&lt;br /&gt;
&lt;br /&gt;
function refreshImage(imageid) {&lt;br /&gt;
    //var image = document.getElementById(imageid);&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);    &lt;br /&gt;
&lt;br /&gt;
    var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=&amp;quot;+canvasindex[imageid];&lt;br /&gt;
    //var url = &amp;quot;http://localhost:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //var url = &amp;quot;http://192.168.98.165:5701/canvasimage?type=png&amp;amp;canvasindex=5&amp;quot;;&lt;br /&gt;
    //alert(url);&lt;br /&gt;
    image.src = url;&lt;br /&gt;
    setSize(imageid);&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
         refreshImage(imageid);&lt;br /&gt;
     }, refreshinterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setSize(imageid){&lt;br /&gt;
    var e = document.getElementById(&amp;quot;sizebox&amp;quot;);&lt;br /&gt;
    var size = e.options[e.selectedIndex].value;&lt;br /&gt;
    var image = document.querySelector(&amp;quot;#&amp;quot;+imageid);&lt;br /&gt;
    if (image != null){&lt;br /&gt;
        image.style.width=size+&amp;quot;px&amp;quot;;&lt;br /&gt;
        image.style.height=&amp;quot;auto&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; instruments.length; i++) {&lt;br /&gt;
    refreshImage(instruments[i]);&lt;br /&gt;
}&lt;br /&gt;
//refreshImage(&amp;quot;CptND&amp;quot;);&lt;br /&gt;
//refreshImage(&amp;quot;CptPFD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Building ==&lt;br /&gt;
&lt;br /&gt;
* Download and extract the latest attached tar archive (https://sourceforge.net/projects/remote-canvas-for-flightgear). It contains the patches listed above,&lt;br /&gt;
* Copy the simgear and flightgear subfolders over your existing source tree.&lt;br /&gt;
* Run the platform specific make for building FG.&lt;br /&gt;
* Copy the resulting fgfs executable to your FlightGears installation bin directory '''after''' saving the existing.&lt;br /&gt;
&lt;br /&gt;
== Optimizations ==&lt;br /&gt;
* Sample rate ~1-3 hz&lt;br /&gt;
* JPEG_QUALITY &amp;lt;= 6&lt;br /&gt;
* image size ~ 512x512&lt;br /&gt;
* RTSP/ffmpeg streaming&lt;br /&gt;
* Turn the whole thing into a configurable placement for capturing/streaming purposes&lt;br /&gt;
* [[Howto:Serializing a Canvas to SVG]] (streaming a Canvas/MFD as a SVG/XML document)&lt;br /&gt;
&lt;br /&gt;
== Using ==&lt;br /&gt;
Add the line&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;canvasimage&amp;gt;/canvasimage&amp;lt;/canvasimage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
to the uri handler defined in file FG_ROOT/httpd-settings.xml &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;uri-handler&amp;gt;&lt;br /&gt;
                &amp;lt;screenshot&amp;gt;/screenshot&amp;lt;/screenshot&amp;gt;&lt;br /&gt;
                &amp;lt;property&amp;gt;/props/&amp;lt;/property&amp;gt;&lt;br /&gt;
                &amp;lt;json&amp;gt;/json/&amp;lt;/json&amp;gt;&lt;br /&gt;
                &amp;lt;pkg&amp;gt;/pkg/&amp;lt;/pkg&amp;gt;&lt;br /&gt;
                &amp;lt;flighthistory&amp;gt;/flighthistory/&amp;lt;/flighthistory&amp;gt;&lt;br /&gt;
                &amp;lt;run&amp;gt;/run.cgi&amp;lt;/run&amp;gt;&lt;br /&gt;
                &amp;lt;navdb&amp;gt;/navdb&amp;lt;/navdb&amp;gt;&lt;br /&gt;
                &amp;lt;canvasimage&amp;gt;/canvasimage&amp;lt;/canvasimage&amp;gt;&lt;br /&gt;
        &amp;lt;/uri-handler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and start fgfs with option &amp;quot;--httpd=5701&amp;quot; (the port number is free, but 5701 is used by the showcase HTML script). Enter the URL&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
localhost:5701/canvasimage?type=png&amp;amp;canvasindex=0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in your browser. The first request will add the property rendertoimage to the canvas with index 0 but return no image (this is no intended behaviour but the result of insufficient synchronization between the rendering thread and the HTTP thread). The request needs to be send again and the image of canvas 0 is returned. Its up to the user to specify a valid canvas index. An invalid canvas index or any form of invalid URL will not result in an error message but simply return no result (until it runs into some browser timeout).&lt;br /&gt;
&lt;br /&gt;
The showcase script CanvasView.html shows the main instruments of Soitanens 737 with a refresh rate of 2 per second. This will not be enough for a smooth display and might be increased by reducing the timeoutinterval down from 500ms. But keep an eye on the overall performance of your running fgfs instance. Providing the images causes a significant system load.&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
* https://sourceforge.net/projects/remote-canvas-for-flightgear&lt;br /&gt;
* {{Search|mode=forum|keywords=ffmpeg+stream}}&lt;br /&gt;
* {{OSG example|example=osgmovie}}&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/LoadingProgress&lt;br /&gt;
* http://trac.openscenegraph.org/projects/osg//wiki/Support/KnowledgeBase/SerializationSupport&lt;br /&gt;
* http://bensoftware.com/blog/comparison-of-streaming-formats/&lt;br /&gt;
* http://www.osgart.org/index.php/NodeCallback_Scene_Setup&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cockpit building]]&lt;br /&gt;
[[Category:Canvas]]&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=117150</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=117150"/>
		<updated>2019-01-21T06:13:51Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Outline */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
=== controlling objects ===&lt;br /&gt;
The AI subsystem just takes care of hooking the model animation properties into the &amp;quot;/ai/models&amp;quot; subtree. Main control is performed by a Nasal module by triggering model animations.&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
The existing solution in jetways.nas for controlling jetways will be retained. For not affecting readability and increaing the complexity of jetways.nas, the core jetway funtionality will be extracted into a separate module/addon that supports the new jetway definition.&lt;br /&gt;
&lt;br /&gt;
The existing jetway solution by ICAO.jetways.xml will not be affected.&lt;br /&gt;
&lt;br /&gt;
== Status as of January 2019 ==&lt;br /&gt;
Due to the overall complexity and the number of involved components a few sub projects are isolated. These sub projects are intended to be just generic multi purpose extensions to FlightGear, which might later be combined for achieving the &amp;quot;big jetway solution&amp;quot;. The sub projects are:&lt;br /&gt;
&lt;br /&gt;
1)  {{Progressbar|100}} {{done}} An additional FG-Command interface to the AI subsystem (AIManager aso.). This provides a way to let the AI subsystem create a new object by just executing a FG-Command. The object built uses a PagedLOD and respects two level of degree, if a low res model file is provided. By using FG-Command this interface will be available from several components like Nasal, ReaderWriterSTG, Websockets, telnet, aso. If the model loaded contains animations, the animation properties will be located below the node in /ai/models/. AIManager will tranform these objects like other AI objects, ie. adjust its position/orientation from the corresponding properties. Removing an object will also be triggered by an FG-Command.&lt;br /&gt;
&lt;br /&gt;
This can be tested from Nasal console with&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
var position = geo.aircraft_position();&lt;br /&gt;
    var course = getprop(&amp;quot;/orientation/heading-deg&amp;quot;);&lt;br /&gt;
    position.apply_course_distance(course,300);&lt;br /&gt;
    var info = geodinfo(position.lat(), position.lon());    &lt;br /&gt;
    var alt = num(info[0]);&lt;br /&gt;
      &lt;br /&gt;
    var node = props.globals.getNode(&amp;quot;/ai/models&amp;quot;,0).addChild(&amp;quot;simpleobject&amp;quot;,0,0);&lt;br /&gt;
    &lt;br /&gt;
    node.getNode(&amp;quot;path&amp;quot;, 1).setValue(&amp;quot;Models/Airport/Jetway/j_generic_s.xml&amp;quot;);        &lt;br /&gt;
    node.getNode(&amp;quot;path-lowres&amp;quot;, 1).setValue(&amp;quot;Models/Buildings/silo.ac&amp;quot;);        &lt;br /&gt;
    node.getNode(&amp;quot;position/latitude-deg&amp;quot;, 1).setDoubleValue(position.lat());&lt;br /&gt;
    node.getNode(&amp;quot;position/longitude-deg&amp;quot;, 1).setDoubleValue(position.lon());        &lt;br /&gt;
    node.getNode(&amp;quot;position/altitude-ft&amp;quot;, 1).setDoubleValue(alt*M2FT);&lt;br /&gt;
    node.addChild(&amp;quot;load&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The original idea of using a property tree based interface inspired by ModelMgr has been dismissed.&lt;br /&gt;
&lt;br /&gt;
2) {{pending}} A property tree based interface to the AI subsystem (AIManager) that lets drive AIManager animation properties in its update() routine depending on the tpf value. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. This feature is especially useful for avoiding update loops in Nasal.&lt;br /&gt;
&lt;br /&gt;
3) {{pending}} A new keyword OBJECT_AI (or similar) for STG files to let ReaderSTG use the above feature no 1) for placing objects.&lt;br /&gt;
&lt;br /&gt;
4) {{pending}} An extended interface to the scenery database.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=117148</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=117148"/>
		<updated>2019-01-21T06:09:04Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Status as of January 2019 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
=== controlling objects ===&lt;br /&gt;
The AI subsystem just takes care of hooking the model animation properties into the &amp;quot;/ai/models&amp;quot; subtree. Main control is performed by a Nasal module by triggering model animations.&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
The existing solution in jetways.nas for controlling jetways will be retained. But for not affecting readability and increaing the complexity of jetways.nas it will be extracted into a separate module.&lt;br /&gt;
&lt;br /&gt;
The existing jetway solution by ICAO.jetways.xml will not be affected.&lt;br /&gt;
&lt;br /&gt;
== Status as of January 2019 ==&lt;br /&gt;
Due to the overall complexity and the number of involved components a few sub projects are isolated. These sub projects are intended to be just generic multi purpose extensions to FlightGear, which might later be combined for achieving the &amp;quot;big jetway solution&amp;quot;. The sub projects are:&lt;br /&gt;
&lt;br /&gt;
1)  {{Progressbar|100}} {{done}} An additional FG-Command interface to the AI subsystem (AIManager aso.). This provides a way to let the AI subsystem create a new object by just executing a FG-Command. The object built uses a PagedLOD and respects two level of degree, if a low res model file is provided. By using FG-Command this interface will be available from several components like Nasal, ReaderWriterSTG, Websockets, telnet, aso. If the model loaded contains animations, the animation properties will be located below the node in /ai/models/. AIManager will tranform these objects like other AI objects, ie. adjust its position/orientation from the corresponding properties. Removing an object will also be triggered by an FG-Command.&lt;br /&gt;
&lt;br /&gt;
This can be tested from Nasal console with&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
var position = geo.aircraft_position();&lt;br /&gt;
    var course = getprop(&amp;quot;/orientation/heading-deg&amp;quot;);&lt;br /&gt;
    position.apply_course_distance(course,300);&lt;br /&gt;
    var info = geodinfo(position.lat(), position.lon());    &lt;br /&gt;
    var alt = num(info[0]);&lt;br /&gt;
      &lt;br /&gt;
    var node = props.globals.getNode(&amp;quot;/ai/models&amp;quot;,0).addChild(&amp;quot;simpleobject&amp;quot;,0,0);&lt;br /&gt;
    &lt;br /&gt;
    node.getNode(&amp;quot;path&amp;quot;, 1).setValue(&amp;quot;Models/Airport/Jetway/j_generic_s.xml&amp;quot;);        &lt;br /&gt;
    node.getNode(&amp;quot;path-lowres&amp;quot;, 1).setValue(&amp;quot;Models/Buildings/silo.ac&amp;quot;);        &lt;br /&gt;
    node.getNode(&amp;quot;position/latitude-deg&amp;quot;, 1).setDoubleValue(position.lat());&lt;br /&gt;
    node.getNode(&amp;quot;position/longitude-deg&amp;quot;, 1).setDoubleValue(position.lon());        &lt;br /&gt;
    node.getNode(&amp;quot;position/altitude-ft&amp;quot;, 1).setDoubleValue(alt*M2FT);&lt;br /&gt;
    node.addChild(&amp;quot;load&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The original idea of using a property tree based interface inspired by ModelMgr has been dismissed.&lt;br /&gt;
&lt;br /&gt;
2) {{pending}} A property tree based interface to the AI subsystem (AIManager) that lets drive AIManager animation properties in its update() routine depending on the tpf value. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. This feature is especially useful for avoiding update loops in Nasal.&lt;br /&gt;
&lt;br /&gt;
3) {{pending}} A new keyword OBJECT_AI (or similar) for STG files to let ReaderSTG use the above feature no 1) for placing objects.&lt;br /&gt;
&lt;br /&gt;
4) {{pending}} An extended interface to the scenery database.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=117147</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=117147"/>
		<updated>2019-01-21T05:58:12Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Status as of January 2019 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
=== controlling objects ===&lt;br /&gt;
The AI subsystem just takes care of hooking the model animation properties into the &amp;quot;/ai/models&amp;quot; subtree. Main control is performed by a Nasal module by triggering model animations.&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
The existing solution in jetways.nas for controlling jetways will be retained. But for not affecting readability and increaing the complexity of jetways.nas it will be extracted into a separate module.&lt;br /&gt;
&lt;br /&gt;
The existing jetway solution by ICAO.jetways.xml will not be affected.&lt;br /&gt;
&lt;br /&gt;
== Status as of January 2019 ==&lt;br /&gt;
Due to the overall complexity and the number of involved components a few sub projects are isolated. These sub projects are intended to be just generic multi purpose extensions to FlightGear, which might later be combined for achieving the &amp;quot;big jetway solution&amp;quot;. The sub projects are:&lt;br /&gt;
&lt;br /&gt;
1) An additional FG-Command interface to the AI subsystem (AIManager aso.). This provides a way to let the AI subsystem create a new object by just executing a FG-Command. The object built uses a PagedLOD and respects two level of degree, if a low res model file is provided. By using FG-Command this interface will be available from several components like Nasal, ReaderWriterSTG, Websockets, telnet, aso. If the model loaded contains animations, the animation properties will be located below the node in /ai/models/. AIManager will tranform these objects like other AI objects, ie. adjust its position/orientation from the corresponding properties. Removing an object will also be triggered by an FG-Command.&lt;br /&gt;
&lt;br /&gt;
This can be tested from Nasal console with&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
var position = geo.aircraft_position();&lt;br /&gt;
    var course = getprop(&amp;quot;/orientation/heading-deg&amp;quot;);&lt;br /&gt;
    position.apply_course_distance(course,300);&lt;br /&gt;
    var info = geodinfo(position.lat(), position.lon());    &lt;br /&gt;
    var alt = num(info[0]);&lt;br /&gt;
      &lt;br /&gt;
    var node = props.globals.getNode(&amp;quot;/ai/models&amp;quot;,0).addChild(&amp;quot;simpleobject&amp;quot;,0,0);&lt;br /&gt;
    &lt;br /&gt;
    node.getNode(&amp;quot;path&amp;quot;, 1).setValue(&amp;quot;Models/Airport/Jetway/j_generic_s.xml&amp;quot;);        &lt;br /&gt;
    node.getNode(&amp;quot;path-lowres&amp;quot;, 1).setValue(&amp;quot;Models/Buildings/silo.ac&amp;quot;);        &lt;br /&gt;
    node.getNode(&amp;quot;position/latitude-deg&amp;quot;, 1).setDoubleValue(position.lat());&lt;br /&gt;
    node.getNode(&amp;quot;position/longitude-deg&amp;quot;, 1).setDoubleValue(position.lon());        &lt;br /&gt;
    node.getNode(&amp;quot;position/altitude-ft&amp;quot;, 1).setDoubleValue(alt*M2FT);&lt;br /&gt;
    node.addChild(&amp;quot;load&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The original idea of using a property tree based interface inspired by ModelMgr has been dismissed.&lt;br /&gt;
&lt;br /&gt;
2) A property tree based interface to the AI subsystem (AIManager) that lets drive AIManager animation properties in its update() routine depending on the tpf value. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. This feature is especially useful for avoiding update loops in Nasal.&lt;br /&gt;
&lt;br /&gt;
3) A new keyword OBJECT_AI (or similar) for STG files to let ReaderSTG use the above feature no 1) for placing objects.&lt;br /&gt;
&lt;br /&gt;
4) An extended interface to the scenery database.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Talk:AI_Scenery_objects&amp;diff=116663</id>
		<title>Talk:AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Talk:AI_Scenery_objects&amp;diff=116663"/>
		<updated>2018-11-10T16:33:11Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:PropertyTree and Canvas.png]]&lt;br /&gt;
&lt;br /&gt;
Hi, Regarding [[AI_Scenery_Objects#Status_as_of_November_2018]], you will probably want to take a look at the SGPropertyChangeListener API, and specifically the PropertyBasedMgr abstration, which is the workhorse of the whole Canvas system. While these APIs were originally used/inspired by the way the AI system works, they have  surpassed those capabilities long ago.&lt;br /&gt;
&lt;br /&gt;
* [[Howto:Create new subsystems]]&lt;br /&gt;
* [[Howto:Use Property Tree Objects]]&lt;br /&gt;
* [[Howto:Add new fgcommands to FlightGear]]&lt;br /&gt;
* [[Canvas Development#Internals]]&lt;br /&gt;
&lt;br /&gt;
HTH&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:54, 9 November 2018 (EST)&lt;br /&gt;
&lt;br /&gt;
I just launched a merge request with my solution, that uses a PropertyListener. I hope it meets your proposal.&lt;br /&gt;
&lt;br /&gt;
[[User:ThomasS|ThomasS]] ([[User talk:ThomasS|talk]]) 11:32, 10 November 2018 (EST)&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Talk:AI_Scenery_objects&amp;diff=116662</id>
		<title>Talk:AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Talk:AI_Scenery_objects&amp;diff=116662"/>
		<updated>2018-11-10T16:32:48Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:PropertyTree and Canvas.png]]&lt;br /&gt;
&lt;br /&gt;
Hi, Regarding [[AI_Scenery_Objects#Status_as_of_November_2018]], you will probably want to take a look at the SGPropertyChangeListener API, and specifically the PropertyBasedMgr abstration, which is the workhorse of the whole Canvas system. While these APIs were originally used/inspired by the way the AI system works, they have  surpassed those capabilities long ago.&lt;br /&gt;
&lt;br /&gt;
* [[Howto:Create new subsystems]]&lt;br /&gt;
* [[Howto:Use Property Tree Objects]]&lt;br /&gt;
* [[Howto:Add new fgcommands to FlightGear]]&lt;br /&gt;
* [[Canvas Development#Internals]]&lt;br /&gt;
&lt;br /&gt;
HTH&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:54, 9 November 2018 (EST)&lt;br /&gt;
&lt;br /&gt;
I just launched a merge request with my solution, that uses a PropertyListener. I hope it meets your proposal.&lt;br /&gt;
[[User:ThomasS|ThomasS]] ([[User talk:ThomasS|talk]]) 11:32, 10 November 2018 (EST)&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116660</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116660"/>
		<updated>2018-11-10T15:16:01Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Status as of November 2018 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
=== controlling objects ===&lt;br /&gt;
The AI subsystem just takes care of hooking the model animation properties into the &amp;quot;/ai/models&amp;quot; subtree. Main control is performed by a Nasal module by triggering model animations.&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
The existing solution in jetways.nas for controlling jetways will be retained. But for not affecting readability and increaing the complexity of jetways.nas it will be extracted into a separate module.&lt;br /&gt;
&lt;br /&gt;
The existing jetway solution by ICAO.jetways.xml will not be affected.&lt;br /&gt;
&lt;br /&gt;
== Status as of November 2018 ==&lt;br /&gt;
Due to the overall complexity and the number of involved components a few sub projects are isolated. These sub projects are intended to be just generic multi purpose extensions to FlightGear, which might later be combined for achieving the &amp;quot;big jetway solution&amp;quot;. The sub projects are:&lt;br /&gt;
&lt;br /&gt;
1) A property tree based interface to the AI subsystem (AIManager aso.) inspired by ModelMgr. This provides a way to let the AI subsystem create a new object by just populating a new node in /ai/models and trigger AIManager by adding a property &amp;quot;load&amp;quot;. The object built uses a PagedLOD and respects two level of degree, if a low res model file is provided. By using the property tree this interface will be available from several components like Nasal, ReaderWriterSTG, Websockets, telnet, aso. If the model loaded contains animations, the animation properties will be located below the node in /ai/models/. AIManager will tranform these objects like other AI objects, ie. adjust its position/orientation from the corresponding properties. Removing an object will be triggered by adding a &amp;quot;unload&amp;quot; property. This can be tested from Nasal console with&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
var position = geo.aircraft_position();&lt;br /&gt;
    var course = getprop(&amp;quot;/orientation/heading-deg&amp;quot;);&lt;br /&gt;
    position.apply_course_distance(course,300);&lt;br /&gt;
    var info = geodinfo(position.lat(), position.lon());    &lt;br /&gt;
    var alt = num(info[0]);&lt;br /&gt;
      &lt;br /&gt;
    var node = props.globals.getNode(&amp;quot;/ai/models&amp;quot;,0).addChild(&amp;quot;simpleobject&amp;quot;,0,0);&lt;br /&gt;
    &lt;br /&gt;
    node.getNode(&amp;quot;path&amp;quot;, 1).setValue(&amp;quot;Models/Airport/Jetway/j_generic_s.xml&amp;quot;);        &lt;br /&gt;
    node.getNode(&amp;quot;path-lowres&amp;quot;, 1).setValue(&amp;quot;Models/Buildings/silo.ac&amp;quot;);        &lt;br /&gt;
    node.getNode(&amp;quot;position/latitude-deg&amp;quot;, 1).setDoubleValue(position.lat());&lt;br /&gt;
    node.getNode(&amp;quot;position/longitude-deg&amp;quot;, 1).setDoubleValue(position.lon());        &lt;br /&gt;
    node.getNode(&amp;quot;position/altitude-ft&amp;quot;, 1).setDoubleValue(alt*M2FT);&lt;br /&gt;
    node.addChild(&amp;quot;load&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) A property tree based interface to the AI subsystem (AIManager) that lets drive AIManager animation properties in its update() routine depending on the tpf value. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. This feature is especially useful for avoiding update loops in Nasal.&lt;br /&gt;
&lt;br /&gt;
3) A new keyword OBJECT_AI (or similar) for STG files to let ReaderSTG use the above feature no 1) for placing objects.&lt;br /&gt;
&lt;br /&gt;
4) An extended interface to the scenery database.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116659</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116659"/>
		<updated>2018-11-10T14:51:11Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Status as of November 2018 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
=== controlling objects ===&lt;br /&gt;
The AI subsystem just takes care of hooking the model animation properties into the &amp;quot;/ai/models&amp;quot; subtree. Main control is performed by a Nasal module by triggering model animations.&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
The existing solution in jetways.nas for controlling jetways will be retained. But for not affecting readability and increaing the complexity of jetways.nas it will be extracted into a separate module.&lt;br /&gt;
&lt;br /&gt;
The existing jetway solution by ICAO.jetways.xml will not be affected.&lt;br /&gt;
&lt;br /&gt;
== Status as of November 2018 ==&lt;br /&gt;
Due to the overall complexity and the number of involved components a few sub projects are isolated. These sub projects are intended to be just generic multi purpose extensions to FlightGear, which might later be combined for achieving the &amp;quot;big jetway solution&amp;quot;. The sub projects are:&lt;br /&gt;
&lt;br /&gt;
1) A property tree based interface to the AI subsystem (AIManager aso.) inspired by ModelMgr. This provides a way to let the AI subsystem create a new object by just populating a new node in /ai/models and trigger AIManager by adding a property &amp;quot;load&amp;quot;. The object built uses a PagedLOD and respects two level of degree, if a low res model file is provided. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. If the model loaded contains animations, the animation properties will be located below the node in /ai/models/. AIManager will tranform these objects like other AI objects, ie. adjust its position/orientation from the corresponding properties. Removing an object will be triggered by adding a &amp;quot;unload&amp;quot; property. This can be tested from Nasal console with&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
var position = geo.aircraft_position();&lt;br /&gt;
    var course = getprop(&amp;quot;/orientation/heading-deg&amp;quot;);&lt;br /&gt;
    position.apply_course_distance(course,300);&lt;br /&gt;
    var info = geodinfo(position.lat(), position.lon());    &lt;br /&gt;
    var alt = num(info[0]);&lt;br /&gt;
      &lt;br /&gt;
    var node = props.globals.getNode(&amp;quot;/ai/models&amp;quot;,0).addChild(&amp;quot;simpleobject&amp;quot;,0,0);&lt;br /&gt;
    &lt;br /&gt;
    node.getNode(&amp;quot;path&amp;quot;, 1).setValue(&amp;quot;Models/Airport/Jetway/j_generic_s.xml&amp;quot;);        &lt;br /&gt;
    node.getNode(&amp;quot;path-lowres&amp;quot;, 1).setValue(&amp;quot;Models/Buildings/silo.ac&amp;quot;);        &lt;br /&gt;
    node.getNode(&amp;quot;position/latitude-deg&amp;quot;, 1).setDoubleValue(position.lat());&lt;br /&gt;
    node.getNode(&amp;quot;position/longitude-deg&amp;quot;, 1).setDoubleValue(position.lon());        &lt;br /&gt;
    node.getNode(&amp;quot;position/altitude-ft&amp;quot;, 1).setDoubleValue(alt*M2FT);&lt;br /&gt;
    node.addChild(&amp;quot;load&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) A property tree based interface to the AI subsystem (AIManager) that lets drive AIManager animation properties in its update() routine depending on the tpf value. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. This feature is especially useful for avoiding update loops in Nasal.&lt;br /&gt;
&lt;br /&gt;
3) A new keyword OBJECT_AI (or similar) for STG files to let ReaderSTG use the above feature no 1) for placing objects.&lt;br /&gt;
&lt;br /&gt;
4) An extended interface to the scenery database.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116658</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116658"/>
		<updated>2018-11-10T14:46:03Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Status as of November 2018 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
=== controlling objects ===&lt;br /&gt;
The AI subsystem just takes care of hooking the model animation properties into the &amp;quot;/ai/models&amp;quot; subtree. Main control is performed by a Nasal module by triggering model animations.&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
The existing solution in jetways.nas for controlling jetways will be retained. But for not affecting readability and increaing the complexity of jetways.nas it will be extracted into a separate module.&lt;br /&gt;
&lt;br /&gt;
The existing jetway solution by ICAO.jetways.xml will not be affected.&lt;br /&gt;
&lt;br /&gt;
== Status as of November 2018 ==&lt;br /&gt;
Due to the overall complexity and the number of involved components a few sub projects are isolated. These sub projects are intended to be just generic multi purpose extensions to FlightGear, which might later be combined for achieving the &amp;quot;big jetway solution&amp;quot;. The sub projects are:&lt;br /&gt;
&lt;br /&gt;
1) A property tree based interface to the AI subsystem (AIManager aso.) inspired by ModelMgr. This provides a way to let the AI subsystem create a new object by just populating a new node in /ai/models and trigger AIManager by adding a property &amp;quot;load&amp;quot;. The object built uses a PagedLOD and respects two level of degree, if a low res model file is provided. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. If the model loaded contains animations, the animation properties will be located below the node in /ai/models/. AIManager will tranform these objects like other AI objects, ie. adjust its position/orientation from the corresponding properties. Removing an object will be triggered by adding a &amp;quot;unload&amp;quot; property. This can be tested from Nasal console with&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
var position = geo.aircraft_position();&lt;br /&gt;
    var course = getprop(&amp;quot;/orientation/heading-deg&amp;quot;);&lt;br /&gt;
    position.apply_course_distance(course,300);&lt;br /&gt;
    var info = geodinfo(position.lat(), position.lon());    &lt;br /&gt;
    var alt = num(info[0]);&lt;br /&gt;
      &lt;br /&gt;
    var node = props.globals.getNode(&amp;quot;/ai/models&amp;quot;,0).addChild(&amp;quot;simpleobject&amp;quot;,0,0);&lt;br /&gt;
    &lt;br /&gt;
    node.getNode(&amp;quot;path&amp;quot;, 1).setValue(&amp;quot;Models/Airport/Jetway/j_generic_s.xml&amp;quot;);        &lt;br /&gt;
    node.getNode(&amp;quot;path-lowres&amp;quot;, 1).setValue(&amp;quot;Models/Buildings/silo.ac&amp;quot;);        &lt;br /&gt;
    node.getNode(&amp;quot;position/latitude-deg&amp;quot;, 1).setDoubleValue(position.lat());&lt;br /&gt;
    node.getNode(&amp;quot;position/longitude-deg&amp;quot;, 1).setDoubleValue(position.lon());        &lt;br /&gt;
    node.getNode(&amp;quot;position/altitude-ft&amp;quot;, 1).setDoubleValue(alt*M2FT);&lt;br /&gt;
    node.addChild(&amp;quot;load&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) A property tree based interface to the AI subsystem (AIManager) that lets drive AIManager animation properties in its update() routine depending on the tpf value. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. This feature is especially useful for avoiding update loops in Nasal.&lt;br /&gt;
3) A new keyword OBJECT_AI (or similar) for STG files to let ReaderSTG use the above feature no 1) for placing objects.&lt;br /&gt;
4) An extended interface to the scenery database.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116657</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116657"/>
		<updated>2018-11-10T14:43:32Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Status as of November 2018 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
=== controlling objects ===&lt;br /&gt;
The AI subsystem just takes care of hooking the model animation properties into the &amp;quot;/ai/models&amp;quot; subtree. Main control is performed by a Nasal module by triggering model animations.&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
The existing solution in jetways.nas for controlling jetways will be retained. But for not affecting readability and increaing the complexity of jetways.nas it will be extracted into a separate module.&lt;br /&gt;
&lt;br /&gt;
The existing jetway solution by ICAO.jetways.xml will not be affected.&lt;br /&gt;
&lt;br /&gt;
== Status as of November 2018 ==&lt;br /&gt;
Due to the overall complexity and the number of involved components a few sub projects are isolated. These sub projects are intended to be just generic multi purpose extensions to FlightGear, which might later be combined for achieving the &amp;quot;big jetway solution&amp;quot;. The sub projects are:&lt;br /&gt;
&lt;br /&gt;
*1) A property tree based interface to the AI subsystem (AIManager aso.) inspired by ModelMgr. This provides a way to let the AI subsystem create a new object by just populating a new node in /ai/models and trigger AIManager by adding a property &amp;quot;load&amp;quot;. The object built uses a PagedLOD and respects two level of degree, if a low res model file is provided. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. If the model loaded contains animations, the animation properties will be located below the node in /ai/models/. AIManager will tranform these objects like other AI objects, ie. adjust its position/orientation from the corresponding properties. Removing an object will be triggered by adding a &amp;quot;unload&amp;quot; property.&lt;br /&gt;
*2) A property tree based interface to the AI subsystem (AIManager) that lets drive AIManager animation properties in its update() routine depending on the tpf value. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. This feature is especially useful for avoiding update loops in Nasal.&lt;br /&gt;
*3) A new keyword OBJECT_AI (or similar) for STG files to let ReaderSTG use the above feature no 1) for placing objects.&lt;br /&gt;
*4) An extended interface to the scenery database.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116652</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116652"/>
		<updated>2018-11-09T06:12:34Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Status as of November 2018 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
=== controlling objects ===&lt;br /&gt;
The AI subsystem just takes care of hooking the model animation properties into the &amp;quot;/ai/models&amp;quot; subtree. Main control is performed by a Nasal module by triggering model animations.&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
The existing solution in jetways.nas for controlling jetways will be retained. But for not affecting readability and increaing the complexity of jetways.nas it will be extracted into a separate module.&lt;br /&gt;
&lt;br /&gt;
The existing jetway solution by ICAO.jetways.xml will not be affected.&lt;br /&gt;
&lt;br /&gt;
== Status as of November 2018 ==&lt;br /&gt;
Due to the overall complexity and the number of involved components a few sub projects are isolated. These sub projects are intended to be just generic multi purpose extensions to FlightGear, which might later be combined for achieving the &amp;quot;big jetway solution&amp;quot;. The sub projects are:&lt;br /&gt;
&lt;br /&gt;
#A property tree based interface to the AI subsystem (AIManager aso.) inspired by ModelMgr. This provides a way to let the AI subsystem create a new object by just populating a new node in /ai/models and trigger AIManager by adding a property &amp;quot;load&amp;quot;. The object built uses a PagedLOD and respects two level of degree, if a low res model file is provided. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. If the model loaded contains animations, the animation properties will be located below the node in /ai/models/. AIManager will tranform these objects like other AI objects, ie. adjust its position/orientation from the corresponding properties. Removing an object will be triggered by adding a &amp;quot;unload&amp;quot; property.&lt;br /&gt;
#A property tree based interface to the AI subsystem (AIManager) that lets drive AIManager animation properties in its update() routine depending on the tpf value. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. This feature is especially useful for avoiding update loops in Nasal.&lt;br /&gt;
#A new keyword OBJECT_AI (or similar) for STG files to let ReaderSTG use the above feature no 1) for placing objects.&lt;br /&gt;
#An extended interface to the scenery database.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116651</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116651"/>
		<updated>2018-11-09T06:11:37Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Status as of November 2018 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
=== controlling objects ===&lt;br /&gt;
The AI subsystem just takes care of hooking the model animation properties into the &amp;quot;/ai/models&amp;quot; subtree. Main control is performed by a Nasal module by triggering model animations.&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
The existing solution in jetways.nas for controlling jetways will be retained. But for not affecting readability and increaing the complexity of jetways.nas it will be extracted into a separate module.&lt;br /&gt;
&lt;br /&gt;
The existing jetway solution by ICAO.jetways.xml will not be affected.&lt;br /&gt;
&lt;br /&gt;
== Status as of November 2018 ==&lt;br /&gt;
Due to the overall complexity and the number of involved components a few sub projects are isolated. These sub projects are intended to be just generic multi purpose extensions to FlightGear, which might later be combined for achieving the &amp;quot;big jetway solution&amp;quot;. The sub projects are:&lt;br /&gt;
&lt;br /&gt;
#A property tree based interface to the AI subsystem (AIManager aso.) inspired by ModelMgr. This provides a way to let the AI subsystem create a new object by just populating a new node in /ai/models and trigger AIManager by adding a property &amp;quot;load&amp;quot;. The object built uses a PagedLOD and respects two level of degree, if a low res model file is provided. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. If the model loaded contains animations, the animation properties will be located below the node in /ai/models/. AIManager will tranform these objects like other AI objects, ie. adjust its position/orientation from&lt;br /&gt;
// the corresponding properties. Removing an object will be triggered by adding a &amp;quot;unload&amp;quot; property.&lt;br /&gt;
#A property tree based interface to the AI subsystem (AIManager) that lets drive AIManager animation properties in its update() routine depending on the tpf value. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. This feature is especially useful for avoiding update loops in Nasal.&lt;br /&gt;
#A new keyword OBJECT_AI (or similar) for STG files to let ReaderSTG use the above feature no 1) for placing objects.&lt;br /&gt;
#An extended interface to the scenery database.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116647</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116647"/>
		<updated>2018-11-08T07:46:24Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Status as of November 2018 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
=== controlling objects ===&lt;br /&gt;
The AI subsystem just takes care of hooking the model animation properties into the &amp;quot;/ai/models&amp;quot; subtree. Main control is performed by a Nasal module by triggering model animations.&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
The existing solution in jetways.nas for controlling jetways will be retained. But for not affecting readability and increaing the complexity of jetways.nas it will be extracted into a separate module.&lt;br /&gt;
&lt;br /&gt;
The existing jetway solution by ICAO.jetways.xml will not be affected.&lt;br /&gt;
&lt;br /&gt;
== Status as of November 2018 ==&lt;br /&gt;
Due to the overall complexity and the number of involved components a few sub projects are isolated. These sub projects are intended to be just generic multi purpose extensions to FlightGear, which might later be combined for achieving the &amp;quot;big jetway solution&amp;quot;. The sub projects are:&lt;br /&gt;
&lt;br /&gt;
#A property tree based interface to the AI subsystem (AIManager aso.) inspired by ModelMgr. This provides a way to let the AI subsystem create a new object by just populating a new node in /ai/models and trigger AIManager by adding a property &amp;quot;load&amp;quot;. The object built uses a PagedLOD and respects two level of degree, if a low res model file is provided. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. If the model loaded contains animations, the animation properties will be located below the node in /ai/models/. Removing an object will be triggered by adding a &amp;quot;unload&amp;quot; property.&lt;br /&gt;
#A property tree based interface to the AI subsystem (AIManager) that lets drive AIManager animation properties in its update() routine depending on the tpf value. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. This feature is especially useful for avoiding update loops in Nasal.&lt;br /&gt;
#A new keyword OBJECT_AI (or similar) for STG files to let ReaderSTG use the above feature no 1) for placing objects.&lt;br /&gt;
#An extended interface to the scenery database.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116646</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116646"/>
		<updated>2018-11-08T07:46:00Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Status as of November 2018 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
=== controlling objects ===&lt;br /&gt;
The AI subsystem just takes care of hooking the model animation properties into the &amp;quot;/ai/models&amp;quot; subtree. Main control is performed by a Nasal module by triggering model animations.&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
The existing solution in jetways.nas for controlling jetways will be retained. But for not affecting readability and increaing the complexity of jetways.nas it will be extracted into a separate module.&lt;br /&gt;
&lt;br /&gt;
The existing jetway solution by ICAO.jetways.xml will not be affected.&lt;br /&gt;
&lt;br /&gt;
== Status as of November 2018 ==&lt;br /&gt;
Due to the overall complexity and the number of involved components a few sub projects are isolated. These sub projects are intended to be just generic multi purpose extensions to FlightGear, which might later be combined for achieving the &amp;quot;big jetway solution&amp;quot;. The sub projects are:&lt;br /&gt;
&lt;br /&gt;
#A property tree based interface to the AI subsystem (AIManager aso.) inspired by ModelMgr. This provides a way to let the AI subsystem create a new object by just populating a new node in /ai/models and trigger AIManager by adding a property &amp;quot;load&amp;quot;. The object built uses a PagedLOD and respects two level of degree, if a low res model file is provided. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. If the model loaded contains animations, the animation properties will be located below the node in /ai/models/. Removing an object will be triggered by adding a &amp;quot;unload&amp;quot; property.&lt;br /&gt;
&lt;br /&gt;
#A property tree based interface to the AI subsystem (AIManager) that lets drive AIManager animation properties in its update() routine depending on the tpf value. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. This feature is especially useful for avoiding update loops in Nasal.&lt;br /&gt;
&lt;br /&gt;
#A new keyword OBJECT_AI (or similar) for STG files to let ReaderSTG use the above feature no 1) for placing objects.&lt;br /&gt;
&lt;br /&gt;
#An extended interface to the scenery database.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116645</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116645"/>
		<updated>2018-11-08T07:44:10Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Status as of November 2018 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
=== controlling objects ===&lt;br /&gt;
The AI subsystem just takes care of hooking the model animation properties into the &amp;quot;/ai/models&amp;quot; subtree. Main control is performed by a Nasal module by triggering model animations.&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
The existing solution in jetways.nas for controlling jetways will be retained. But for not affecting readability and increaing the complexity of jetways.nas it will be extracted into a separate module.&lt;br /&gt;
&lt;br /&gt;
The existing jetway solution by ICAO.jetways.xml will not be affected.&lt;br /&gt;
&lt;br /&gt;
== Status as of November 2018 ==&lt;br /&gt;
Due to the overall complexity and the number of involved components a few sub projects are isolated. These sub projects are intended to be just generic multi purpose extensions to FlightGear, which might later be combined for achieving the &amp;quot;big jetway solution&amp;quot;. The sub projects are:&lt;br /&gt;
&lt;br /&gt;
*A property tree based interface to the AI subsystem (AIManager aso.) inspired by ModelMgr. This provides a way to let the AI subsystem create a new object by just populating a new node in /ai/models and trigger AIManager by adding a property &amp;quot;load&amp;quot;. The object built uses a PagedLOD and respects two level of degree, if a low res model file is provided. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. If the model loaded contains animations, the animation properties will be located below the node in /ai/models/. Removing an object will be triggered by adding a &amp;quot;unload&amp;quot; property.&lt;br /&gt;
&lt;br /&gt;
*A property tree based interface to the AI subsystem (AIManager) that lets drive AIManager animation properties in its update() routine depending on the tpf value. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. This feature is especially useful for avoiding update loops in Nasal.&lt;br /&gt;
&lt;br /&gt;
*A new keyword OBJECT_AI (or similar) for STG files to let ReaderSTG use the above features for placing objects.&lt;br /&gt;
&lt;br /&gt;
*An extended interface to the scenery database.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116644</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116644"/>
		<updated>2018-11-08T07:15:53Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: Status November 2018&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
=== controlling objects ===&lt;br /&gt;
The AI subsystem just takes care of hooking the model animation properties into the &amp;quot;/ai/models&amp;quot; subtree. Main control is performed by a Nasal module by triggering model animations.&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
The existing solution in jetways.nas for controlling jetways will be retained. But for not affecting readability and increaing the complexity of jetways.nas it will be extracted into a separate module.&lt;br /&gt;
&lt;br /&gt;
The existing jetway solution by ICAO.jetways.xml will not be affected.&lt;br /&gt;
&lt;br /&gt;
== Status as of November 2018 ==&lt;br /&gt;
Due to the overall complexity and the number of involved components a few sub projects are isolated. These sub projects are intended to be just generic multi purpose extensions to FlightGear, which might later be combined for achieving the &amp;quot;big jetway solution&amp;quot;. The sub projects are:&lt;br /&gt;
&lt;br /&gt;
* A property tree based interface to the AI subsystem (AIManager aso.) inspired by ModelMgr. This provides a way to let the AI subsystem create a new object by just populating a new node in /ai/models and trigger AIManager by adding a property &amp;quot;load&amp;quot;. The object built uses a PagedLOD and respects two level of degree, if a low res model file is provided. By using the property tree this interface will be available from several components like Nasal, Websockets, telnet, aso. Removing an object will be triggered by adding a &amp;quot;unload&amp;quot; property.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:ThomasS&amp;diff=116643</id>
		<title>User:ThomasS</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:ThomasS&amp;diff=116643"/>
		<updated>2018-11-08T05:49:04Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: November 2018 Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{user&lt;br /&gt;
| name = Thomas S&lt;br /&gt;
| location = West of EDDK&lt;br /&gt;
| favorite aircraft = Boeing 737 NGX&lt;br /&gt;
| website =&lt;br /&gt;
| irc = &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
I'm '''Thomas S''' on the official forum and here on the wiki. &lt;br /&gt;
&lt;br /&gt;
== About me ==&lt;br /&gt;
I have been interested in flight simulation since mid 80ies when I first ran Flight Simulator II on my Apple II. However, I'm just an occasional flight simmer with only basic knowledge about flying an aircraft. &lt;br /&gt;
&lt;br /&gt;
== Me and FlightGear ==&lt;br /&gt;
Since my visit to FsWeekend in 2012 I use FlightGear in parallel to MSFS and X-Plane.&lt;br /&gt;
&lt;br /&gt;
== Primary Interests ==&lt;br /&gt;
* The software aspects. How does it all work together for visualizing/simulating an aircraft and its environment. &lt;br /&gt;
* Cockpit Building&lt;br /&gt;
* Scenery&lt;br /&gt;
&lt;br /&gt;
My current FlightGear projects are:&lt;br /&gt;
* An Addon for adding [[Ground Services]] to an airport.&lt;br /&gt;
* Remote display of canvases in a browser window ([[Read canvas image by HTTP]]).&lt;br /&gt;
* Migrating lasermans custom EDDK scenery into the official scenery ([[Flughafen_Köln/Bonn]]).&lt;br /&gt;
* A more generic way for maintaining animated jetways ([[AI Scenery Objects]])&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Talk:Ground_Services&amp;diff=116588</id>
		<title>Talk:Ground Services</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Talk:Ground_Services&amp;diff=116588"/>
		<updated>2018-10-31T06:32:52Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* 11/2018: Getting your MapStructure layers merged */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 11/2018: Getting your MapStructure layers merged ==&lt;br /&gt;
Hi, I think you should consider opening a merge request to have your MapStructure related layers added to fgdata. If in doubt, you can probably reach out to Stuart who's been working on the FG1000, and who would surely also appreciate having access to your work there. I believe, this should be a safe addition regardless of the feature freeze, because those layers are not being used anywhere else. However, once they're added, they will surely be used for other aircraft. Given Stuart's work on the FG1000 and a number of related MapStructure layers, I believe he would be in the best position to review/merge your work. I am going to send him a heads-up, so that he's aware of this.&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:04, 30 October 2018 (EDT)&lt;br /&gt;
&lt;br /&gt;
You mention a &amp;quot;feature freeze&amp;quot; which sounds like we are in a hurry. I'm afraid I'm not prepared for creating a merge request at the moment, because I'm not sure my layers are ready to be merged. They are in a RC status &lt;br /&gt;
just fitting for my purpose. The layers are available at https://github.com/thomass171/GroundServices. Maybe Stuart might just have a look and check for readiness.&lt;br /&gt;
[[User:ThomasS|ThomasS]] ([[User talk:ThomasS|talk]]) 02:31, 31 October 2018 (EDT)&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116352</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116352"/>
		<updated>2018-10-09T05:35:13Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Outline */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
=== controlling objects ===&lt;br /&gt;
The AI subsystem just takes care of hooking the model animation properties into the &amp;quot;/ai/models&amp;quot; subtree. Main control is performed by a Nasal module by triggering model animations.&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
The existing solution in jetways.nas for controlling jetways will be retained. But for not affecting readability and increaing the complexity of jetways.nas it will be extracted into a separate module.&lt;br /&gt;
&lt;br /&gt;
The existing jetway solution by ICAO.jetways.xml will not be affected.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116351</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116351"/>
		<updated>2018-10-09T05:16:07Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* object properties */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
=== controlling objects ===&lt;br /&gt;
The AI subsystem just takes care of hooking the model animation properties into the &amp;quot;/ai/models&amp;quot; subtree. Main control is performed by a Nasal module by triggering model animations.&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116350</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116350"/>
		<updated>2018-10-09T04:59:20Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: /* Requirements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
=== System Load (FPS) ===&lt;br /&gt;
Users not interested in animated objects (jetways) should not be affected. &lt;br /&gt;
&lt;br /&gt;
=== STG ===&lt;br /&gt;
A new STG token OBJECT_AI is added for defining an AI scenery object. There is no need for providing a shared option as these models are highly location specific. Such a line looks like&lt;br /&gt;
&lt;br /&gt;
OBJECT_AI &amp;lt;object-properties-path&amp;gt; &amp;lt;flags&amp;gt; &amp;lt;longitude&amp;gt; &amp;lt;latitude&amp;gt;...&lt;br /&gt;
&lt;br /&gt;
This complies to other object definitions except for the file referenced. This will not by a model file but just a property list file defining the AI object (see below).&lt;br /&gt;
&lt;br /&gt;
ReaderWriterSTG decides depending on a global switch &lt;br /&gt;
&amp;quot;ai-scenery-objects-enabled&amp;quot; to either:&lt;br /&gt;
* ignore these lines &lt;br /&gt;
* load a static scenery object if available (supplied and defined by the scenery designer), otherwise the animated model is used. This provides the option to the scenery designer to define a less complex model for reducing frame rate drawbacks. &lt;br /&gt;
* create a PagedLOD node to display a static object (jetway) until the range reaches a defined threhold (might be 100m for jetways), and then loads an animated object (jetway). Pass the model information to AIManager for creating an instance of  FGAISceneryObject and load the object-properties-path into the AI/models subtree. The object-properties-path will be the file containing jetway location specific data. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;flags&amp;quot; will just be a placeholder for future use for hopefully avoiding &lt;br /&gt;
a change to the file specification for upcoming requirements. The exact &lt;br /&gt;
implementation ReaderWriterSTG works however might change. &lt;br /&gt;
&lt;br /&gt;
=== object properties ===&lt;br /&gt;
The object properties file is a regular PropertyList file defining the characteristics of the scenery objects like&lt;br /&gt;
* the animated model file&lt;br /&gt;
* optionally a more simple static model file&lt;br /&gt;
&lt;br /&gt;
== Outline ==&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116337</id>
		<title>AI Scenery objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=AI_Scenery_objects&amp;diff=116337"/>
		<updated>2018-10-08T09:09:42Z</updated>

		<summary type="html">&lt;p&gt;ThomasS: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Non-stable}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|name = AI Scenery Objects&lt;br /&gt;
|started= 07/2018&lt;br /&gt;
|description = Providing a way for controlling scenery objects from the scenery objects database by the AI subsystem &lt;br /&gt;
|status = Under active development as of 07/2018&lt;br /&gt;
|developers =  ThomasS (since 07/2018) &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
|topic-fg= &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
{{See also|Howto:Animated jetways}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The currently preferred way for defining animated jetways for an airport is putting the definitions into a ICAO.jetways.xml file and let someone with commit access upload the file to the scenery server for sharing it by TerraSync. But using a single file per airport has a few drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Its difficult to maintain and to evolve the jetways step by step without always modifying the complete file&lt;br /&gt;
* It bypasses parts of the well established process for adding objects to the scenery and always requires some manual intervention by a core developer for committing it.&lt;br /&gt;
* Temporary runtime model files are created on demand for each airport.&lt;br /&gt;
&lt;br /&gt;
After some discussion on the developer mailing list  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/CAMcJc7oP_AuXaNDQOF1pTYtSM4pskCDWg1gXpxkKtXaF4LVfLg%40mail.gmail.com/#msg36378569&lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Mailing list discussion &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  July, 2018 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; the original idea scetched above broadened to a more generic solution, that not only disposes icao.jetways.xml, so the name &amp;quot;AI Scenery Object&amp;quot; arose. So an animated jetway is just one type of an AI Scenery Object. Cranes or bridges might be other types.&lt;br /&gt;
&lt;br /&gt;
This page is about a proof of concept for an alternative way for maintaining animated jetways by uploading animated jetways as AI scenery Object to the scenery object database similar to other scenery objects and have these controlled by the AI subsystem and a Nasal module  &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=34461&amp;amp;sid=4be4c415b0b814080102d632310b3297#p334260 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Animated Jetways: Type 1 or 2? &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; ThomasS &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jul 20th, 2018 &lt;br /&gt;
  |added  =  Jul 20th, 2018&lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
== Outline ==&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>ThomasS</name></author>
	</entry>
</feed>