Board index FlightGear Development

Announcing Comete Gauges for FlightGear

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

Bugs can be reported in the bug tracker.

Announcing Comete Gauges for FlightGear

Postby alni » Thu Jun 16, 2011 7:46 am

As I have posted in the thread for Alni FlightGear Control, I have started a project named Comete Project.

Comete Project is open source licensed under the GPLv3 license. Project home can be found at http://code.google.com/p/comete/

Up until now the only sub-project was Comete for FlightGear. But now a new sub-project is nearly ready for the source to be public. This sub-project is called Comete Gauges for FlightGear (CG FGFS). CG FGFS displays gauges in a instrument like panel. The textures of the gauges in taken from the FlightGear FS project.

Here follows a screenshot:
Image

All the gauges is fully functional. You may notice that the bottom row is missing the side-slip gauge, this is due to that the side-slip gauges requires more work and fine-tuning than the others.

CG FGFS is meant to be running from an android device with a large screen, preferable ~7" or greater. (It runs great on a Galaxy Tab :) )

By the end of this week I will upload the source code for CG FGFS, and also publish a test version to the Android Market.
alni
 
Posts: 10
Joined: Sat Jan 15, 2011 9:53 am
Version: v2
OS: Arch Linux

Re: Announcing Comete Gauges for FlightGear

Postby Hooray » Sat Jul 02, 2011 2:05 pm

Such announcements/news should ideally be posted to the FlightGear newsletter: http://wiki.flightgear.org/FlightGear_Newsletter

To make additions to the upcoming newsletter, please see: http://wiki.flightgear.org/Next_newsletter
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
Nasal | Projects | Core development |
Programming resources
Hooray
 
Posts: 6390
Joined: Tue Mar 25, 2008 8:40 am

Re: Announcing Comete Gauges for FlightGear

Postby Oby » Sun Jan 29, 2012 9:02 pm

Eagerly looking forward to the Android market release of this :D Now all we need is a good map application - preferrable with links to charts and other information.
Oby
 
Posts: 28
Joined: Mon Jun 14, 2010 8:39 pm

Re: Announcing Comete Gauges for FlightGear

Postby Gijs » Sun Jan 29, 2012 9:11 pm

Huh, how could i have missed this topic?! I guess it's because I didn't have an Android phone back then.

Sadly Alni seems to have left the forum, but there have been recent updates to the source code, so I have hope that he'll release it one day! I'll send him an email.
I'm enjoying my vacation

Airports: EHAM, EHLE, KSFO
Aircraft: 747-400, DC-2, F-117, Jetman, L1011-500
FlightGear Liveries
User avatar
Gijs
Moderator
 
Posts: 8629
Joined: Tue Jul 03, 2007 2:55 pm
Location: Amsterdam/Delft, the Netherlands
Callsign: PH-GYS
Version: Git
OS: Windows 7

Re: Announcing Comete Gauges for FlightGear

Postby Hooray » Mon Jan 30, 2012 3:02 pm

FWIW, regarding the telnet/props interface, we also used this for the j661 project, but we added a little twist to it by adding new commands to send properties conditionally using new subscribe/unsubscribe commands. So rather than continuously polling all properties, you can subscribe to certain properties in order to get update notifications:

Code: Select all
diff --git a/src/Network/props.cxx b/src/Network/props.cxx
index 7240d5c..bd014db 100644
--- a/src/Network/props.cxx
+++ b/src/Network/props.cxx
@@ -33,6 +33,7 @@
 #include <simgear/misc/strutils.hxx>
 #include <simgear/props/props.hxx>
 #include <simgear/props/props_io.hxx>
+#include <simgear/structure/exception.hxx>
 
 #include <sstream>
 #include <iostream>
@@ -45,6 +46,12 @@
 
 #include "props.hxx"
 
+#include <map>
+#include <vector>
+#include <string>
+
+#include <boost/functional/hash.hpp> // for property hashing (should probably be replaced eventually)
+
 using std::stringstream;
 using std::ends;
 
@@ -55,7 +62,7 @@ using std::endl;
  * Props connection class.
  * This class represents a connection to props client.
  */
-class PropsChannel : public simgear::NetChat
+class PropsChannel : public simgear::NetChat, public SGPropertyChangeListener
 {
     simgear::NetBuffer buffer;
 
@@ -75,6 +82,7 @@ public:
      * Constructor.
      */
     PropsChannel();
+    ~PropsChannel();
 
     /**
      * Append incoming data to our request buffer.
@@ -89,10 +97,38 @@ public:
      */
     void foundTerminator();
 
+    // callback for registered listeners (subscriptions)
+    void valueChanged(SGPropertyNode *node);
 private:
+
+    typedef std::vector<std::string> ParameterList;
+
+
     inline void node_not_found_error( const string& s ) const {
         throw "node '" + s + "' not found";
     }
+
+    void error(std::string msg) {  // wrapper: prints errors to STDERR and to the telnet client
+       push( msg.c_str() ); push( getTerminator() );
+       SG_LOG(SG_GENERAL, SG_ALERT, __FILE__<<"@" << __LINE__ <<" in " << __FUNCTION__ <<":"<< msg.c_str() << std::endl);
+    }
+
+
+    bool check_args(ParameterList tok, unsigned int num, const char* func) {
+       if (tok.size()-1 < num) {
+          error(string("Wrong argument count for:")+string(func) );
+          return false;
+       }
+       return true;
+    }
+
+    std::vector<SGPropertyNode_ptr> _listeners;
+    typedef void (PropsChannel::*TelnetCallback) (const ParameterList&);
+    std::map<std::string, TelnetCallback> callback_map;
+
+    // callback implementations:
+    void subscribe(const ParameterList &p);
+    void unsubscribe(const ParameterList &p);
 };
 
 /**
@@ -104,6 +140,67 @@ PropsChannel::PropsChannel()
       mode(PROMPT)
 {
     setTerminator( "\r\n" );
+    callback_map["subscribe"]    =    &PropsChannel::subscribe;
+    callback_map["unsubscribe"]   =   &PropsChannel::unsubscribe;
+}
+
+PropsChannel::~PropsChannel() {
+  // clean up all registered listeners   
+  for (unsigned int i=0;i< _listeners.size(); i++)
+    _listeners[i]->removeChangeListener( this  );
+
+}
+
+void PropsChannel::subscribe(const ParameterList& param) {
+   if (! check_args(param,1,"subscribe")) return;
+
+   std::string command = param[0];
+   const char* p = param[1].c_str();
+   if (!p) return;
+
+        SG_LOG(SG_GENERAL, SG_ALERT, p << std::endl);
+        push( command.c_str() ); push ( " " );
+        push( p );
+        push( getTerminator() );
+
+        SGPropertyNode *n = globals->get_props()->getNode( p,true );
+   if ( n->isTied() ) {
+      error("Error:Tied properties cannot register listeners");
+      return;
+   }
+    if (n) {
+         n->addChangeListener( this );
+    std::stringstream hashcode;
+    boost::hash<std::string> string_hash;
+    hashcode << "id:" << string_hash(n->getPath()) << getTerminator();
+    // push( hashcode.str().c_str() );  // not yet very useful
+    _listeners.push_back( n ); // housekeeping, save for deletion in dtor later on
+         }
+         else {
+       error("listener could not be added");
+         }
+
+
+}
+
+void PropsChannel::unsubscribe(const ParameterList &param) {
+  if (!check_args(param,1,"unsubscribe")) return;
+
+  try {
+   SGPropertyNode *n = globals->get_props()->getNode( param[1].c_str() );
+   n->removeChangeListener( this );
+  } catch (sg_exception &e) {
+     error("Error:Listener could not be removed");
+  }
+}
+
+
+//TODO: provide support for different types of subscriptions MODES ? (child added/removed, thesholds, min/max)
+void PropsChannel::valueChanged(SGPropertyNode* ptr) {
+  SG_LOG(SG_GENERAL, SG_ALERT, __FILE__<< "@"<<__LINE__ << ":" << __FUNCTION__ << std::endl); 
+  std::stringstream response;
+  response << ptr->getPath(true) << "=" <<  ptr->getStringValue() << "\r\n"; //TODO: use hashes, echo several properties at once, use proper terminator
+  push( response.str().c_str() );
 }
 
 /**
@@ -160,7 +257,7 @@ PropsChannel::foundTerminator()
     const char* cmd = buffer.getData();
     SG_LOG( SG_IO, SG_INFO, "processing command = \"" << cmd << "\"" );
 
-    vector<string> tokens = simgear::strutils::split( cmd );
+    ParameterList tokens = simgear::strutils::split( cmd );
 
     SGPropertyNode* node = globals->get_props()->getNode( path.c_str() );
 
@@ -292,7 +389,7 @@ PropsChannel::foundTerminator()
                     if ( !globals->get_commands()
                              ->execute( "reinit", &args) )
                     {
-                        SG_LOG( SG_NETWORK, SG_ALERT,
+                        SG_LOG( SG_GENERAL, SG_ALERT,
                                 "Command " << tokens[1] << " failed.");
                         if ( mode == PROMPT ) {
                             tmp += "*failed*";
@@ -357,7 +454,7 @@ PropsChannel::foundTerminator()
                     if ( !globals->get_commands()
                              ->execute(tokens[1].c_str(), &args) )
                     {
-                        SG_LOG( SG_NETWORK, SG_ALERT,
+                        SG_LOG( SG_GENERAL, SG_ALERT,
                                 "Command " << tokens[1] << " failed.");
                         if ( mode == PROMPT ) {
                             tmp += "*failed*";
@@ -386,7 +483,14 @@ PropsChannel::foundTerminator()
                 mode = DATA;
             } else if ( command == "prompt" ) {
                 mode = PROMPT;
-            } else {
+            } else if (command  == "subscribe" || command == "unsubscribe") {
+         TelnetCallback t = callback_map[ command.c_str() ]; //FIXME: use map lookup for condition
+         if (t)
+                 (this->*t) (tokens);
+         else
+            error("No matching callback found for command:"+command);
+       }
+       else {
                 const char* msg = "\
 Valid commands are:\r\n\
 \r\n\
@@ -400,7 +504,9 @@ prompt             switch to interactive mode (default)\r\n\
 pwd                display your current path\r\n\
 quit               terminate connection\r\n\
 run <command>      run built in command\r\n\
-set <var> <val>    set <var> to a new <val>\r\n";
+set <var> <val>    set <var> to a new <val>\r\n\
+subscribe <var>      subscribe to property changes (returns hash code for property)\r\n\
+unscubscribe <id>  unscubscribe from property changes (id must be the property hash as returned from subscribe command)\r\n";
                 push( msg );
             }
         }
diff --git a/src/Network/props.hxx b/src/Network/props.hxx
index e55f7c1..09b5a09 100644
--- a/src/Network/props.hxx
+++ b/src/Network/props.hxx
@@ -40,7 +40,8 @@
  * FlightGear properties.
  */
 class FGProps : public FGProtocol,
-      public simgear::NetChannel
+      public simgear::NetChannel,
+      public SGPropertyChangeListener // for subscriptions
 {
 private:
 
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
Nasal | Projects | Core development |
Programming resources
Hooray
 
Posts: 6390
Joined: Tue Mar 25, 2008 8:40 am


Return to Development

Who is online

Users browsing this forum: No registered users and 2 guests