Seite 1 von 1
Mein Slot wird nicht aufgerufen...
Verfasst: 8. März 2010 11:30
von Rumbert
Hallo,
innerhalb der run methode eines Threads erzeuge ich einen Timer und verbinde ihn mit einem Slot. Beim debuggen wird im Ausgabefenster nichts angemeckert, aber trotzdem wird der Slot nie aufgerufen.
Code: Alles auswählen
void ThreadClass::run()
{
...
QTimer* o1_curTimer = new QTimer();
while(condition)
{
...
if (NULL != o1_curTimer)
{
connect( o1_curTimer, SIGNAL(timeout()),
this, SLOT(slotMotorCur1()) );
int zahl = 50;
o1_curTimer->start(zahl);
}
...
msleep(2);
...
}// end while
if (NULL!=o1_curTimer)
{
delete(o1_curTimer);
o1_curTimer = NULL;
}
}// end run
void ThreadClass::slotMotorCur1()
{
qDebug() << "Hier!";
}
Er schimpft weder bei der Objekt Erzeugung noch beim connect.
Leider habe ich keine Idee wie ich tiefer debuggen könnte, um zu sehen ob die timeouts emmitiert werden oder wo sie versickern. Hat jemand eine Idee oder sieht den Fehler?
Grüße André
Verfasst: 8. März 2010 11:56
von franzf
Der Code in deiner while-Schleife wird schneller fertig sein als die 50ms die dein timer braucht. Und da du jeden Schleifendurchlauf den timer neu startest hast du gute Karten dass NIE dein timer ein finished() senden wird.
Und warum connectest du jedesmal neu?!? Es reicht doch, die connection VOR der while-Schleife zu erledigen. So lange du in der Schleife keinen Disconnect machst bleibt die connection bestehen.
Verfasst: 8. März 2010 12:12
von Rumbert
Ok ich habe wohl hier zu viel vom Code weggelassen.
In der Schleife arbeite ich Nachrichten aus einer Queue ab, die von nem anderen Thread gefüllt wird. Und wenn ein bestimmte Nachricht aus der Queue abgearbeitet wird, dann wird der gepostete Block ausgeführt.
Ebenso gibt es eine andere Nachricht bei der ich den Timer stoppe und dann die Verbindung disconnecte.
Die Nachricht zum Starten des Timers kommt nur bei einer entsprechenden Nutzerinteraktion. Drum sollte der von dir geschilderte Fall nicht eintreten. Das Connect könnte ich dennoch aus der Schleife ziehen wenn das eleganter ist. Ich dachte, es wäre so sauberer da ich auch an entsprechender Stelle ein disconnect mache.
Verfasst: 8. März 2010 12:20
von RavenIV
Vielleicht solltest Du den gesamten Code zeigen.
Aus dem Fetzen, den Du präsentierst, kann man nichts rauslesen.
Weiterhin kannst Du mit mehr Debug-Ausgaben arbeiten.
Bei mehreren Threads solltest Du diese mit Zeitangaben im Millisekunden-Bereich ausstatten und auch die Thread-ID dazu packen.
Verfasst: 8. März 2010 15:00
von Rumbert
Ok hier etwas mehr Code, alles kann/darf ich nicht posten.
Im Wesentlichen sind in der run Methode noch 10-20 weitere Messages, die in else if Blöcken abgefragt werden und dann bearbeitet werden. Es klappt soweit alles einwandfrei. Lediglich bei der Nachricht "CONFIG_UPDATE" bekam ich nun Probleme.
Eigentlich will ich beim eintreffen dieser Nachricht einen Timer einschalten, der in einem Intervall immer Werte in die OutgoingMessageQeue schreibt. Nur wird leider der Slot nicht aktiv. Wie gesagt so weit funktioniert alles mit den Queues und Threads nur der Timer will nicht.
Code: Alles auswählen
CPP-File
Robot* Robot::_instance = 0;
Robot* Robot::Instance()
{
if (_instance == 0)
{
_instance = new Robot;
}
return _instance;
}
void Robot::Delete()
{
if (_instance != 0)
{
delete _instance;
_instance = 0;
}
}
Robot::Robot()
{
m_theRobbi = new Robot();
mutex.lock();
m_valueConnectionStatus = "Not Connected";
mutex.unlock();
connect( m_theRobbi, SIGNAL (connectionStateChanged(int)),
SLOT ( slotConnectionStateHasChanged(int)) );
m_vx = 0;
m_vy = 0;
m_omega = 0;
counter = 0;
_numMot = 1;
}
Robot::~Robot()
{
delete (m_theRobbi);
m_theRobbi = NULL;
}
bool Robot::connectToRobot(char* ipAdd, int portNumber)
{
Q_UNUSED (portNumber);
emit signalCreateStatusMessage("Trying to connect at IP: " + QString(ipAdd));
m_theRobbi->connectRobotino(ipAdd);
return true;
}
void RobotinoCom::disconnectFromRobot()
{
m_theRobbi->closeConnection();
}
void Robot::run()
{
// do while connected
bool isConnected = false;
mutex.lock();
if (m_valueConnectionStatus == "Connected")
isConnected = true;
else
isConnected = false;
mutex.unlock();
QTimer* o1_curTimer = new QTimer();
while(isConnected)
{
QString message = IncommingMessageQueue::Instance()->processMessageFromQueue();
QString msgName, msgParams;
if (message != "" && message.contains(';'))
{
int pos = message.indexOf(",",0);
if (-1 == pos)
{
// Message contains no parameter
if (!message.endsWith(";"))
{
// Message is corrupt and does not end with ";" !!!
qDebug() << "ERROR ### Fehlerhafte Nachricht";
}
else
{
// delete ";" at the end from the message string
msgName = message.remove(message.size()-1,1);
}
}
else
{
// everything left before the first "," is the message name
msgName = message.left(pos);
// everything between the first "," and the ";" is belongs to the param-list
msgParams = message.right(message.size()-pos-1).remove(QChar(';'));
}
}
if (msgName == "START_MOVE_ARM")
{
QStringList paramList = msgParams.split(",");
for (int i = 0; i < paramList.count(); ++i)
{
if (paramList.at(i)== "omni1")
{
moveAxisNum(0);
}
if (paramList.at(i)== "omni2")
{
moveAxisNum(1);
}
if (paramList.at(i)== "omni3")
{
moveAxisNum(2);
}
if (paramList.at(i)== "stop")
{
stop(0.0);
}
}// END for
OutgoingMessageQueue::Instance()->addMessageToQueue("START_MOVE,ok;");
}// END if START_MOVE_ARM
else if (msgName == "CONFIG_UPDATE")
{
QStringList paramList = msgParams.split(",");
if ((paramList.count()>= 1) && (paramList.at(0) == "sensors"))
{
for (int i = 1; i < paramList.count(); i=i+2)
{
if (paramList.at(i) == "o1_cur")
{
_numMot = 1;
if (paramList.at(i+1)>0)
{
if (NULL != o1_curTimer)
{
connect( o1_curTimer, SIGNAL(timeout()),
this, SLOT(slotUnSolMotorCur1()) );
int zahl = paramList.at(i+1).toInt();
o1_curTimer->start(2);
}
}
else if (paramList.at(i+1)==0)
{
if (NULL != o1_curTimer)
{
o1_curTimer->stop();
disconnect( o1_curTimer, SIGNAL(timeout()),
this, SLOT(slotUnSolMotorCur1()) );
}
}
}
}
OutgoingMessageQueue::Instance()->addMessageToQueue("SENSOR_UPDATE,ok;");
}// END if sensors
}// END if CONFIG_UPDATE
else if (msgName == "GET_VERSION")
{
OutgoingMessageQueue::Instance()->addMessageToQueue("Version 2.1,ROBOT;");
}
msleep(2);
mutex.lock();
if (m_valueConnectionStatus == "Connected")
isConnected = true;
else
isConnected = false;
mutex.unlock();
}
if (NULL!=o1_curTimer)
{
delete(o1_curTimer);
o1_curTimer = NULL;
}
}
void Robot::slotConnectionStateHasChanged(int state)
{
switch( state )
{
case 0: // Com::NotConnected:
mutex.lock();
m_valueConnectionStatus = "Not Connected";
mutex.unlock();
emit signalConnectionStatus(0);
emit signalCreateStatusMessage("Not connected.");
finished();
break;
case 1: // Com::HostLookupState:
mutex.lock();
m_valueConnectionStatus = "Try to connect";
mutex.unlock();
emit signalConnectionStatus(1);
emit signalCreateStatusMessage("Searching Host.");
break;
case 2: // Com::Connecting:
mutex.lock();
m_valueConnectionStatus = "Connecting";
mutex.unlock();
emit signalConnectionStatus(1);
emit signalCreateStatusMessage("Currently connecting.");
break;
case 3: // Com::Connected:
mutex.lock();
m_valueConnectionStatus = "Connected";
mutex.unlock();
emit signalConnectionStatus(2);
emit signalCreateStatusMessage("Is connected.");
start();
break;
case 6: // Com::ClosingState:
mutex.lock();
m_valueConnectionStatus = "Connection going down";
mutex.unlock();
emit signalConnectionStatus(1);
emit signalCreateStatusMessage("Currently disconnecting.");
start();
break;
}
}
QString Robot::getConnectionState()
{
return m_valueConnectionStatus;
}
void Robot::slotUnSolMotorCur1()
{
double cur = static_cast<double>(getMotorCurrent(1));
qDebug() << cur;
OutgoingMessageQueue::Instance()->addMessageToQueue("SENSOR_UPDATE,o1_cur,"+QString::number(cur,'g',3)+";");
}
Code: Alles auswählen
h-File
#ifndef Robot_H
#define Robot_H
#include <QtGui>
const double vMax = 420.0;
class Robot: public QThread
{
Q_OBJECT
public:
static Robot* Instance();
static void Delete();
virtual ~Robot();
void run();
...
QString getConnectionState();
public slots:
void slotConnectionStateHasChanged(int state);
void slotRobotErrorRecived(Com::Error error, const char* errorString);
void slotUnSolMotorCur1();
signals:
void signalConnectionStatus(int i);
void signalCreateStatusMessage(const QString&);
protected:
RobotinoCom();
private:
void updateVelocity();
static Robot* _instance;
Robot* m_theRobbi;
double m_vx, m_vy, m_omega;
QString m_valueConnectionStatus;
QMutex mutex;
int counter;
int _numMot;
};
#endif
Verfasst: 9. März 2010 11:45
von Rumbert
hmm... kann ich irgendwie mit protokollieren ob das TimeOut Signal emittiert wird, ich Tappe irgend wie im Dunkeln herum und habe keine Idee mehr
