1 #include <control.h>
extern "C" {
#include "extApi.h"
}
9 int Control::control( int clientID ) {
//LLAMADA DESDE EJECUTAR ( CONTROL PRINCIPAL )
return 0;
}
15 int Control::interrupt_1( int clientID ){
//LLAMADA DESDE BOTON DE INTERRUPCION 1
return 0;
}
21 int Control::interrupt_2( int clientID ){
//LLAMADA DESDE BOTON DE INTERRUPCION 2
return 0;
}
27 int Control::interrupt_3( int clientID ){
//LLAMADA DESDE BOTON DE INTERRUPCION 3
return 0;
}
33 int Control::interrupt_4( int clientID ){
//LLAMADA DESDE BOTON DE INTERRUPCION 4
return 0;
}
1 //Definición de Clase Plantilla de Código de Control ( puede ser cualquiera con tal de que implemente I_control )
#ifndef CONTROL_H
#define CONTROL_H
#include <i_control.h>
//La clase implementa la "interfaz" ( clase abstracta ) i_control
7 class Control: public I_Control
{
public:
10 int control( int clientID );
11 int interrupt_1( int clientID );
12 int interrupt_2( int clientID );
13 int interrupt_3( int clientID );
14 int interrupt_4( int clientID );
};
#endif // CONTROL_H
1 //Clase Ejemplo de Código Usuario. Ver Documentación de Remote Api para entender funciones.
#include <demo.h>
#include <sstream>
#include <math.h>
extern "C" {
#include "extApi.h"
}
using namespace std;
11 int Demo::control( int clientID ) {
cout << "Demo: Inicio de Control\n";
int leftMotorHandle;
int rightMotorHandle;
int leftMotorHandle0;
int rightMotorHandle0;
//genera un handle para los motores de khepera y khepera#0 y de los objetos robot en sí.
simxGetObjectHandle( clientID, "K3_rightWheelMotor#", &rightMotorHandle, simx_opmode_oneshot_wait );
simxGetObjectHandle( clientID, "K3_leftWheelMotor#", &leftMotorHandle, simx_opmode_oneshot_wait );
simxGetObjectHandle( clientID, "K3_rightWheelMotor#0", &rightMotorHandle0, simx_opmode_oneshot_wait );
simxGetObjectHandle( clientID, "K3_leftWheelMotor#0", &leftMotorHandle0, simx_opmode_oneshot_wait );
while ( simxGetConnectionId( clientID )!=-1 )
{
//mover khepera
simxSetJointTargetVelocity( clientID, leftMotorHandle, 2*pi, simx_opmode_oneshot );
simxSetJointTargetVelocity( clientID, rightMotorHandle, 2*pi, simx_opmode_oneshot );
//mover khepera#0
simxSetJointTargetVelocity( clientID, leftMotorHandle0, pi, simx_opmode_oneshot );
simxSetJointTargetVelocity( clientID, rightMotorHandle0, pi, simx_opmode_oneshot );
}
cout << "Demo: Control abortado\n";
return 0;
}
//adelante
42 int Demo::interrupt_1( int clientID ){
int leftMotorHandle;
int rightMotorHandle;
float velocidad = this->velocidad;
cout << "Demo: Adelante v: " << velocidad << "\n";
simxGetObjectHandle( clientID, rightmotor.c_str( ), &rightMotorHandle, simx_opmode_oneshot_wait );
simxGetObjectHandle( clientID, leftmotor.c_str( ), &leftMotorHandle, simx_opmode_oneshot_wait );
while ( simxGetConnectionId( clientID )!=-1 ) {
simxSetJointTargetVelocity( clientID, leftMotorHandle, velocidad, simx_opmode_oneshot );
simxSetJointTargetVelocity( clientID, rightMotorHandle, velocidad, simx_opmode_oneshot );
}
return 0;
}
//marcha atrás
60 int Demo::interrupt_2( int clientID ){
int leftMotorHandle;
int rightMotorHandle;
float velocidad = this->velocidad;
cout << "Demo: Marcha atrás v: " << velocidad << "\n";
simxGetObjectHandle( clientID, rightmotor.c_str( ), &rightMotorHandle, simx_opmode_oneshot_wait );
simxGetObjectHandle( clientID, leftmotor.c_str( ), &leftMotorHandle, simx_opmode_oneshot_wait );
while ( simxGetConnectionId( clientID )!=-1 ) {
simxSetJointTargetVelocity( clientID, leftMotorHandle, -velocidad, simx_opmode_oneshot );
simxSetJointTargetVelocity( clientID, rightMotorHandle, -velocidad, simx_opmode_oneshot );
}
return 0;
}
//giro izquierda
78 int Demo::interrupt_3( int clientID ){
int leftMotorHandle;
int rightMotorHandle;
float angulos[3]={0, 0, 0};
float alfa =0;
float anterior=0;
float angulo=0;
float velocidad = this->velocidad;
simxGetObjectHandle( clientID, rightmotor.c_str( ), &rightMotorHandle, simx_opmode_oneshot_wait );
simxGetObjectHandle( clientID, leftmotor.c_str( ), &leftMotorHandle, simx_opmode_oneshot_wait );
//para girar 90º, obtiene la orientación ( angulos de euler con respecto a los ejes absolutos ).
simxGetObjectOrientation( clientID, leftMotorHandle, -1, angulos, simx_opmode_oneshot_wait );
//alfa es el angulo beta inicial.
alfa=angulos[1];
//anterior es necesario para calcular el incremento de angulo ( debido al sistema angular de vrep: 0->90->0->-90->0 )
anterior=alfa;
//angulo es el angulo actual en coordenadas radiales.
angulo=alfa;
while ( simxGetConnectionId( clientID )!=-1 ) {
//calculo angulo nuevo con la diferencia del dado por vrep y el anterior dado por vrep ( incremento ).
simxGetObjectOrientation( clientID, leftMotorHandle, -1, angulos, simx_opmode_oneshot );
angulo= angulo+fabs( angulos[1]-anterior );
//si el angulo actual está mas allá de 90º del inicial, giro completo. Si no, sigue girando.
if ( angulo<alfa+pi/2 ) {
simxSetJointTargetVelocity( clientID, leftMotorHandle, 0, simx_opmode_oneshot );
simxSetJointTargetVelocity( clientID, rightMotorHandle, velocidad, simx_opmode_oneshot );
} else {
simxSetJointTargetVelocity( clientID, leftMotorHandle, velocidad, simx_opmode_oneshot );
simxSetJointTargetVelocity( clientID, rightMotorHandle, velocidad, simx_opmode_oneshot );
}
anterior=angulos[1];
}
return 0;
}
//giro derecha ( ídem giro izquierda ).
119 int Demo::interrupt_4( int clientID ){
int leftMotorHandle;
int rightMotorHandle;
float angulos[3]={0, 0, 0};
float alfa =0;
float anterior=0;
float angulo=0;
float velocidad = this->velocidad;
cout << "Demo: Giro Der. v: " << velocidad << "\n";
simxGetObjectHandle( clientID, rightmotor.c_str( ), &rightMotorHandle, simx_opmode_oneshot_wait );
simxGetObjectHandle( clientID, leftmotor.c_str( ), &leftMotorHandle, simx_opmode_oneshot_wait );
//para girar a la
simxGetObjectOrientation( clientID, rightMotorHandle, -1, angulos, simx_opmode_oneshot_wait );
alfa=angulos[1];
anterior=alfa;
angulo=alfa;
while ( simxGetConnectionId( clientID )!=-1 ) {
simxGetObjectOrientation( clientID, leftMotorHandle, -1, angulos, simx_opmode_oneshot );
angulo= angulo-fabs( angulos[1]-anterior );
if ( angulo>alfa-pi/2 ) {
simxSetJointTargetVelocity( clientID, leftMotorHandle, velocidad, simx_opmode_oneshot );
simxSetJointTargetVelocity( clientID, rightMotorHandle, 0, simx_opmode_oneshot );
} else {
simxSetJointTargetVelocity( clientID, leftMotorHandle, velocidad, simx_opmode_oneshot );
simxSetJointTargetVelocity( clientID, rightMotorHandle, velocidad, simx_opmode_oneshot );
}
anterior=angulos[1];
}
return 0;
}
//adjunta el índice del robot al label de vrep, para identificar que robot "interrumpir".
//permitir robots con nombre personalizado es posible, pero resulta mas trabajoso de lo que reporta al usuario, por tanto no se incluye en la demo.
155 void Demo::setRobot( int indice_robot ) {
if ( indice_robot>0 ) {
std::ostringstream sstr;
sstr << "K3_leftWheelMotor#" << indice_robot -1;
leftmotor = sstr.str( );
sstr.str( "" );
sstr.clear( );
sstr << "K3_rightWheelMotor#" << indice_robot -1;
rightmotor = sstr.str( );
} else {
leftmotor = "K3_leftWheelMotor#";
rightmotor = "K3_rightWheelMotor#";
}
}
//establece la velocidad ( multiplo de pi ) con el argumento dado.
172 void Demo::setVelocidad( int multiplicador ) {
velocidad=multiplicador*pi;
}
1 //Definicion Clase Ejemplo de Código Usuario.
#ifndef DEMO_H
#define DEMO_H
#include <i_control.h>
//La clase implementa la "interfaz" ( clase abstracta ) i_control
7 class Demo: public I_Control
{
public:
10 int control( int clientID );
11 int interrupt_1( int clientID );
12 int interrupt_2( int clientID );
13 int interrupt_3( int clientID );
14 int interrupt_4( int clientID );
//establece el nombre del robot a controlar con las interrupciones demo.
16 void setRobot ( int indice_robot );
//establece la velocidad de los motores en las interrupciones demo.
18 void setVelocidad ( int multiplicador );
private:
20 std::string leftmotor = "K3_leftWheelMotor#";
21 std::string rightmotor = "K3_rightWheelMotor#";
const float pi=3.141592;
float velocidad = pi;
};
#endif // DEMO_H
1 //"Interfaz" ( clase abstracta ) que debe implementar la clase de código cliente
//Ver clase ejemplo en Demo.
#ifndef I_CONTROL_H
#define I_CONTROL_H
9 class I_Control
{
public:
12 virtual int control( int clientID ) = 0; //Método virtual puro, debe sobrecargarse con el contenido de Control.
13 virtual int interrupt_1( int clientID ) = 0; //Métodos virtuales puros, debe sobrecargarse con el contenido de interrupciones.
14 virtual int interrupt_2( int clientID ) = 0; //( normalmente adelante, atras, izq y der, respectivamente ).
15 virtual int interrupt_3( int clientID ) = 0;
16 virtual int interrupt_4( int clientID ) = 0;
};
#endif
1 #include "kheperasimgui.h"
#include "ui_kheperasimgui.h"
#include <thread>
#include <QMessageBox>
#include <QTimer>
#include <QInputDialog>
#include <iostream>
#include <i_control.h>
#include "control.cpp"
#include "demo.cpp"
#include <QTextStream>
#include <QScrollBar>
#include <QUrl>
#include <QDesktopServices>
extern "C" {
#include "extApi.h"
}
using namespace std;
//Constructor del objeto GUI
21 KheperaSimGUI::KheperaSimGUI( QWidget *parent ) :
QMainWindow( parent ),
ui( new Ui::KheperaSimGUI )
{
ui->setupUi( this );
log = freopen ( "log", "w", stdout );
//Define un temporizador que ejecutar refrescar_datos( ) cada 150ms
QTimer *timer = new QTimer( this );
connect( timer, SIGNAL( timeout( ) ), this, SLOT( refrescar_datos( ) ) );
//inicia el temporizador
timer->start( 150 );
}
//Destructor del objeto GUI
36 KheperaSimGUI::~KheperaSimGUI( )
{
delete ui;
}
//Abre una conexión con V-REP ( puerto por defecto 19997 ), Inicia la simulacion y cierra la conexión.
43 void KheperaSimGUI::iniciar_sim( string ip ){
//Comprueba que no haya una conexión ya abierta antes de conectar.
if ( simxGetConnectionId( clientIDsim )==-1 ){
clientIDsim=simxStart( ( simxChar* ) ip.c_str( ), 19997, true, true, 2000, 5 );
}
//Comprueba que se haya realizado la conexión con éxito. Si no, muestra error.
if ( clientIDsim!=-1 )
{
simxStartSimulation( clientIDsim, simx_opmode_oneshot_wait );
simxFinish( clientIDsim );
ui->pausar->setEnabled( true );
cout << "Gui: Simulación iniciada\n";
} else {
cout << "Error: Imposible iniciar simulación remotamente. ( Pulsar Play en V-REP y volver a intentar )\n";
QMessageBox error;
error.setText( "Error: Imposible iniciar simulación remotamente. ( Pulsar Play en V-REP y volver a intentar )" );
error.exec( );
}
}
//Abre una conexión con la escena V-REP, en la IP y puerto dado.
65 int KheperaSimGUI::conectar( string ip, int puerto ){
clientIDexe=simxStart( ( simxChar* ) ip.c_str( ), puerto, true, true, 2000, 5 );
//Comprueba la conexión, si ha fallado, muestra error.
if ( simxGetConnectionId( clientIDexe )==-1 ) {
cout << "Error: Imposible conectar con el servidor. Asegúrese de que el puerto es correcto ( " << ui->puertotexto->text( ).toInt( ) <<" )\n";
cout << "Debe ejecutar un proceso servidor en el Host Simulador, normalmente con una llamada a\n";
cout << "simExtRemoteApiStart( puerto ) en un Child Script de Lua.\n";
cout << "Ver código de control demo y escena demo2khepera.ttt\n";
QMessageBox error;
error.setText( "Error: Imposible conectar con el servidor" );
error.exec( );
}
return clientIDexe;
}
//crea y lanza un thread ( hilo ) con el metodo pedido, para permitir funcionamiento concurrente.
83 void KheperaSimGUI::codigo_en_hilo( ptrfunc ptrfuncion )
{
if ( ui->demoset->isChecked( ) ){
std::thread hilo( ptrfuncion, &demo, clientIDexe );
//el hilo continua ejecutándose hasta que retorna la función hilo ( el hilo padre se "desprende" del hijo )
hilo.detach( );
} else {
std::thread hilo( ptrfuncion, &control, clientIDexe );
hilo.detach( );
}
}
//refresca los datos de posición y velocidad de la gui. La invoca el timer creado en el constructor de la GUI.
96 void KheperaSimGUI::refrescar_datos( )
{ //Comprueba que haya una conexión. Si la hay, obtiene los datos. ( Ver Doc. Remote API para entender funciones )
if ( simxGetConnectionId( clientIDexe )!=-1 ) {
int robotHandle;
//indica de que robot se representarán los datos, segun el combobox de selección.
string robot = ui->comboBox_2->currentText( ).toUtf8( ).constData( );
simxGetObjectHandle( clientIDexe, robot.c_str( ), &robotHandle, simx_opmode_oneshot_wait );
simxGetObjectPosition( clientIDexe, robotHandle, -1, position, simx_opmode_oneshot );
simxGetObjectVelocity( clientIDexe, robotHandle, velocidad, NULL, simx_opmode_oneshot );
} else {
//Si no hay conexión, pone a 0 los valores.
for ( int i = 0; i<3; i++ ){
position[i]=0;
velocidad[i]=0;
}
}
//actualiza los "LCD" de la GUI
ui->xlcd->display( position[0] );
ui->ylcd->display( position[1] );
ui->zlcd->display( position[2] );
ui->vxlcd->display( velocidad[0] );
ui->vylcd->display( velocidad[1] );
ui->vzlcd->display( velocidad[2] );
//Muestra el contenido del archivo log en el textEdit. Solo si "mostrar output" está selecc.
if ( ui->actionMostrar_Output->isChecked( ) ) {
fclose( log );
log = fopen( "log", "r" );
QTextStream stream( log );
QString str = stream.readAll( );
ui->textEdit->setText( str );
QScrollBar *sb = ui->textEdit->verticalScrollBar( );
sb->setValue( sb->maximum( ) );
fclose( log );
//redirecciona stdout al archivo log. ver página man de freopen.
log = freopen ( "log", "a", stdout );
}
}
//código de evento: pulsar botón ejecutar.
137 void KheperaSimGUI::on_ejecutar_clicked( )
{ //define la IP y puerto desde los textbox.
ip = ui->iptexto->text( ).toUtf8( ).constData( );
puerto = ui->puertotexto->text( ).toInt( );
//si está marcada la opción de Inicio remoto, inicia la sim. remotamente.
if( ui->inicioremotoset->isChecked( ) ){
iniciar_sim( ip );
}
//cierra cualquier conexión de control/interrupcion que haya.
simxFinish( clientIDexe );
//conecta y ejecuta el código de control ( Demo ó Control ) en un hilo independiente.
if ( conectar( ip, puerto ) != -1 ) {
ptrfunc ptrfuncion = &I_Control::control;
codigo_en_hilo( ptrfuncion );
cout << "Gui: Control ejecutado\n";
}
}
//código de evento: pulsar botón iniciar simulación.
157 void KheperaSimGUI::on_sim_clicked( )
{
ip = ui->iptexto->text( ).toUtf8( ).constData( );
puerto = ui->puertotexto->text( ).toInt( );
iniciar_sim( ip );
}
//código de evento: pulsar botón parar simulación.
165 void KheperaSimGUI::on_parar_clicked( )
{
//abre una conexión en el puerto por defecto, para la simulación y cierra la conexión.
clientIDsim=simxStart( ( simxChar* ) ip.c_str( ), 19997, true, true, 2000, 5 );
simxStopSimulation( clientIDsim, simx_opmode_oneshot_wait );
simxFinish( clientIDsim );
cout << "Gui: Simulación parada\n";
ui->pausar->setText( "Pausar Sim." );
ui->pausar->setEnabled( false );
}
//código de evento: pulsar boton pausar/reanudar sim.
177 void KheperaSimGUI::on_pausar_clicked( )
{ //obtiene el estado actual del botón: Pausar/Reanudar.
string texto = ui->pausar->text( ).toUtf8( ).constData( );
//abre una conexión en el puerto por defecto.
clientIDsim=simxStart( ( simxChar* ) ip.c_str( ), 19997, true, true, 2000, 5 );
//si tiene que pausar, pausa, y se pone en estado reanudar. Ídem al contrario.
if ( !texto.compare( "Pausar Sim." ) ) {
simxPauseSimulation( clientIDsim, simx_opmode_oneshot_wait );
cout << "Gui: Simulación pausada\n";
ui->pausar->setText( "Reanud Sim." );
} else {
simxStartSimulation( clientIDsim, simx_opmode_oneshot_wait );
cout << "Gui: Simulación reanudada\n";
ui->pausar->setText( "Pausar Sim." );
}
//cierra la conexión en puerto por defecto.
simxFinish( clientIDsim );
}
//código de evento: pulsar botón de interrupt X.
198 void KheperaSimGUI::on_interrupt1_clicked( )
{ //cierra cualquier conexión de control/interrupcion que exista, conecta
//y ejecuta el código de interrupción ( Demo ó Control ) en un hilo independiente.
simxFinish( clientIDexe );
if ( conectar( ip, puerto ) != -1 ) {
//crea un puntero a metodo miembro con el metodo seleccionado.
ptrfunc ptrfuncion = &I_Control::interrupt_1;
//ejecuta el metodo seleccionado en un hilo.
codigo_en_hilo( ptrfuncion );
}
}
210 void KheperaSimGUI::on_interrupt2_clicked( )
{
simxFinish( clientIDexe );
if ( conectar( ip, puerto ) != -1 ) {
ptrfunc ptrfuncion = &I_Control::interrupt_2;
codigo_en_hilo( ptrfuncion );
}
}
220 void KheperaSimGUI::on_interrupt3_clicked( )
{
simxFinish( clientIDexe );
if ( conectar( ip, puerto ) != -1 ) {
ptrfunc ptrfuncion = &I_Control::interrupt_3;
codigo_en_hilo( ptrfuncion );
}
}
228 void KheperaSimGUI::on_interrupt4_clicked( )
{
simxFinish( clientIDexe );
if ( conectar( ip, puerto ) != -1 ) {
ptrfunc ptrfuncion = &I_Control::interrupt_4;
codigo_en_hilo( ptrfuncion );
}
}
//código de evento: selección de nombre de robot para mostrar sus datos.
237 void KheperaSimGUI::on_comboBox_2_activated( QString robottexto )
{ //Si se selecciona Personalizado, abre un dialogo para introducir un nuevo nombre.
if ( !robottexto.compare( "Personalizado..." ) ){
QString nombrerobot = QInputDialog::getText( this, tr( "Nombre Nuevo" ), tr( "Nombre robot:" ) );
//Comprueba que no se canceló el dialogo, añade la nueva opción a la lista y la selecciona.
if ( nombrerobot!=NULL ) {
ui->comboBox_2->insertItem( 0, nombrerobot );
ui->comboBox_2->setCurrentIndex( 0 );
}
} else if ( !robottexto.compare( "Añadir" ) ){
std::ostringstream sstr;
sstr << "K3_robot#" << ui->comboBox_2->count( ) -3;
QString str = QString::fromStdString( sstr.str( ) );
ui->comboBox_2->insertItem( ui->comboBox_2->count( )-2, str );
ui->comboBox_2->setCurrentIndex( ui->comboBox_2->count( )-3 );
}
}
//cambia los nombres de los botones de interrupcion al modo Control.
256 void KheperaSimGUI::on_controlset_clicked( )
{
ui->interrupt1->setText( "Interrupt 1" );
ui->interrupt2->setText( "Interrupt 2" );
ui->interrupt3->setText( "Interrupt 3" );
ui->interrupt4->setText( "Interrupt 4" );
ui->comboBox_3->setEnabled( false );
ui->label_13->setEnabled( false );
ui->comboBox->setEnabled( false );
}
//revierte los botones de interrupcion al modo demo.
267 void KheperaSimGUI::on_demoset_clicked( )
{
ui->interrupt1->setText( "Adelante" );
ui->interrupt2->setText( "Atrás" );
ui->interrupt3->setText( "Izquierda" );
ui->interrupt4->setText( "Derecha" );
ui->comboBox_3->setEnabled( true );
ui->label_13->setEnabled( true );
ui->comboBox->setEnabled( true );
}
//permite cambiar el robot al que se envian las interrupciones. Solo modo demo.( En modo control el usuario puede elegir con su código cualquier robot/acción )
278 void KheperaSimGUI::on_comboBox_3_activated( const QString a )
{ string texto = a.toUtf8( ).constData( );
if ( !texto.compare( "Añadir" ) ){
std::ostringstream sstr;
sstr << "K3_robot#" << ui->comboBox_3->count( ) -2;
QString str = QString::fromStdString( sstr.str( ) );
ui->comboBox_3->insertItem( ui->comboBox_3->count( )-1, str );
ui->comboBox_3->setCurrentIndex( ui->comboBox_3->count( )-2 );
}
demo.setRobot( ui->comboBox_3->currentIndex( ) );
}
//permite cambiar la velocidad de los motores en las interrupciones. Solo modo Demo. Advierte que el robot se desestabiliza para altas velocidades.
291 void KheperaSimGUI::on_comboBox_activated( int index )
{ //comprueba velocidad > 2x y que no se ha especificado que no se muestre la advertencia.
if ( index>1 && !nomostrarwarning ){
QMessageBox warning;
QCheckBox nomostrar;
nomostrar.setText( "No volver a mostrar" );
warning.setText( "Para V > 2x, el control no asegura la estabilidad del robot" );
warning.setCheckBox( &nomostrar );
warning.exec( );
if ( warning.checkBox( )->isChecked( ) ){
nomostrarwarning = true;
}
}
demo.setVelocidad( index+1 );
}
//codigo de cierre por menú
307 void KheperaSimGUI::on_actionSalir_triggered( )
{
fclose( log );
exit( 0 );
}
//muestra el output ( hace la ventana mas grande ) o lo oculta ( ventana mas pequeña )
313 void KheperaSimGUI::on_actionMostrar_Output_toggled( bool arg1 )
{
if ( arg1 ) {
setFixedSize( 450, 410 );
} else {
setFixedSize( 450, 275 );
}
}
//código de cierre por pulsar X en ventana.
322 void KheperaSimGUI::closeEvent( QCloseEvent *bar ) {
fclose( log );
}
328 void KheperaSimGUI::on_actionAyuda_triggered( )
{
QDesktopServices::openUrl( QUrl( "http://xpeiro.github.io/compu3/" ) );
}
//Definición de la clase de la Interfaz Gráfica.
#ifndef KHEPERASIMGUI_H
#define KHEPERASIMGUI_H
#include <QMainWindow>
#include <demo.h>
#include <control.h>
#include <i_control.h>
#include <stdio.h>
namespace Ui {
12 class KheperaSimGUI;
}
15 class KheperaSimGUI : public QMainWindow
{
Q_OBJECT
public:
21 explicit KheperaSimGUI( QWidget *parent = 0 );
22 ~KheperaSimGUI( );
23 typedef int ( I_Control::* ptrfunc ) ( int );
25 private slots:
//inicia la simulación remotamente ( IP:parámetro. Puerto: 19997, predeterminado de V-REP )
void iniciar_sim( std::string ip );
//abre una conexión remota nueva en la ip y puerto dada
29 int conectar( std::string ip, int puerto );
//ejecuta la función hilo como un thread y lo desvincula del padre-> detach( ).
31 void codigo_en_hilo( KheperaSimGUI::ptrfunc ptrfuncion );
//muestra los datos de posicion y velocidad en la GUI.
33 void refrescar_datos( );
//Slots/Métodos que se cargan en los eventos definidos por sus nombres.
35 void on_ejecutar_clicked( );
37 void on_sim_clicked( );
39 void on_parar_clicked( );
41 void on_pausar_clicked( );
43 void on_interrupt1_clicked( );
45 void on_interrupt2_clicked( );
47 void on_interrupt3_clicked( );
49 void on_interrupt4_clicked( );
51 void on_controlset_clicked( );
53 void on_demoset_clicked( );
55 void on_comboBox_2_activated( QString robottexto );
57 void on_comboBox_3_activated( const QString a );
59 void on_comboBox_activated( int index );
61 void on_actionSalir_triggered( );
63 void on_actionMostrar_Output_toggled( bool arg1 );
65 void closeEvent( QCloseEvent *bar );
67 void on_actionAyuda_triggered( );
private:
Ui::KheperaSimGUI *ui;
//Handle/identificador usado para conexiones de señales de manejo de simulación ( Iniciar, Parar, Pausar/Reanudar )
//Usa siempre el puerto 19997, inicializado por defecto en V-REP
int clientIDsim=-1;
//Handle/identificador usado para conexiones de señales de control/interrupcion.
//Usa el puerto definido por el usuario ( debe abrirse manualmente con un Script Lua. Ver modelo Khepera incluido ).
int clientIDexe=-1;
//IP del Host Simulador. Localhost por defecto.
std::string ip="127.0.0.1";
//Puerto de escucha. Debe configurarse en un Script Lua. Ver modelo Khepera incluido.
int puerto=20001;
// buffer de coordenadas de posición.
float position[3];
// buffer de módulos de velocidad ( lineal ).
float velocidad[3];
//toggle de la advertencia de velocidad excesiva.
bool nomostrarwarning =false;
FILE * log;
Demo demo;
Control control;
};
#endif // KHEPERASIMGUI_H
1 #include "kheperasimgui.h"
#include <QApplication>
4 int main( int argc, char *argv[] )
{ //Instancia la GUI
QApplication a( argc, argv );
KheperaSimGUI w;
//muestra la GUI
w.show( );
//Fija el tamaño de la ventana.
w.setFixedSize( 450, 275 );
return a.exec( );
}