Пример #1
0
bool CWindowListener::OnRButtonUp( guint32 nFlags, double x, double y ){
	if ( CanProcess() ) {
		g_2DView.OnRButtonUp( (int)x, (int)y );
		return true;
	}
	return false;
}
Пример #2
0
bool CWindowListener::OnLButtonUp( guint32 nFlags, double x, double y ){
	if ( CanProcess() ) {
		g_pManager->OnLButtonUp( (int)x, (int)y );
		return true;
	}
	return false;
}
Пример #3
0
static gint keypress (GtkWidget* widget, GdkEventKey* event, gpointer data)
{
  unsigned int code = gdk_keyval_to_upper(event->keyval);

  if (code == GDK_Escape)
  {
    gtk_widget_destroy (g_pToolWnd);
    g_pToolWnd = NULL;
    return TRUE;
  }

  if (CanProcess ())
  {
    if (g_2DView.OnKeyDown (code))
      return FALSE;

    if (code == GDK_Return)
    {
      Textool_Validate();
      return FALSE;
    }
  }

  return TRUE;
}
Пример #4
0
static gint expose (GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
  if (event->count > 0)
    return TRUE;

  if (!CanProcess ())
    return TRUE;

  if (g_bTexViewReady)
  {
    g_2DView.m_rect.bottom = widget->allocation.height;
    g_2DView.m_rect.right = widget->allocation.width;

    if (!g_QglTable.m_pfn_glwidget_make_current (g_pToolWidget))
    {
      Sys_Printf("TexTool: glMakeCurrent failed\n");
      return TRUE;
    }

    DoExpose ();

    g_QglTable.m_pfn_glwidget_swap_buffers (g_pToolWidget);
  }

  return TRUE;
}
Пример #5
0
static void DoPaint ()
{
  if (!CanProcess ())
    return;
  
  if (g_bTexViewReady)
  {
    g_2DView.m_rect.bottom = g_pToolWnd->getHeight();
    g_2DView.m_rect.right = g_pToolWnd->getWidth();
    
    // set GL_PROJECTION
    g_2DView.PreparePaint();
    // render the objects
    // the master is not rendered the same way, draw over a unified texture background
    g_2DView.TextureBackground(g_DrawObjects[0].pObject->getTextureNumber());
    if (g_nDrawObjects >= 1)
    {
      int i;
      for (i=1;i<g_nDrawObjects;i++)
      {
        // we use a first step to the GL_MODELVIEW for the master object
        // GL_MODELVIEW will be altered in RenderAuxiliary too
        g_DrawObjects[0].pObject->PrepareModelView(g_DrawObjects[i].pTopo);
        g_DrawObjects[i].pObject->RenderAuxiliary();
      }
    }
    // draw the polygon outline and control points
    g_DrawObjects[0].pObject->PrepareModelView(NULL);
    g_DrawObjects[0].pObject->RenderUI();
  }
}
Пример #6
0
/// \brief		Verify whether the intended position was achieved
/// \details	The MCDC position notify command returns the character 'p' when the position is achieved
///	\pre		A corresponding call to SetPosition() was made along with the notify parameter set to true
///	\post		Boolean value returned indicating whether or not the position, set in SetPosition(), has been reached
bool MotionController::IsPositionVerified(long timeOut)
{
    bool success = false;

    if( FAILED(CanProcess()) )
    {
        return false;
    }

    if(m_posNotifyCounter < 1)
    {
        qDebug() << "MotionController : m_posNotifyCounter=" << m_posNotifyCounter;
        throw MotionControllerException("Position verified counter out of sync");
    }

    // If DEBUG_NO_ROBOT is defined as a preprocessor definition DO NOT call ReadCharsAndCompare() method
    // as there are no characters to receive (just set to true).
    bool equal = true;
#ifndef DEBUG_NO_ROBOT
    equal = ReadCharsAndCompare("p\r\n", timeOut);
#endif

    if( equal )
    {
        success = true;
        --m_posNotifyCounter;
        m_currentState = Verified;
    }

    return success;
}
Пример #7
0
/// \brief		Set corridor window
/// \details	Uses the 'CORRIDOR' command to set the corridor window. Notifcation for position/velocity
///				will be sent whenever the motor enters inside the corridor window (i.e. speeds up or slows down
///				notification). This functionality greatly speeds up the maximum bandwidth of the vibration motor
///	\pre		MCDC is still connected on the given COM port
///	\post		Corridor value is set for the particular MCDC
void MotionController::SetCorridorValue(int corridor)
{
    if( FAILED(CanProcess()) ) return;

    m_command = QString("%1CORRIDOR%2\r").arg(DEVICE_ID,corridor);
    m_serial.Write(m_command.toStdString().c_str());
}
Пример #8
0
/// \brief		Starts the motor homing sequence
/// \details	The motor moves until a limit switch is hit, at which point the position is set to zero
///	\pre		The homing velocity and limit behaviors have been previously saved in the MCDC
///	\post		The motor is stopped and position is set to 0
void MotionController::HomingSequence(void)
{
    if( FAILED(CanProcess()) ) throw MotionControllerException("Cannot perform homing");;
    // Construct the string to send with both the LA and the M commands embedded in a single transmission
    m_command = QString("%1GOHOSEQ\r").arg(DEVICE_ID);
    m_serial.Write(m_command.toStdString().c_str());

    m_currentState = Stopped;
}
Пример #9
0
/// \brief		Set position limits on MCDC device
/// \details	Uses the 'LL' command to set the minimum and maximum encoder values that the
///				motor can travel. To enable or disable the limits call enablePositionLimits().
///	\pre		MCDC is still connected on the given COM port
///	\post		Position limits enforced or removed depending on the boolean value of enable
void MotionController::SetPositionLimits(int min, int max)
{
    if( FAILED(CanProcess()) ) return;

    m_command = QString("%1LL%2\r").arg(DEVICE_ID,min);
    m_serial.Write(m_command.toStdString().c_str());

    m_command = QString("%1LL%2\r").arg(DEVICE_ID,max);
    m_serial.Write(m_command.toStdString().c_str());
}
Пример #10
0
bool CWindowListener::Paint()
{
  if (!CanProcess ())
    return false;

  if (g_bTexViewReady)
    DoExpose();

  return true;
}
Пример #11
0
/// \brief	Change the maximum motor velocity that the motor can spin at
/// \pre	MCDC is still connected on the given COM port
/// \post	MCDC internal mac velocity parameter is set to maxspeed
bool MotionController::ChangeMaxMotorVelocity(int maxSpeed)
{
    if( FAILED(CanProcess()) ) return false;

    //Tell MCDC to change the maximum speed of travel to the given speed param
    m_command = QString("%1SP%2\r").arg(DEVICE_ID).arg(maxSpeed);
    m_serial.Write(m_command.toStdString().c_str());

    return true;
}
Пример #12
0
HRESULT CSerialCommHelper::Read_Upto (std::string& data,char chTerminator ,long* Count,long TimeOut)
{
	HRESULT hr = CanProcess();
	if ( FAILED(hr)) return hr;

	MTXDBG(CRITICAL,_("CSerialCommHelper : CSerialCommHelper: Read_Upto called "));
	try
	{
		std::string Tmp;
		Tmp.erase ();
		long BytesRead;

		bool Found =  SerialBuffer.Read_Upto(Tmp ,chTerminator,BytesRead,DataRx );

		if ( Found ) 
		{
			data = Tmp ;
		}
		else
		{//there are either none or less bytes...
			long iRead = 0;
			bool condition =  true;
			while (  condition )
			{
				MTXDBG(CRITICAL,_("CSerialCommHelper : CSerialCommHelper : Read_Upto () making blocking read cl  "));
				DWORD Wait  = ::WaitForSingleObject ( DataRx , TimeOut ) ;

				if  ( Wait == WAIT_TIMEOUT) 
				{
					MTXDBG(CRITICAL,_("CSerialCommHelper : CSerialCommHelper : Read_Upto () timed out in blocking read"));
					data.erase ();
					hr = E_FAIL;
					return hr;

				}

				bool Found =  SerialBuffer.Read_Upto(Tmp ,chTerminator,BytesRead,DataRx );
				if ( Found ) 
				{
					data = Tmp;
					MTXDBG(CRITICAL,_("CSerialCommHelper : CSerialCommHelper: Read_Upto WaitForSingleObject  data:{%s}len:{%d}"),((Tmp)).c_str(),Tmp.size ());
					return S_OK;
				}
				MTXDBG(CRITICAL,("CSerialCommHelper : CSerialCommHelper: Read_Upto WaitForSingleObject  not FOUND "));

			}
		}
	}
	catch(...)
	{
		MTXDBG(CRITICAL,_("CSerialCommHelperUnhandled exception"));
		g_assert ( 0  ) ;
	}
	return hr;
}
Пример #13
0
bool CWindowListener::OnMouseMove( guint32 nFlags, double x, double y ){
	if ( CanProcess() ) {
		if ( g_2DView.OnMouseMove( (int)x, (int)y ) ) {
			return true;
		}

		g_pManager->OnMouseMove( (int)x, (int)y );
		return true;
	}
	return false;
}
Пример #14
0
static void motion (GtkWidget *widget, GdkEventMotion *event, gpointer data)
{
  if (CanProcess ())
  {
    if (g_2DView.OnMouseMove (event->x, event->y))
      return;

    if (g_pManager->OnMouseMove (event->x, event->y))
      return;
  }
}
Пример #15
0
static void button_release( GtkWidget *widget, GdkEventButton *event, gpointer data ){
	if ( CanProcess() ) {
		switch ( event->button )
		{
		case 1:
			g_pManager->OnLButtonUp( event->x, event->y ); break;
		case 3:
			g_2DView.OnRButtonUp( event->x, event->y ); break;
		}
	}
}
Пример #16
0
/// \brief		Clear any data on the serial port
///	\pre		none
///	\post		Any data waiting to be read on the com port is discarded
void MotionController::ClearExistingData(void)
{
    if( FAILED(CanProcess()) )
    {
        throw MotionControllerException("Cannot clear data due to motion controller state");
    }

    if( m_serial.Purge() != S_OK )
    {
        throw MotionControllerException("Purging of serial buffer failed");
    }
}
Пример #17
0
/// \brief		Enable position limits on MCDC device
/// \details	Uses the 'APL' command to either allow or dis-allow the MCDC device to move past
///				a specific encoder value. The specific encoder values can be changed with setPositionLimits().
///	\pre		MCDC is still connected on the given COM port
///	\post		Position limits enforced or removed depending on the boolean value of enable
void MotionController::EnablePositionLimits(bool enable)
{
    if( FAILED(CanProcess()) ) return;

    m_limitsEnabled = enable;
    int en = 0;
    if(enable)
    {
        en = 1;
    }

    m_command = QString("%1APL%2\r").arg(DEVICE_ID).arg(en);
    m_serial.Write(m_command.toStdString().c_str());
}
Пример #18
0
///	\brief		Get the current/amperage value of the motor in milli-amps (mA)
///	\details	Send the "grc" command followed by a read of the serial port to get the current amperage of the motor
///	\pre		MCDC is still connected
///	\post		The current in mA is returned
int MotionController::GetCurrent(void)
{
    if( FAILED(CanProcess()) ) return false;

    m_command = QString("%1GRC\r").arg(DEVICE_ID);
    m_serial.Write(m_command.toStdString().c_str());

    std::string szRecvData;
    QString current = "";
    char recvChar = '|';
    bool breakFromLoop = false;
    bool CR_recv = false;	//Bool to indicate if Carriage return was received

    while(true)
    {
        while( !m_serial.IsInputAvailable() ) Sleep(1);

        if(m_serial.Read_N(szRecvData, 1, -1) != S_OK)
        {
            throw MotionControllerException("Current read from serial port failed");
        }

        recvChar = *szRecvData.c_str();

        switch(recvChar)
        {
        case '|':
            break;	//No valid chars have come through the serial port yet

        case '\r':	//CR char (0D in Hex) is the second last char to be received
            CR_recv = true;
            break;

        case '\n':	//LF char (0A in Hex) is that last char to be received before breaking from loop
            breakFromLoop = true;	//All chars have now been recv'd correctly
            break;

        default:
            if( isdigit(recvChar) )
                current.append( recvChar );
            break;
        }

        if(breakFromLoop) break;	//Break from loop if ending char was recv'd
    }

    bool ok;
    long amperage = current.toInt(&ok, 10);
    return amperage;
}
Пример #19
0
/// \brief		Set the digital output of the MCDC
///	\details	Sets the FAULT pin to either high-impedance or GND
/// \pre		MCDC DIGOUT is set to true
///	\post		FAULT output pin is set based on OnOff
void  MotionController::setDigitalOutput(bool OnOff)
{
    if(!IsInitialized())
        return;

    if( FAILED(CanProcess()) ) throw MotionControllerException("Cannot control output");;

    // Construct the string to send with the appropriate command
    if( OnOff)
        m_command = QString("%1SO\r").arg(DEVICE_ID);
    else
        m_command = QString("%1CO\r").arg(DEVICE_ID);

    m_serial.Write(m_command.toStdString().c_str());
}
Пример #20
0
/// \brief		Set current limit of MCDC device
/// \details	Uses the 'LPC' command to set the maximum allowable MCDC drive current
/// \warning	Be very CAREFUL how you change the safety checks in this function if you ever do.
///				Each motor connected to the MCDC has a maximum allowable current and if exceed for
///				long periods of time, the motor can be damaged.
///	\pre		MCDC is still connected on the given COM port
///	\post		Current limit set for the particular MCDC
void MotionController::SetPeakCurrentLimit(int currentLimit)
{
    if( FAILED(CanProcess()) ) return;

    //Set Current Limit
    /*** WARNING: Make sure the current limit is not set too high ***/
    if(currentLimit < 0 || currentLimit > 3000)	//If greater than 2A it may be unsafe to operate (i.e damage the motor)
        //Even 2A could be too high for smaller motors so be carefull
    {
        throw MotionControllerException("Current limit may be set too high, re-check value");
        return;
    }

    m_command = QString("%1LPC%2\r").arg(DEVICE_ID,currentLimit);
    m_serial.Write(m_command.toStdString().c_str());
}
Пример #21
0
bool CWindowListener::OnKeyPressed( char *s ){
	if ( !strcmp( s,"Escape" ) ) {
		Textool_Cancel();
		return TRUE;
	}
	if ( CanProcess() ) {
		if ( g_2DView.OnKeyDown( s ) ) {
			return TRUE;
		}

		if ( !strcmp( s,"Return" ) ) {
			Textool_Validate();
			return TRUE;
		}
	}
	return FALSE;
}
Пример #22
0
/// \brief		Rotate the motor to a given position (in encoder tick format) and request notification if necessary
/// \details	If the notify parameter is set to 'true' then the notificationValue parameter should also be set
///	\pre		MCDC is still connected on the given COM port
///	\post		Motor spins to and maintains a given position (i.e. maintains its location at a specific encoder tick)
bool MotionController::SetPosition(int pos, DeviceNotification *notify/*=NULL*/)
{
    if( FAILED(CanProcess()) ) return false;

    if( notify != NULL)
    {
        RequestPositionNotification(notify);
    }

    //Construct the string to send with both the LA and the M commands embedded in a single transmission
    m_command = QString("%1LA%2\r%3M\r").arg(DEVICE_ID).arg(pos).arg(DEVICE_ID);
    m_serial.Write(m_command.toStdString().c_str());

    m_currentState = Moving;

    return true;
}
Пример #23
0
/// \brief		Request verification (send back a 'p' char) when a particular position is reached
/// \details	If  the 'notify' param does not have a target, then only notify when motor reaches its target position
///	\pre		MCDC is still connected on the given COM port
///	\post		MCDC is given a request to notify at a specific position when overshot or when the target position is reached
bool MotionController::RequestPositionNotification(DeviceNotification *notify)
{
    if( FAILED(CanProcess()) ) return false;

    if( notify->HasNotifyValue() )
    {
        //Notify when motor overshoots/reaches the 'GetNotifyValue()' position
        m_command = QString("%1NP%2\r").arg(DEVICE_ID).arg(notify->GetNotifyValue());
    }
    else
    {
        //Only notify when motor reaches its TARGET position
        m_command = QString("%1NP\r").arg(DEVICE_ID);
    }

    m_serial.Write(m_command.toStdString().c_str());
    ++m_posNotifyCounter;

    return true;
}
Пример #24
0
/*-----------------------------------------------------------------------
	-- Reads all the data that is available in the local buffer.. 
	does NOT make any blocking calls in case the local buffer is empty
-----------------------------------------------------------------------*/
HRESULT CSerialCommHelper::ReadAvailable(std::string& data)
{

	HRESULT hr = CanProcess();
	if ( FAILED(hr)) return hr;
	try
	{
		std::string Temp;
		bool res = SerialBuffer.Read_Available (Temp,DataRx);

		data = Temp;
	}
	catch(...)
	{
		MTXDBG(CRITICAL,_("CSerialCommHelper Unhandled exception in ReadAvailable()"));
		g_assert ( 0  ) ;
		hr = E_FAIL;
	}
	return hr;
}
Пример #25
0
/// \brief		Verify whether the intended velocity was achieved
/// \details	The MCDC velocity notify command returns the character 'v' when the velocity is achieved
///	\pre		A corresponding call to SetVelocity() was made along with the notify parameter set to true
///	\post		Boolean value returned indicating whether or not the velocity, set in SetVelocity(), has been reached
bool MotionController::IsVelocityVerified(long timeOut)
{
    bool success = false;

    if( FAILED(CanProcess()) ) return false;

    if(m_velNotifyCounter < 1)
    {
        qDebug() << "MotionController : m_velNotifyCounter=" << m_velNotifyCounter;
        throw MotionControllerException("Velocity verified counter out of sync");
    }

    if( ReadCharsAndCompare("v\r\n", timeOut) )	// "v\r\n"
    {
        success = true;
        --m_velNotifyCounter;
        m_currentState = Verified;
    }

    return success;
}
Пример #26
0
/// \brief		Spin the motor at a given speed (RPM) and request notification if desired
/// \details	If the notify parameter is set to 'true' then the notificationValue parameter should also be set
///	\pre		MCDC is still connected on the given COM port
///	\post		Motor spins at and maintains a constant velocity (and may be notified when it reaches that particular velocity)
bool MotionController::SetVelocity(int rpm, DeviceNotification *notify/*=NULL*/)
{
    if( FAILED(CanProcess()) ) return false;

    if(m_limitsEnabled)
    {
        qDebug() << "ERROR: Cannot drive motor in velocity mode when limits are enabled";
        return false;
    }

    if( notify != NULL )
    {
        RequestVelocityNotification(notify);
    }

    m_command = QString("%1V%2\r").arg(QString::number(DEVICE_ID)).arg(QString::number(rpm));
    m_serial.Write(m_command.toStdString().c_str());

    m_currentState = Moving;

    return true;
}
Пример #27
0
HRESULT CSerialCommHelper::Write (const char* data,DWORD Size)
{
	HRESULT hr = CanProcess();
	if ( FAILED(hr)) return hr;
	int res = 0 ;
	OVERLAPPED ov;
	memset(&ov,0,sizeof(ov));
	ov.hEvent = CreateEvent( 0,true,0,0);
	DWORD BytesWritten = 0;
	//do
	{
		res = WriteFile (CommPort,data,Size,&BytesWritten  ,&ov);
		if ( res == 0 )
		{
			WaitForSingleObject(ov.hEvent ,INFINITE);
		}

	}//	while ( ov.InternHigh != Size ) ;
	CloseHandle(ov.hEvent);
	std::string Data(data);
	MTXDBG(CRITICAL,_("RCSeri:Writing:{%s} len:{%d}"),(Data).c_str(),Data.size());

	return S_OK;
}
Пример #28
0
///	\brief		Get the current position value of the motor in encoder ticks
///	\details	Send the "pos" command followed by a read of the serial port to get the most current position of the motor
///	\pre		MCDC is still connected
///	\post		The current position in encoder ticks is returned
long MotionController::GetPosition(void)
{
    if( FAILED(CanProcess()) ) return false;

    m_command = QString("%1POS\r").arg(DEVICE_ID);
    m_serial.Write(m_command.toStdString().c_str());


    std::string szRecvData;
    QString position = "";
    char recvChar = '|';
    bool breakFromLoop = false;
    bool CR_recv = false;	//Bool to indicate if Carriage return was received

    while(true)
    {
        int nTries = 0;
        while( !m_serial.IsInputAvailable() && nTries++ < MAX_QUERY_TRIES ) Sleep(1);

        if(nTries >= MAX_QUERY_TRIES) {
            //printf("Failed stupid\n");
            return m_lastPos;
        }

        //Input is now available...just read it
        if(m_serial.Read_N(szRecvData, 1, -1) != S_OK)
        {
            throw MotionControllerException("Position read from serial port failed");
        }

        recvChar = *szRecvData.c_str();

        switch(recvChar)
        {
        case '|':
            break;	//No valid chars have come through the serial port yet

        case '\r':	//CR char (0D in Hex) is the second last char to be received
            CR_recv = true;
            break;

        case '\n':	//LF char (0A in Hex) is that last char to be received before breaking from loop
            breakFromLoop = true;	//All chars have now been recv'd correctly
            break;

        case '-':		//Minus sign may exist in the first char only, if its doesn't assert
            position.append(recvChar);
            break;

        default:
            if( isdigit(recvChar) )
                position.append(recvChar);
            break;
        }

        if(breakFromLoop) break;	//Break from loop if ending char was recv'd
    }

    bool ok;
    long pos = position.toLong(&ok, 10);
    m_lastPos = pos;
    return pos;
}
Пример #29
0
HRESULT CSerialCommHelper::Read_N (std::string& data, long Count ,long TimeOut )
{
	HRESULT hr = CanProcess();

	if ( FAILED(hr)) 
	{
		g_assert(0);
		return hr;
	}

	MTXDBG(CRITICAL,_("CSerialCommHelper : CSerialCommHelper : Read_N called for %d bytes"),Count);
	try
	{
		std::string Tmp ;
		Tmp.erase();

		MTXDBG(CRITICAL,_("CSerialCommHelper : CSerialCommHelper : Read_N (%d) locking the queue  "),Count);

		int iLoc =  SerialBuffer.Read_N(Tmp ,Count ,DataRx );

		if ( iLoc == Count ) 
		{
			data = Tmp;
		}
		else
		{//there are either none or less bytes...
			long iRead = 0;
			int iRemaining = Count - iLoc;
			while (  1 )
			{

				MTXDBG(CRITICAL,_("CSerialCommHelper : CSerialCommHelper : Read_N (%d) making blocking read() "),Count);

				DWORD Wait  = WaitForSingleObject ( DataRx , TimeOut ) ;

				if  ( Wait == WAIT_TIMEOUT ) 
				{
					MTXDBG(CRITICAL,_("CSerialCommHelper : CSerialCommHelper : Read_N (%d) timed out in blocking read"),Count);
					data.erase ();
					hr = E_FAIL;
					return hr;
				}

				g_assert ( Wait == WAIT_OBJECT_0 );
				MTXDBG(CRITICAL,_("CSerialCommHelper : CSerialCommHelper : Read_N (%d) Woke Up from WaitXXX() locking Q"),Count);

				iRead =  SerialBuffer.Read_N(Tmp , iRemaining  ,DataRx);
				iRemaining -= iRead ;

				MTXDBG(CRITICAL,_("CSerialCommHelper : CSerialCommHelper : Read_N (%d) Woke Up from WaitXXX() Unlocking Q"),Count);

				if (  iRemaining  == 0) 
				{
					MTXDBG(CRITICAL,_("CSerialCommHelper : CSerialCommHelper : Read_N (%d) Woke Up from WaitXXX() Done reading "),Count);
					data = Tmp;
					return S_OK;
				}
			}
		}
	}
	catch(...)
	{
		MTXDBG(CRITICAL,_("CSerialCommHelper Unhandled exception"));
		g_assert ( 0  ) ;
	}
	return hr;
}