http://openig.compro.net

A Opensource Image generator for the masses !
It is currently Thu Sep 23, 2021 3:26 am

All times are UTC - 5 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Thu Feb 11, 2016 2:05 pm 
Offline

Joined: Tue May 26, 2015 5:46 am
Posts: 21
Hi,

I am trying to make networking available on (1.2.) now 2.0.

My procedure was running openig-bullet.exe out of the box, then, going to default.txt in the same folder as openig-bullet.exe, then comment this line:

#manip 1 trackball

and uncomment these ones:

manip 1 trackball off
bullet freeze

Then, I went to bin\igplugins\IgPlugin-Networking.dll.xml and change from MASTER to SLAVE.
So, I ran openig-bullet.exe, but the slave is hanging... I've also allowed this program through proxy.
Should I do anything else?

Also, how would I write a TCP/UDP client to send coordinates to an aircraft (or for the car) to move?

Thanks in advance,
Daniel


Top
 Profile  
 
PostPosted: Fri Feb 12, 2016 5:21 pm 
Offline

Joined: Tue May 12, 2015 6:11 pm
Posts: 16
Hi Daniel,

We have just posted the 2.0.0 (like a few hours ago) so please go ahead and update :-). Lots of new cool features.

Let me give you some explanation first.

There are two modes available: MASTER and SLAVE. The MASTER suppose to control the entities and the SLAVE should accept these updates from the MASTER. And this is done with the provided Networking plugin (will explain how it works bellow). The Networking plugin has to be registered with the application's openig.xml (like the Application-Bullet has) and the modes are set in the plugins/OpenIG-Plugin-Networking.dll.xml <-- here one set the mode (MASTER/SLAVE), ports, the IP and the protocol (TCP/UDP). The Networking plugin was built using the provided Library-Networking (we go through the code bellow).

So, for you to get started, let say first on a single host, you specify your IP in the <HOST> section ( <TCP-Server> too for TCP ), and run an instance of the app. Then just change the <Mode> to SLAVE (from the default MASTER) and run another instance. Here is a short video of how you can do this:

https://dl.dropboxusercontent.com/u/91101321/OpenIG-2.0.0-Networking.mp4
Let examine the default.txt. For the MASTER mode it is important that you, the host is controlling the model. We have the bulllet for this so there is nothing to do, you can move the car with the arrows keys. For SLAVE though, you must disable any control on the entities and get them updated by the MASTER over network: for this we disable the trackball manipulator for the camera and the bullet for the car model - now they are getting updates over the network. Here is the section - and this is only valid for SLAVE:

{$OPENIG_NETWORKING_MODE==SLAVE} manip 1 trackball off
{$OPENIG_NETWORKING_MODE==SLAVE} bullet freeze

Now let examine a bit the code, from the Networking Plugin. This is how it is done:
- the host application, let use Application-Bullet as an example, is only controlling the models, as you wish. Here it is enough to set the entity position. And that's all you need from the host side.
- then, here the plugin framework takes the magic. There is a Sample Networking plugin that listen to the scene, iterates over the entity map from the OpenIG::Base::ImageGenerator and broadcast the Entity positions. This is how it is done in the Networking plugin, and we have 'invented' a sample protocol to serve as a guide. One can implement proprietary, maybe CIGI etc. And one can also configure the IG to work with any networking plugin or all of them.

Here is the code needed - please refer to the OpenIG::PluginBase::Plugin class to learn about the hooks. But in general and short, there is an Plugin::update(OpenIG::PluginBase::PluginContext& context) hook that is being called on update. Let assume you have the network setup in the init method and in this update hook you simply iterate over the entities and send them over the network. You have to define packets for this and use the underlaying networking libary to do so. Here are some snippets from the Networking Plugin that will help a bit how to write your own protocol and implement your own packets:

Let examine how to broadcast an EntityState as a MASTER, then we visit later bellow the SLAVE part

1. EntityState Packet. Here what is needed to broadcast for an Entity is the ID and the position/orientation/scale - it's Matrix
Code:
#define OPCODE_ENTITYSTATE            100

struct EntityState: public OpenIG::Library::Networking::Packet
{
   EntityState()
      : entityID(0)
   {
   }

   META_Packet(OPCODE_ENTITYSTATE, EntityState);

   virtual int write(OpenIG::Library::Networking::Buffer &buf) const
   {      
      buf << (unsigned char)opcode();
      buf << entityID;
      buf << mx(0, 0) << mx(0, 1) << mx(0, 2) << mx(0, 3);
      buf << mx(1, 0) << mx(1, 1) << mx(1, 2) << mx(1, 3);
      buf << mx(2, 0) << mx(2, 1) << mx(2, 2) << mx(2, 3);
      buf << mx(3, 0) << mx(3, 1) << mx(3, 2) << mx(3, 3);

      return sizeof(unsigned char) + sizeof(entityID) + sizeof(osg::Matrixd::value_type) * 16;
   }

   virtual int read(OpenIG::Library::Networking::Buffer &buf)
   {      
      unsigned char op;

      buf >> op;
      buf >> entityID;
      buf >> mx(0, 0) >> mx(0, 1) >> mx(0, 2) >> mx(0, 3);
      buf >> mx(1, 0) >> mx(1, 1) >> mx(1, 2) >> mx(1, 3);
      buf >> mx(2, 0) >> mx(2, 1) >> mx(2, 2) >> mx(2, 3);
      buf >> mx(3, 0) >> mx(3, 1) >> mx(3, 2) >> mx(3, 3);

      return sizeof(unsigned char) + sizeof(entityID) + sizeof(osg::Matrixd::value_type) * 16;
   }

   unsigned int   entityID;
   osg::Matrixd   mx;
};


2. We need a Buffer to write to (the class provided by the Library-Networking takes care of endianess)
Code:
OpenIG::Library::Networking::Buffer buffer(BUFFER_SIZE);


3. In the Plugin::update method that is called each frame, we get the ImageGenerator instance through the PluginContext, we use it to iterate over all the Entities and we send them off to the network
Code:
    virtual void update(OpenIG::PluginBase::PluginContext& context)
    {      
      OpenIG::Base::ImageGenerator::EntityMapIterator itr = context.getImageGenerator()->getEntityMap().begin();
      for (; itr != context.getImageGenerator()->getEntityMap().end(); ++itr)
      {
         EntityState estate;
         estate.entityID = itr->first;
         estate.mx = itr->second->getMatrix();
         estate.write(buffer);
      }


4. We send the buffer to the network (here is for example how the network is setup in Plugin::init let say for UDP)
Code:
// This goes in Plugin::init
boost::shared_ptr<OpenIG::Library::Networking::Network>         _network;
_network = boost::shared_ptr<OpenIG::Library::Networking::UDPNetwork>(new OpenIG::Library::Networking::UDPNetwork("127.0.0.1"));

...
// This goes in Plugin::update
_network->send(buffer);


And this is it for the MASTER. Now, the SLAVE need to understand these Packets, so again, we receive a buffer, we parse the buffer and we update our IG on the SLAVE side
1. Use the Packet defined for the EntityState from above
2. A Parser is needed to understand our custom Packet. It is very easy to do one, it uses the Factory design pattern and all you need is to define a template for the Parser. Here is one that will understand our EntityState packet
Code:
struct Parser : public OpenIG::Library::Networking::Parser
{
   Parser()
   {
      OpenIG::Library::Networking::Factory::instance()->addTemplate(new EntityState);      
   }

   virtual OpenIG::Library::Networking::Packet* parse(OpenIG::Library::Networking::Buffer& buffer)
   {      
      const unsigned char* opcode = buffer.fetch();

      OpenIG::Library::Networking::Packet* packet = OpenIG::Library::Networking::Factory::instance()->packet(*opcode);
      if (packet)
      {
         packet->read(buffer);         
      }
      return packet;
   }
   
};

3. We set this parser to the network
Code:
_network->setParser(new Parser);

4. Now, once a packet is parsed, we can define callbacks when a Packet with a specific OPCODE is encountered
Code:
struct EntityStateCallback : public OpenIG::Library::Networking::Packet::Callback
{
   EntityStateCallback(OpenIG::Base::ImageGenerator* ig)
      : imageGenerator(ig)
   {

   }

   virtual void process(OpenIG::Library::Networking::Packet& packet)
   {
      EntityState* es = dynamic_cast<EntityState*>(&packet);
      if (es)
      {
         imageGenerator->updateEntity(es->entityID, es->mx);
      }
   }

   OpenIG::Base::ImageGenerator* imageGenerator;
};

_network->addCallback((OpenIG::Library::Networking::Packet::Opcode)OPCODE_ENTITYSTATE, new EntityStateCallback(_ig));


So to sum up, for SLAVEs you will need again the same Packet definition based on an OPCODE, then a Parser that will have a template of the Packet, and register a Callback in the network (the callback is what is to happen when a Packet with some OPCODE arrives on the network)

Now, with this brief guide I encourage you to go through the provided OpenIG-Plugin-Networking and see how it is done there. The important thing is to understand the concept - the host app need not to know about networking at all - let it only control the entities (weather, cameras ..etc), and let the Plugins take care of it.

I hope this will gives you the idea and help you. If not, please ping again, and we will try to help again :-)

Cheers, and thanks for the interest in OpenIG!

Nick


Top
 Profile  
 
PostPosted: Sat Feb 13, 2016 8:01 pm 
Offline

Joined: Sat Jan 02, 2016 6:07 pm
Posts: 2
So will networking work with CIGI connections?


Top
 Profile  
 
PostPosted: Mon Feb 15, 2016 12:17 pm 
Offline

Joined: Tue May 12, 2015 6:11 pm
Posts: 16
Hi Djmax,

it should. I am not a CIGI expert but I did some readings on this (and forget most of it I guess :-) ). CIGI is working with Geographics coordinates right? For this you would want a Geocentric database or some transformations of coordinates (this is doable, at least I know it was doable for databases generated by Presagis TerraVista and parsing ther projInfo.txt file where the coordinate frame of the database is somehow encoded). But just these days we were doing some tests with Geocentric (ECEF) databases and OpenIG is ready as is in the 2.0.0. Most of the plugins works well, like the F+ (some of the features need revisit), SilverLining worked out of the box, Triton needs some changes in shader for the height map generation we are using), but for initial tests it passed ok, so we can say OpenIG is Geocentric capable at early stages - stay tuned for the next release were we plan to make full support for it and maybe for RoundEarth as well.

Back to your question: The provided Library-Networking is based on boost and can do UDP/TCP communication. And the provided OpenIG-Plugin-Networking demonstrate usage of it. What you need to do is to mimic the code above described and implement the CIGI protocol. Anyway we do have in plans for supporting CIGI in a new plugin somewhere in the future, but also feel free to join the efforts too :-)


Top
 Profile  
 
PostPosted: Sat Feb 20, 2016 3:44 pm 
Offline

Joined: Sat Jan 02, 2016 6:07 pm
Posts: 2
So you're suggesting I integrate the CIGI SDK for it to work? or can it work right of the bat?


Top
 Profile  
 
PostPosted: Thu Feb 25, 2016 6:43 pm 
Offline

Joined: Tue May 26, 2015 5:46 am
Posts: 21
Great, thanks for the deep explanation. I think I got the idea on how to create a server for the Slave using UDP!

Thank you!


Top
 Profile  
 
PostPosted: Thu Feb 25, 2016 10:56 pm 
Offline
Site Admin

Joined: Tue May 12, 2015 10:50 am
Posts: 18
Djmax wrote:
So you're suggesting I integrate the CIGI SDK for it to work? or can it work right of the bat?



Hello DJ,

We had a few discussions months back about integrating the CIGI SDK as a plug-in interface for OpenIG. While CIGI is an "OPEN" standard for IG it is quite an effort just to be fully compliant (from IG point of view as we need all CIGI opcodes supported) . So it was a "time issue" and not that we do not want or still need.. (Problem with free is balance of features and the time and efforts of volunteers.)

But, we "did" decide to make an example network plug-in that provides the base for ANY payload you need. It is not just a UPD or TCP plug-in. You will notice, in the design, are controls for master and slave channels and mechanisms to alert on packet drop and misses.

We REALLY want to do CIGI and I would support anyone that has background or expertise in the CIGI framework to join us and contribute to the plug-in. I know there are many that could use this to attach quickly to their current simulator host if already supporting CIGI.

Our position right now, (just due to time really..), is to focus on a flexible "Generic" plug-in that would address those older HOSTS that had their respective frame definitions and opcodes.

So, in short. it is on the "list" just not at the top right now. If I can get a few more volunteers then for sure it would be nice to do now :D :D

All the best to you and wish you good health !


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 5 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group