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 > |