Re: [Plib-users] Problem with setLabel, weirdness ensues.
Brought to you by:
sjbaker
|
From: cory b. <co...@gm...> - 2008-06-11 19:55:58
|
I am ok with public code on this one. I put the GPL stuff on top of
the file. Here is the email I sent to John:
Wow! Fantastic response time! Thank you. I have been banging my head
on this problem for while now.
I attached the main file that I am working with.
The relevant bits(to the best of my knowledge) are located in the
following functions:
main: line 96
init_pui_widgets: line 453
pui_callback: line 516
I am doing the development in Ubuntu. I will send you the supporting
classes for this program if needed.
Let me know if you still want me to make a small sample program to
demonstrate the issue.
Also the char array for radio button labels:
char *controller_selector_labels[] = { "Roll", "Pitch", NULL };
gives a warning: softSim.cxx:76: warning: deprecated conversion from
string constant to 'char*'
Do you know how to fix that?
Thanks,
Cory
Here is the code:
/**********************************************************************
* softSim.cxx
* Software simulation interface for FlightGear
*
* Written by Cory Barton, started May 2008
* Copyright (C) 2008 Cory Barton co...@gm...
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*********************************************************************/
//#include <memory.h>
#include <stdio.h>
#include <sstream>
#include <simgear/compiler.h>
#include <GL/glut.h>
//#include SG_GLUT_H
#include <plib/fnt.h>
#include <plib/pu.h>
#include <string>
#include <simgear/io/sg_socket.hxx>
#include <simgear/io/sg_serial.hxx>
#include <simgear/io/sg_file.hxx>
#include "SSAircraft.hxx"
#include "SSPid.hxx"
using namespace std;
//defines
#define DECIMALS 6
#define KEY_ESCAPE 27
#define WINDOW_X 350 //window width
#define WINDOW_Y 350 //window height
#define PUI_X_OFFSET 0
#define PUI_Y_OFFSET 0
#define GAIN_MIN -1 //gain values for sliders MIN should be 0 or less
#define GAIN_MAX 1
#define DEG_MIN -180 //target value limiters
#define DEG_MAX 180
//global items
//objects
SGIOChannel *in_channel, *out_channel, *log_file;
SSAircraft *sim_craft = new SSAircraft();
SSPid *aileron_pid = new SSPid();
SSPid *elevator_pid = new SSPid();
//vars
bool slaved = false;
bool network = false;
bool serial = false;
bool output = false;
bool logging = false;
bool pauseSoftSim = true;
char baud[ 256 ] = "4800";
char inport[ 256 ] = "5500";
char outport[ 256 ] = "5501";
char device [256 ] = "/dev/ttyS0";
int sock;
float update = 1.0f;
char out_file[ 1024 ] = "softSimLog.csv";
char save_buf[ 2 * 2048 ];
int save_len = 0;
//pui widgets from PLIB library
//puGroup *gui_group;
puFrame *gui_frame;
char *controller_selector_labels[] = { "Roll", "Pitch", NULL };
puButtonBox *controller_selector;
puButton *pause_button, *log_button;
puSlider *kp_slider, *ki_slider, *kd_slider, *target_slider;
//function prototypes
void print_help( void );
void timer( int value );
bool parse_fgear_data( char *buf );
void redrawWindow( void );
void reshapeWindow( int w, int h );
string command_output( void );
void processNormalKeys( unsigned char key, int x, int y );
void init_pui_widgets( void );
void pui_callback( puObject *pob );
void processMousefn ( int button, int updown, int x, int y );
void processMotionfn ( int x, int y );
int main( int argc, char **argv ) {
// parse arguments
for ( int i = 1; i < argc; i++ ) {
if ( sscanf(argv[i], "--udp-in=%s", inport ) == 1 ) {
slaved = true;
network = true;
serial = false;
} else if ( sscanf( argv[i], "--udp-out=%s", outport ) == 1 ) {
output = true;
} else if ( sscanf( argv[i], "--serial=%s", device ) == 1 ) {
slaved = true;
serial = true;
network = false;
} else if ( sscanf( argv[i], "--baud=%s", baud ) == 1 ) {
// do nothing
} else if ( sscanf( argv[i], "--update=%f", &update ) == 1 ) {
// do nothing
} else if ( sscanf( argv[i], "--log=%s", out_file ) == 1 ) {
logging = true;
} else if ( strcmp( argv[i], "--help" ) == 0 ) {
print_help();
return 0;
} else {
print_help();
fprintf( stderr, "%s: unknown flag \"%s\".\n", argv[0], argv[i] );
return 1;
}
}
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB );
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( WINDOW_X, WINDOW_Y );
glutCreateWindow( "SoftSim" );
glutDisplayFunc( redrawWindow );
glutReshapeFunc( reshapeWindow );
glutIdleFunc( redrawWindow );
glutMouseFunc ( processMousefn ); // process mouse clicks
glutMotionFunc ( processMotionfn ); // process mouse moves
glutPassiveMotionFunc ( processMotionfn );
glutKeyboardFunc( processNormalKeys );
// enable depth testing
glEnable( GL_DEPTH_TEST );
if ( slaved ) {
glutTimerFunc( ( int )( 1000.0f/update ), timer, 0 );
if ( network ) {
in_channel = new SGSocket( "", inport, "udp" );
if ( output ) {
out_channel = new SGSocket( "", outport, "udp" );
}
} else if ( serial ) {
in_channel = new SGSerial( device, baud );
} else {
printf( "unknown input, defaulting to network on port 5500\n" );
in_channel = new SGSocket( "", "5500", "udp" );
}
in_channel->open( SG_IO_IN );
if ( output ) {
out_channel->open( SG_IO_OUT );
}
if ( logging ) {
string f_name = out_file;
log_file = new SGFile( f_name );
log_file->open( SG_IO_OUT );
}
}
//initialize PID controllers
aileron_pid->set_gains( 0.06, 0.004, -0.04 );
aileron_pid->set_reference( 0 );
aileron_pid->set_limits( -1, 1 );
elevator_pid->set_gains( -0.05, -0.001, 0 );
elevator_pid->set_reference( 0 );
elevator_pid->set_limits( -1, 1 );
init_pui_widgets();
glutMainLoop();
if ( slaved ) {
in_channel->close();
if ( output ) {
out_channel->close();
}
if ( logging ) {
log_file->close();
}
}
return 0;
}
void timer( int value ) {
char buffer[ 512 ];
size_t found;
string log_str; //string to log to file
int length;
if ( !pauseSoftSim ){
//read incoming data
while ( ( length = in_channel->readline( buffer, 512 ) ) > 0 ) {
parse_fgear_data( buffer );
if ( logging ) {
//prepare log string
log_str = buffer;
//find \n char and replace with comma
found=log_str.find( '\n' );
if ( found!=string::npos ) {
log_str.replace( found, 1, "," );
}
}
}
string command_str = command_output();
if ( output ) {
//send outgoing data
out_channel->write( command_str.c_str(), command_str.size() );
}
//log to file
if ( logging ) {
//don't log if no data from udp
if ( log_str.length () > 0 ) {
log_str.append( command_str );
log_file->writestring( log_str.c_str() );
//cout << command_str.c_str() << endl;
//cout << log_str << endl;
}
}
//make some updates
system( "clear" ); //this is not portable. I should probably
//be using the ncurses library
cout.precision( DECIMALS );
cout << "Roll error: " << aileron_pid->get_error() << endl;
cout << "Pitch error: " << elevator_pid->get_error() << endl;
}
glutTimerFunc( ( int )( 1000.0f/update ), timer, value );
}
//parse incoming data from flight gear
bool parse_fgear_data( char *buf )
{
//variables
//control
double aileron, elevator, rudder, throttle;
//position
double latitudeDegree, longitudeDegree, altitude;
//attitude
double headingDegree, rollDegree, pitchDegree, sideSlip;
//speed / accel
double airspeed, verticalSpd, xAccel, yAccel, zAccel;
//printf("%s\n", buf);
string msg = buf;
string::size_type begin, end;
begin = 0;
end = msg.find( ",", begin );
if ( end == string::npos ) {
return false;
}
//aileron
aileron = atof( msg.substr( begin, end ).c_str() );
begin = end + 1;
//elevator
end = msg.find( ",", begin );
if ( end == string::npos ) {
return false;
}
elevator = atof( msg.substr( begin, end - begin ).c_str() );
begin = end + 1;
//rudder
end = msg.find( ",", begin );
if ( end == string::npos ) {
return false;
}
rudder = atof( msg.substr( begin, end - begin ).c_str() );
begin = end + 1;
//throttle
end = msg.find( ",", begin );
if ( end == string::npos ) {
return false;
}
throttle = atof( msg.substr( begin, end - begin ).c_str() );
begin = end + 1;
//latitude
end = msg.find( ",", begin );
if ( end == string::npos ) {
return false;
}
latitudeDegree = atof( msg.substr( begin, end - begin ).c_str() );
begin = end + 1;
//longitude
end = msg.find( ",", begin );
if ( end == string::npos ) {
return false;
}
longitudeDegree = atof( msg.substr( begin, end - begin ).c_str() );
begin = end + 1;
//altitude
end = msg.find( ",", begin );
if ( end == string::npos ) {
return false;
}
altitude = atof( msg.substr( begin, end - begin ).c_str() );
begin = end + 1;
//roll
end = msg.find( ",", begin );
if ( end == string::npos ) {
return false;
}
rollDegree = atof( msg.substr( begin, end - begin ).c_str() );
begin = end + 1;
//pitch
end = msg.find( ",", begin );
if ( end == string::npos ) {
return false;
}
pitchDegree = atof( msg.substr( begin, end - begin ).c_str() );
begin = end + 1;
//heading
end = msg.find( ",", begin );
if ( end == string::npos ) {
return false;
}
headingDegree = atof( msg.substr( begin, end - begin ).c_str() );
begin = end + 1;
//side slip
end = msg.find( ",", begin );
if ( end == string::npos ) {
return false;
}
sideSlip = atof( msg.substr( begin, end - begin ).c_str() );
begin = end + 1;
//airspeed
end = msg.find( ",", begin );
if ( end == string::npos ) {
return false;
}
airspeed = atof( msg.substr( begin, end - begin ).c_str() );
begin = end + 1;
//vertical speed
end = msg.find( ",", begin );
if ( end == string::npos ) {
return false;
}
verticalSpd = atof( msg.substr( begin, end - begin ).c_str() );
begin = end + 1;
//x accel
end = msg.find( ",", begin );
if ( end == string::npos ) {
return false;
}
xAccel = atof( msg.substr( begin, end - begin ).c_str() );
begin = end + 1;
//y accel
end = msg.find( ",", begin );
if ( end == string::npos ) {
return false;
}
yAccel = atof( msg.substr( begin, end - begin ).c_str() );
begin = end + 1;
//z accel
end = msg.find( "\n", begin );
if ( end == string::npos ) {
return false;
}
zAccel = atof( msg.substr( begin, end - begin ).c_str() );
begin = end + 1;
//set aircraft values
sim_craft->set_aileron( aileron );
sim_craft->set_elevator( elevator );
sim_craft->set_rudder( rudder );
sim_craft->set_throttle( throttle );
sim_craft->set_latitude( latitudeDegree );
sim_craft->set_longitude( longitudeDegree );
sim_craft->set_altitude( altitude );
sim_craft->set_roll( rollDegree );
sim_craft->set_pitch( pitchDegree );
sim_craft->set_heading( headingDegree );
sim_craft->set_sideslip( sideSlip );
sim_craft->set_airspeed( airspeed );
sim_craft->set_vert_speed( verticalSpd );
sim_craft->set_xaccel( xAccel );
sim_craft->set_yaccel( yAccel );
sim_craft->set_zaccel( zAccel );
return true;
}
string command_output( void ) {
stringstream s;
s.precision( DECIMALS );
s << aileron_pid->update( sim_craft->get_roll() ) << ","
<< elevator_pid->update( sim_craft->get_pitch() ) << endl;
/*
s << sim_craft->get_aileron() << ","
<< sim_craft->get_elevator() << ","
<< sim_craft->get_rudder() << ","
<< sim_craft->get_throttle() << endl;
*/
//cout << s.str() << endl;
return s.str();
}
void redrawWindow( void ) {
puDisplay();
glutSwapBuffers();
glutPostRedisplay();
}
void reshapeWindow( int w, int h ) {
glutReshapeWindow( WINDOW_X, WINDOW_Y ); //set window back to initial size
}
void processMousefn ( int button, int updown, int x, int y ) {
// Invoke the PUI mouse function
puMouse ( button, updown, x, y ) ;
glutPostRedisplay () ;
}
void processMotionfn ( int x, int y ){
// Invoke the PUI mouse motion function
puMouse ( x, y ) ;
glutPostRedisplay () ;
}
void processNormalKeys(unsigned char key, int x, int y) {
// Invoke the PUI keyboard function
puKeyboard ( key, PU_DOWN ) ;
glutPostRedisplay() ;
}
/**********************************************************************
* Initialize pui controls
*********************************************************************/
void init_pui_widgets( void ) {
//unused variable bbb
char bbb[ PUSTRING_MAX ]; //if I remove this setLabel() fails!
char txt[ PUSTRING_MAX ];
puInit();
gui_frame = new puFrame( PUI_X_OFFSET,
PUI_Y_OFFSET,
PUI_X_OFFSET + WINDOW_X,
PUI_Y_OFFSET + WINDOW_Y );
//radio buttons
controller_selector = new puButtonBox ( 10, 200, 90, 270,
controller_selector_labels, 1 );
//value corresponds to index of item in labels array
controller_selector->setCallback( pui_callback );
//kp slider
kp_slider = new puSlider ( 100, 60, 200, TRUE );
kp_slider->setMinValue( GAIN_MIN );
kp_slider->setMaxValue( GAIN_MAX );
kp_slider->setValue( ( float ) aileron_pid->get_kp() ); //set value
to aileron gains since roll is selected by default
sprintf( txt, "Kp: %.3f", aileron_pid->get_kp() ); //format label
kp_slider->setLabel( txt );
cout << txt << endl;
kp_slider->setLabelPlace( PUPLACE_TOP_CENTERED );
kp_slider->setCallback( pui_callback );
//ki slider
ki_slider = new puSlider ( 140, 60, 200, TRUE );
ki_slider->setMinValue( GAIN_MIN );
ki_slider->setMaxValue( GAIN_MAX );
ki_slider->setValue( ( float ) aileron_pid->get_ki() );
ki_slider->setLabel( "Ki" );
ki_slider->setLabelPlace( PUPLACE_TOP_CENTERED );
ki_slider->setCallback( pui_callback );
//kd slider
kd_slider = new puSlider ( 180, 60, 200, TRUE );
kd_slider->setMinValue( GAIN_MIN );
kd_slider->setMaxValue( GAIN_MAX );
kd_slider->setValue( ( float ) aileron_pid->get_kd() );
kd_slider->setLabel( txt );
kd_slider->setLabelPlace( PUPLACE_TOP_CENTERED );
kd_slider->setCallback( pui_callback );
//target slider
target_slider = new puSlider ( 10, 30, 330, FALSE, 20);
target_slider->setMinValue( DEG_MIN );
target_slider->setMaxValue( DEG_MAX );
target_slider->setValue( ( float ) aileron_pid->get_reference() );
target_slider->setLabel( "Target" );
target_slider->setLabelPlace( PUPLACE_BOTTOM_CENTERED );
target_slider->setCallback( pui_callback );
//pause button
pause_button = new puButton( 210, 130, "Pause" );
pause_button->setSize( 60, 30 );
pause_button->setValue( 1 ); //pause by default
pause_button->setCallback( pui_callback );
//log button
log_button = new puButton( 210, 80, "Log" );
log_button->setSize( 60, 30 );
log_button->setValue( 0 ); //logging off by default
log_button->setCallback( pui_callback );
}
/**********************************************************************
* pui callback
*********************************************************************/
void pui_callback( puObject *pob ){
//this will be 0 for roll and 1 for pitch
int val = controller_selector->getValue();
//unused variable bbb
char bbb[ PUSTRING_MAX ]; //trying to make setLabel work
char txt[ PUSTRING_MAX ];
if ( pob == log_button ) { //toggle logging
logging = log_button->getValue();
//cout << "log_button" << endl;
} else if ( pob == pause_button ) { //toggle pause
pauseSoftSim = pause_button->getValue();
//cout << "pause_button" << endl;
} else if ( pob == kp_slider ) { //update kp
if ( val == 0 ) {
aileron_pid->set_kp( ( double ) kp_slider->getValue() );
sprintf( txt, "Kp: %.3f", aileron_pid->get_kp() ); //format label
kp_slider->setLabel( txt ); //BROKEN
} else {
elevator_pid->set_kp( ( double ) kp_slider->getValue() );
sprintf( txt, "Kp: %.3f", elevator_pid->get_kp() ); //format label
kp_slider->setLabel( txt ); //BROKEN
}
//cout << "kp_slider" << endl;
} else if ( pob == ki_slider ) { //update ki
if ( val == 0 ) {
aileron_pid->set_ki( ( double ) ki_slider->getValue() );
} else {
elevator_pid->set_ki( ( double ) ki_slider->getValue() );
}
//cout << "ki_slider" << endl;
} else if ( pob == kd_slider ) { //update kd
if ( val == 0 ) {
aileron_pid->set_kd( ( double ) kd_slider->getValue() );
} else {
elevator_pid->set_kd( ( double ) kd_slider->getValue() );
}
//cout << "kd_slider" << endl;
} else if ( pob == target_slider ) { //update reference
if ( val == 0 ) {
aileron_pid->set_reference( ( double ) target_slider->getValue() );
} else {
elevator_pid->set_reference( ( double ) target_slider->getValue() );
}
//cout << "target_slider" << endl;
} else if ( pob == controller_selector ) { //update gui
if ( val == 0 ) {
target_slider->setValue( ( float ) aileron_pid->get_reference() );
kp_slider->setValue( ( float ) aileron_pid->get_kp() );
ki_slider->setValue( ( float ) aileron_pid->get_ki() );
kd_slider->setValue( ( float ) aileron_pid->get_kd() );
} else {
target_slider->setValue( ( float ) elevator_pid->get_reference() );
kp_slider->setValue( ( float ) elevator_pid->get_kp() );
ki_slider->setValue( ( float ) elevator_pid->get_ki() );
kd_slider->setValue( ( float ) elevator_pid->get_kd() );
}
} else {
cout << "Unknown callback to pui_callback" << endl;
}
}
void print_help( void ) {
printf("softSim: a software simulation interface for FlightGear\n\nUsage:\n");
printf(" --help Prints this help message\n");
printf(" --update=x Update rate in Hertz\n");
printf(" --udp-in=x Input read from UDP socket at specified port
(defaults to 5500)\n");
printf(" This is essential, so do not ommit this flag\n");
printf(" --udp-out=x Output to UDP socket at specified port
(defaults to 5501)\n");
printf(" --serial=dev Input read from serial port with specified device\n");
printf(" --baud=x Set serial port baud rate (defaults to 4800)\n");
printf(" --log=file Log to file\n");
}
On Wed, Jun 11, 2008 at 3:49 PM, Fay John F Dr CTR USAF 46 SK
<joh...@eg...> wrote:
> Because I am giving him a private e-mail address to send sample code to.
>
> Sorry ... I didn't mean to sound hush-hush. I will definitely publish
> the fix if and when I find it.
>
> John F. Fay
> Technical Fellow
> Jacobs Technology TEAS Group
> 850-883-1294
>
> -----Original Message-----
> From: pli...@li...
> [mailto:pli...@li...] On Behalf Of M&M
> Sent: Wednesday, June 11, 2008 2:45 PM
> To: PLIB Users
> Subject: Re: [Plib-users] Problem with setLabel, weirdness ensues.
>
> Hi,
>
> Why contact seperately? Why not to the mailing list?
>
> Cheers
>
>
>
>
>
> On Wed, Jun 11, 2008 at 8:30 PM, Fay John F Dr CTR USAF 46 SK
> <joh...@eg...> wrote:
>
>
> Cory,
>
> That is indeed weird. I will contact you separately
> about it.
>
> John F. Fay
> Technical Fellow
> Jacobs Technology TEAS Group
> 850-883-1294
>
>
>
>
> -------------------------------------------------------------------------
> Check out the new SourceForge.net Marketplace.
> It's the best place to buy or sell services for
> just about anything Open Source.
> http://sourceforge.net/services/buy/index.php
> _______________________________________________
> plib-users mailing list
> pli...@li...
> https://lists.sourceforge.net/lists/listinfo/plib-users
>
|