Advanced Question Boost libraries with Orbiter Module

Zatnikitelman

Addon Developer
Addon Developer
Joined
Jan 13, 2008
Messages
2,302
Reaction score
6
Points
38
Location
Atlanta, GA, USA, North America
I've had both a breakthrough and major letdown in interfacing a serial device with Orbiter. I've tried using the Boost Serial library through this wrapper class I found online Here. The console version worked great in terms of verifying the right data was being sent and processed properly, but when I plonked it into an Orbiter plugin I'm writing, it fails to compile with the error:
>c:\users\matt\downloads\boost_1_45_0\boost_1_45_0\boost\asio\detail\socket_types.hpp(22) : fatal error C1189: #error : WinSock.h has already been included
I'm compiling in debug mode and have code generation set to "Multithreaded Debug" under Code Generation in VC++2008.
does anyone know what I'm doing wrong?
Thanks,
Zatman-Matt
 

orb

New member
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
Is this error while you're compiling boost as a static multithreaded debug library that will be linked later with your module, or is it appearing while you're compiling your module because socket_types.hpp is included in your project?
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,660
Reaction score
2,381
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
I think you can fix this by changing the order of your "#include" statements, if not, I need to check the Windows SDK documentation for the right #define statement to exclude the WinSock.h
 

MeDiCS

Donator
Donator
Joined
Sep 22, 2008
Messages
602
Reaction score
2
Points
0
According to MSDN, #define WIN32_LEAN_AND_MEAN should exclude sockets from being included with a #include <windows.h>.
 

Zatnikitelman

Addon Developer
Addon Developer
Joined
Jan 13, 2008
Messages
2,302
Reaction score
6
Points
38
Location
Atlanta, GA, USA, North America
Thanks to everyone who responded. I figured it out and got it compiled and mostly working. However, I'm having an extreme lag problem between sending serial data, and it being updated within Orbiter. I'll update the info the device (an Arduino Mega) is sending, and it'll take 30 seconds or so to register the change in Orbiter. It also seems to buffer changes, so if I send the value up, then down, then back up, I'll see the data in Orbiter change in the same manner only heavily delayed. I have a simple test program that uses the same process I'm using in Orbiter. The only difference between the two is the test program uses a while(true) loop to display data, while in my Orbiter module, it's called in opcPreStep. The test program reflects changes in the sent data instantly. Framerate doesn't appear to be the problem as I'm getting between 80 and 90 fps when running this module. The module code is posted below. As you may or may not be able to tell from the comments, I'm printing the serial data to the debug string as soon as it's received so there's no processing or anything else right now that could be getting in the way. The serial wrapper class I'm using is the same as the link in my first post.
Thanks for any help you can provide.

Module .cpp file:
Code:
#define STRICT
#define ORBITER_MODULE
#define WIN32_LEAN_AND_MEAN
#include "orbitersdk.h"
#include "SerialClass.h"

HINSTANCE g_hDLL;
NOTEHANDLE pitchtest;
DWORD module;
int count = 0;
SimpleSerial s("COM4",9600);

int handleSerial(int *addr, int *payload)
{	
	//int addr = 0;
	//int val = 0;
	
	std::string input = s.readLine();
	
	char *cstring = (char*)input.c_str();
	sprintf(oapiDebugString(),"%s",cstring);
	
	//sprintf(oapiDebugString(),"%s",cstring);
	//sscanf_s(cstring,"<%d|%d>",addr,payload);
	return 0;
	//sprintf(oapiDebugString(),"Value is %d",payload);
	
	//cout<<"Address: "<<addr<<" Value: "<<val<<endl;	
}

DLLCLBK void InitModule(HINSTANCE hModule)
{
	g_hDLL = hModule;
	pitchtest = oapiCreateAnnotation(false,1,_V(0,1,0));
	oapiAnnotationSetPos(pitchtest, 0.02, 0.4, 1, 1);
	oapiWriteLog("Flight Deck Initialized");
}

DLLCLBK void ExitModule(HINSTANCE hModule)
{
}
DLLCLBK void opcPreStep(double SimT,double simDT, double mjd)
{
	//oapiWriteLog("Reached Prestep");
	if(SimT>10)
	{
		VESSEL3 *vessel = (VESSEL3*)oapiGetFocusInterface();
		int add = 0;
		int payload = 0;
		int y = handleSerial(&add,&payload);

		double pitch = (double)payload;
		if(add == 1)
		{
			//sprintf(oapiDebugString(),"Is 1 and %d",payload);
			pitch = (1/464)*pitch-1;
			vessel->SetAttitudeRotLevel(0,payload);
			char temp [20];
			sprintf(temp,"Pitch is %d",pitch);	
		}
		//oapiAnnotationSetText(pitchtest,temp);
		//sprintf(oapiDebugString(),"Pitch is %lf",payload);
	}
}
Module .h file:
Code:
#include <boost/asio.hpp>
//#include <boost/asio/serial_port.hpp>

class SimpleSerial
{
public:
    /**
     * Constructor.
     * \param port device name, example "/dev/ttyUSB0" or "COM4"
     * \param baud_rate communication speed, example 9600 or 115200
     * \throws boost::system::system_error if cannot open the
     * serial device
     */
    SimpleSerial(std::string port, unsigned int baud_rate): io(), serial(io,port)
    {
        serial.set_option(boost::asio::serial_port_base::baud_rate(baud_rate));
    }

    /**
     * Write a string to the serial device.
     * \param s string to write
     * \throws boost::system::system_error on failure
     */
    void writeString(std::string s)
    {
        boost::asio::write(serial,boost::asio::buffer(s.c_str(),s.size()));
    }

    /**
     * Blocks until a line is received from the serial device.
     * Eventual '\n' or '\r\n' characters at the end of the string are removed.
     * \return a string containing the received line
     * \throws boost::system::system_error on failure
     */
    std::string readLine()
    {
        //Reading data char by char, code is optimized for simplicity, not speed
        using namespace boost;
		
        std::string result;
        for(;;)
        {
	    //char c[11]={0};
	    char c;
            asio::read(serial,asio::buffer(&c,1));
	    //cout<<c;
            //return "0";
            switch(c)
            {
                case '\r':
                    break;
                case '\n':
                    return result;
                default:
                    result+=c;
            }
        }
    }

private:
    boost::asio::io_service io;
    boost::asio::serial_port serial;
};
 
Last edited:

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
If you add a sleep(15) in your program that uses a while loop (to emulate it having a framerate) does it show the same behavior as orbiter?
 

Zatnikitelman

Addon Developer
Addon Developer
Joined
Jan 13, 2008
Messages
2,302
Reaction score
6
Points
38
Location
Atlanta, GA, USA, North America
Wow, yes, same result as in Orbiter. Is there a way around this? I'm thinking putting the serial reading code into a separate thread would be the best option, but if there's a better way, I'm listening.
 
Top