void mtsMicroScribeDigitizer::Configure(const std::string & filename)
{
    // Setup error handlers
#define SETUP_ERROR_HANDLER(_errorCode, _handlerName)\
    if (ARM_SUCCESS != ArmSetErrorHandlerFunction(_errorCode, ErrorHandler_##_handlerName)) {\
        CMN_LOG_CLASS_INIT_ERROR << "Startup: Failed to set error handler: "#_errorCode  << std::endl;\
        cmnThrow("Startup: Failed to set error handler: "#_errorCode);\
    }
    SETUP_ERROR_HANDLER(NO_HCI_HANDLER,     NoHCI);
    SETUP_ERROR_HANDLER(BAD_PORT_HANDLER,   BadPort);
    SETUP_ERROR_HANDLER(CANT_OPEN_HANDLER,  CantOpen);
    SETUP_ERROR_HANDLER(CANT_BEGIN_HANDLER, CantBegin);
    // MJ: TIMED_OUT_HANDLER and BAD_PACKET_HANDLER are not overridden because the SDK explicitly 
	// recommends not to do that as follows (see BAD_PACKET_handler and TIMED_OUT_handler):
	//
	// "Although this function is still exported for backward compatibility issue, user 
	// shouldn't have any reason to provide any custom TIMED_OUT_handler because the default 
	// ArmDll32's TIMED_OUT_handler should be enough. Any incorrect behavior in such custom 
	// error handler function could affect ArmDll32's performance."
#undef SETUP_ERROR_HANDLER

    // Connect to hardware
    if (ARM_SUCCESS != ArmConnect(0, 0)) {
        CMN_LOG_CLASS_INIT_ERROR << "Startup: Unable to connect to ArmDll32" << std::endl;
        ArmEnd();
        cmnThrow("Startup: Unable to connect to ArmDll32");
    } else {
        OnDeviceConnection();
    }

    // Get device product information
    const size_t len = 256;
    char buf[len];
    // Product name
    if (ARM_SUCCESS == ArmGetProductName(buf, len)) {
        DigitizerInfo.ProductName = buf;
    } else {
        DigitizerInfo.ProductName = "Failed to fetch";
    }
    // Model name
    if (ARM_SUCCESS == ArmGetModelName(buf, len)) {
        DigitizerInfo.ModelName = buf;
    } else {
        DigitizerInfo.ModelName = "Failed to fetch";
    }
    // Serial number
    if (ARM_SUCCESS == ArmGetSerialNumber(buf, len)) {
        DigitizerInfo.SerialNumber = buf;
    } else {
        DigitizerInfo.SerialNumber = "Failed to fetch";
    }
    // Driver and firmware version
	char buf2[len];
    if (ARM_SUCCESS == ArmGetVersion(buf, buf2, len)) {
        DigitizerInfo.DriverVersion = buf;
        DigitizerInfo.FirmwareVersion = buf2;
    } else {
        DigitizerInfo.DriverVersion = "Failed to fetch";
        DigitizerInfo.FirmwareVersion = "Failed to fetch";
    }
	// Num of DoF
	int dof;
	if (ARM_SUCCESS == ArmGetNumDOF(&dof)) {
		// -1 if DoF cannot be determined (e.g., pre-G2 versions of the MicroScribe)
		DigitizerInfo.NumDoF = dof;
    } else {
        DigitizerInfo.NumDoF = -1;
    }

    CMN_LOG_CLASS_INIT_VERBOSE << "Startup: " << DigitizerInfo << std::endl;

    // Set refresh rate
    if (ARM_SUCCESS != ArmSetUpdateEx(ARM_FULL, (UINT) (this->Period * 1000))) { // second argument in msec
        CMN_LOG_CLASS_INIT_ERROR << "Startup: Unable to set update for ArmDll32" << std::endl;
        ArmDisconnect();
        ArmEnd();
        cmnThrow("Startup: Unable to set update for ArmDll32");
    }

	// Check device status (device can be disonncected after all getters succeeded)
	if (ARM_SUCCESS == ArmGetDeviceStatus(&DeviceStatusVendor)) {
		DeviceStatus(STATUS) = DeviceStatusVendor.status;
		DeviceStatus(BAUD) = DeviceStatusVendor.Baud;
		DeviceStatus(PORT_NUMBER) = DeviceStatusVendor.PortNumber;

		if (!(DeviceStatus(STATUS) & ARM_CONNECTED)) {
			OnDeviceDisconnection();
			return;
		}
	}
}
예제 #2
0
// This creates a vrpn_3DMicroscribe and sets it to reset mode.
vrpn_3DMicroscribe::vrpn_3DMicroscribe (const char * name, vrpn_Connection * c,
					const char * Port, long int BaudRate,
					float OffsetX/* = 0.0f*/,
					float OffsetY/* = 0.0f*/,
					float OffsetZ/* = 0.0f*/,
					float Scale/*=1.0f*/):
		vrpn_Tracker(name, c),
		vrpn_Button_Filter(name, c),
		_numbuttons(2)
{
	// Set the parameters in the parent classes
	vrpn_Button::num_buttons = _numbuttons;
	
	if(!strcmp(Port, "COM1") )
		m_PortNumber=1;
	else if(!strcmp(Port, "COM2") )
		m_PortNumber=2;
	else if(!strcmp(Port, "COM3") )
		m_PortNumber=3;
	else if(!strcmp(Port, "COM4") )
		m_PortNumber=4;
	m_BaudRate=BaudRate;
	m_OffSet[0]=OffsetX; m_OffSet[1]=OffsetY; m_OffSet[2]=OffsetZ;
	m_Scale=Scale;

	// Set the status of the buttons and analogs to 0 to start
	clear_values();

#ifdef VRPN_USE_MICROSCRIBE
	int iResult;
	iResult=ArmStart(NULL);
	if(ARM_SUCCESS != iResult)
	{
		//error starting the MicroScribe drivers
		VRPN_MSG_ERROR( "Unable to start MicroScribe ArmDll32." );
		return;
	}

	//don't use error handlers
	iResult = ArmSetErrorHandlerFunction(NO_HCI_HANDLER, NULL);
	iResult = ArmSetErrorHandlerFunction(BAD_PORT_HANDLER, NULL);
	iResult = ArmSetErrorHandlerFunction(CANT_OPEN_HANDLER, NULL);
	iResult = ArmSetErrorHandlerFunction(CANT_BEGIN_HANDLER, NULL);

	//connect to the correct port
	switch(m_PortNumber)
	{
	case 1:
		iResult = ArmConnect(1, m_BaudRate);
		break;
	case 2:
		iResult = ArmConnect(2, m_BaudRate);
		break;
	case 3:
		iResult = ArmConnect(3, m_BaudRate);
		break;
	case 4:
		iResult = ArmConnect(4, m_BaudRate);
		break;
	default:
		iResult = ArmConnect(0, 0); //try all available ports and baud rates
		break;
	}

	if(ARM_SUCCESS != iResult)
	{ 
		//error connecting, end the thread
		ArmEnd();
		VRPN_MSG_ERROR( "Unable to connect to the MicroScribe." );
		return;
	}

#endif
	// Set the mode to reset
	status = STATUS_RESETTING;
}