#include <mil.h>
#include "interactiveexample.h"
CInteractiveExample::CInteractiveExample()
: CExampleInterface(M_SYSTEM_DEFAULT, M_GRAB),
m_MilDigitizer(M_NULL)
{
MdigAlloc(GetMilSystem(), M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_DEFAULT, &m_MilDigitizer);
if (m_MilDigitizer != M_NULL)
{
MIL_INT SizeX = MdigInquire(m_MilDigitizer, M_SIZE_X, M_NULL);
MIL_INT SizeY = MdigInquire(m_MilDigitizer, M_SIZE_Y, M_NULL);
SetImageSize(SizeX, SizeY);
}
}
CInteractiveExample::~CInteractiveExample()
{
if (m_MilDigitizer != M_NULL)
MdigFree(m_MilDigitizer);
}
bool CInteractiveExample::IsValid() const
{
bool IsValid = IsValidBase();
if (m_MilDigitizer == M_NULL)
IsValid = false;
return IsValid;
}
void CInteractiveExample::PauseInStandAloneMode() const
{
}
void CInteractiveExample::PrintExplanationForMinContrast() const
{
MosPrintf(MIL_TEXT("Activate the laser line and adjust the camera's aperture (or exposure) to\n")
MIL_TEXT("easily distinguish the laser line from the background. Then, adjust the\n")
MIL_TEXT("minimum contrast value to extract the laser line correctly.\n\n")
MIL_TEXT("Extracted laser line is displayed in green.\n")
MIL_TEXT("Use '1' and '2' to decrease/increase M_MINIMUM_CONTRAST in increments of 10,\n")
MIL_TEXT("or '4' and '5' to use increments of 1.\n")
MIL_TEXT("Press <Enter> when you are satisfied with the extraction results.\n\n"));
}
bool CInteractiveExample::AskMinContrastAdjust(MIL_INT* pMinContrast)
{
const MIL_INT BIG_INCREMENT = 10;
const MIL_INT SMALL_INCREMENT = 1;
bool AskQuit = false;
while (MosKbhit())
{
switch (MosGetch())
{
case MIL_TEXT('1'):
*pMinContrast -= BIG_INCREMENT;
break;
case MIL_TEXT('2'):
*pMinContrast += BIG_INCREMENT;
break;
case MIL_TEXT('4'):
*pMinContrast -= SMALL_INCREMENT;
break;
case MIL_TEXT('5'):
*pMinContrast += SMALL_INCREMENT;
break;
case MIL_TEXT('\r'):
case MIL_TEXT('\n'):
AskQuit = true;
break;
}
if (*pMinContrast < 0)
*pMinContrast = 0;
else if (*pMinContrast > 255)
*pMinContrast = 255;
}
MosPrintf(MIL_TEXT("\rM_MINIMUM_CONTRAST: %3d"), (int)(*pMinContrast));
return AskQuit;
}
bool CInteractiveExample::AskIfFeatureExtractionAccurate()
{
return AskYesNo(MIL_TEXT("Is the feature extraction accurate (y/n)? "));
}
bool CInteractiveExample::AskIfCameraCalibrationAccurate()
{
return AskYesNo(MIL_TEXT("Is the camera calibration accurate (y/n)? "));
}
bool CInteractiveExample::AskIfLineExtractionAccurate()
{
return AskYesNo(MIL_TEXT("Is the laser line extraction accurate (y/n)? "));
}
bool CInteractiveExample::AskIfLaserCalibrationAccurate()
{
return AskYesNo(MIL_TEXT("Is the calibration of the 3d reconstruction setup accurate (y/n)? "));
}
MIL_ID CInteractiveExample::TryToReloadCameraCalibration(const MIL_TEXT_CHAR* CalibrationFileName) const
{
MIL_ID MilCalibration = M_NULL;
MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE);
McalRestore(CalibrationFileName, GetMilSystem(), M_DEFAULT, &MilCalibration);
MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE);
if (MilCalibration != M_NULL)
{
bool UseReloadedCalibration = false;
MIL_INT CalibrationStatus = McalInquire(MilCalibration, M_CALIBRATION_STATUS, M_NULL);
MIL_INT CalibrationMode = McalInquire(MilCalibration, M_CALIBRATION_MODE , M_NULL);
if ( CalibrationStatus == M_CALIBRATED &&
(CalibrationMode == M_TSAI_BASED || CalibrationMode == M_3D_ROBOTICS) )
{
MosPrintf(MIL_TEXT("Camera calibration file '"));
MosPrintf(CalibrationFileName);
MosPrintf(MIL_TEXT("' has been found in the current\ndirectory. "));
UseReloadedCalibration = AskYesNo(MIL_TEXT("Do you want to reload this calibration context (y/n)? "));
}
if (!UseReloadedCalibration)
{
McalFree(MilCalibration);
MilCalibration = M_NULL;
MosPrintf(SEPARATOR);
}
}
return MilCalibration;
}
void CInteractiveExample::GrabCalibrationGrid()
{
MosPrintf(MIL_TEXT("Put the 15x16 calibration grid at Z=0 mm.\n")
MIL_TEXT("Press <Enter> to calibrate.\n\n"));
MdigGrabContinuous(m_MilDigitizer, GetMilDisplayImage());
MosGetch();
MdigHalt(m_MilDigitizer);
}
void CInteractiveExample::GrabLaserLineToAdjustContrast()
{
MdigGrab(m_MilDigitizer, GetMilDisplayImage());
}
bool CInteractiveExample::GrabCalibrationLaserLine(MIL_INT ReferencePlaneIndex, MIL_DOUBLE CalibrationDepth, bool ShouldAskIfFinished)
{
MosPrintf(MIL_TEXT("Set up the reference plane #%d at Z=%.3g mm.\n"), (int)ReferencePlaneIndex, CalibrationDepth);
if (ShouldAskIfFinished)
MosPrintf(MIL_TEXT("Press <Enter> to add this plane, or 's' to stop adding reference planes.\n\n"));
else
MosPrintf(MIL_TEXT("Press <Enter> to add this plane.\n\n"));
MdigGrabContinuous(m_MilDigitizer, GetMilDisplayImage());
MIL_INT UserChar = MosGetch();
MdigHalt(m_MilDigitizer);
bool ReadyToCalibrate = false;
if (ShouldAskIfFinished && UserChar == MIL_TEXT('s'))
{
ReadyToCalibrate = true;
if (ReferencePlaneIndex == 1)
{
MosPrintf(MIL_TEXT("Since a single reference plane is used, the laser plane is assumed to be\n")
MIL_TEXT("vertical. Press <Enter> to continue.\n\n"));
MosGetch();
}
}
return ReadyToCalibrate;
}
bool CInteractiveExample::AskYesNo(const MIL_TEXT_CHAR* QuestionString)
{
MosPrintf(QuestionString);
while (true)
{
switch (MosGetch())
{
case MIL_TEXT('y'):
MosPrintf(MIL_TEXT("YES\n\n"));
return true;
case MIL_TEXT('n'):
MosPrintf(MIL_TEXT("NO\n\n"));
return false;
}
}
}