Commit 193cded3 authored by Jussi Lindgren's avatar Jussi Lindgren

plugins/processing/matlab:

 * Fixed path processing bug of the Matlab scripting box preventing Matlab launch on Linux
 * Changed the Matlab boxes and scenarios to ask for the Matlab executable instead of the setting being platform-specific (although on Windows, giving just the path works too, hence this change should be compatible with older Matlab-box using scenarios).
 * Fixed some compilation warnings
 * Deprecated the Matlab filter box. Please use the scripting box instead.
modules/fs:
 + Added a function to get the parent path of a path
cmake-modules:
 * Fixed the alternative way to detect Matlab on Linux and added support for upper-case MATLAB folder (2013a default install does this, for example)
parent 4ba94200
......@@ -17,9 +17,18 @@ IF(UNIX OR WIN32)
# Alternative way to try to find matlab
FILE(GLOB_RECURSE Executable_Candidates "/usr/local/matlab*/matlab")
IF(Executable_Candidates)
LIST(GET Executable_Candidates 1 Matlab_EXECUTABLE)
LIST(GET Executable_Candidates 0 Matlab_EXECUTABLE)
ENDIF(Executable_Candidates)
ENDIF(UNIX AND NOT Matlab_EXECUTABLE)
IF(UNIX AND NOT Matlab_EXECUTABLE)
# Alternative way 2 to try to find matlab
FILE(GLOB_RECURSE Executable_Candidates "/usr/local/MATLAB*/matlab")
IF(Executable_Candidates)
LIST(GET Executable_Candidates 0 Matlab_EXECUTABLE)
ENDIF(Executable_Candidates)
ENDIF(UNIX AND NOT Matlab_EXECUTABLE)
IF(Matlab_EXECUTABLE)
GET_FILENAME_COMPONENT(Matlab_ROOT ${Matlab_EXECUTABLE} PATH)
SET(Matlab_ROOT ${Matlab_ROOT}/..)
......@@ -71,4 +80,4 @@ IF(Matlab_FOUND)
ENDIF(Matlab_LIB_FOUND)
ELSE(Matlab_FOUND)
MESSAGE(STATUS " FAILED to find Matlab...")
ENDIF(Matlab_FOUND)
\ No newline at end of file
ENDIF(Matlab_FOUND)
......@@ -16,6 +16,9 @@ namespace FS
static FS::boolean createPath(const char* sPath);
// Creates all components of a path to the filesystem except the last part (i.e. for paths including a filename in the end)
static FS::boolean createParentPath(const char* sPath);
// Returns a path omitting the last part of it (essentially boost::filesystem::parent_path). Output sParentPath needs to be pre-allocated.
static FS::boolean getParentPath(const char *sPath, char *sParentPath);
private:
Files(void);
......
......@@ -158,3 +158,14 @@ bool Files::createParentPath(const char *sPath)
{
return boost::filesystem::create_directories(boost::filesystem::path(sPath).parent_path());
}
bool Files::getParentPath(const char *sPath, char *sParentPath)
{
if(!sPath || !sParentPath) {
return false;
}
strcpy(sParentPath, boost::filesystem::path(sPath).parent_path().string().c_str());
return true;
}
......@@ -100,9 +100,9 @@
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Path to Matlab Executables</Name>
<DefaultValue>C:/Program Files (x86)/MATLAB/R2011b/bin/win32</DefaultValue>
<Value>C:/Program Files (x86)/MATLAB/R2011b/bin/win32</Value>
<Name>Matlab executable (path)</Name>
<DefaultValue>C:/Program Files (x86)/MATLAB/R2011b/bin/win32/matlab.exe</DefaultValue>
<Value>C:/Program Files (x86)/MATLAB/R2011b/bin/win32/matlab.exe</Value>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
......@@ -495,7 +495,7 @@
<Identifier>(0x000037be, 0x000071f3)</Identifier>
<Text>&lt;b&gt;Configure the Matlab Scripting box:&lt;/b&gt;
&lt;span color=&quot;red&quot;&gt; Set the matlab installation directory before use !&lt;/span&gt;
&lt;span color=&quot;red&quot;&gt; Set the matlab executable path before use !&lt;/span&gt;
Enter the path to your local Matlab installation.
......@@ -601,4 +601,4 @@ The documentation page for this tutorial is available at:
<NumChildren>0</NumChildren>
</VisualisationWidget>
</VisualisationTree>
</OpenViBE-Scenario>
\ No newline at end of file
</OpenViBE-Scenario>
......@@ -293,9 +293,9 @@
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Path to Matlab Executables</Name>
<DefaultValue>C:/Program Files (x86)/MATLAB/R2011b/bin/win32</DefaultValue>
<Value>C:/Program Files (x86)/MATLAB/R2011b/bin/win32</Value>
<Name>Matlab executable (path)</Name>
<DefaultValue>C:/Program Files (x86)/MATLAB/R2011b/bin/win32/matlab.exe</DefaultValue>
<Value>C:/Program Files (x86)/MATLAB/R2011b/bin/win32/matlab.exe</Value>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
......@@ -672,8 +672,8 @@ every 2 seconds</Text>
<Identifier>(0x000042fe, 0x00002140)</Identifier>
<Text>&lt;b&gt;Configure the Matlab Scripting box:&lt;/b&gt;
&lt;span color=&quot;red&quot;&gt; Set the matlab installation directory
and working directory before use !&lt;/span&gt;
&lt;span color=&quot;red&quot;&gt; Set the matlab executable path
and the working directory before use !&lt;/span&gt;
If you want to add a sinusoid noise to the signal
set the noise frequency and amplitude.
......@@ -756,4 +756,4 @@ Set the frequency range for the plot scale.</Text>
<NumChildren>0</NumChildren>
</VisualisationWidget>
</VisualisationTree>
</OpenViBE-Scenario>
\ No newline at end of file
</OpenViBE-Scenario>
......@@ -23,9 +23,9 @@
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Path to Matlab Executables</Name>
<DefaultValue>C:/Program Files (x86)/MATLAB/R2011b/bin/win32</DefaultValue>
<Value>C:/Program Files (x86)/MATLAB/R2011b/bin/win32</Value>
<Name>Matlab executable (path)</Name>
<DefaultValue>C:/Program Files (x86)/MATLAB/R2011b/bin/win32/matlab.exe</DefaultValue>
<Value>C:/Program Files (x86)/MATLAB/R2011b/bin/win32/matlab.exe</Value>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
......@@ -268,8 +268,8 @@
<Identifier>(0x000035a5, 0x000068bb)</Identifier>
<Text>&lt;b&gt;Configure the Matlab Scripting box:&lt;/b&gt;
&lt;span color=&quot;red&quot;&gt; Set the matlab installation directory
and working directory before use !&lt;/span&gt;
&lt;span color=&quot;red&quot;&gt; Set the matlab executable path
and the working directory before use !&lt;/span&gt;
You can select the number of channels
and size of data chunk.
......@@ -354,4 +354,4 @@ The documentation page for this tutorial is available at:
<NumChildren>0</NumChildren>
</VisualisationWidget>
</VisualisationTree>
</OpenViBE-Scenario>
\ No newline at end of file
</OpenViBE-Scenario>
......@@ -15,6 +15,8 @@
#include <windows.h>
#endif
#include <fs/Files.h>
#define MATLAB_BUFFER 2048
#define m_pMatlabEngine ((Engine*)m_pMatlabEngineHandle)
#define m_pMatlabStimulation ((mxArray*)m_pMatlabStimulationHandle)
......@@ -32,11 +34,44 @@ using namespace OpenViBEPlugins::Tools;
#define boolean OpenViBE::boolean
// Sanitizes a path so that it only has / or \ characters and has a / or \ in the end.
// @fixme should move to plugins-FS possibly
void CBoxAlgorithmMatlabFilter::sanitizePath(OpenViBE::CString &sPathToModify) const {
std::string l_oTmpPath(sPathToModify);
// Append / to end of path if its not there already
if(l_oTmpPath.length()>0)
{
char l_cLastChar = l_oTmpPath.at(l_oTmpPath.length()-1);
if(l_cLastChar != '\\' && l_cLastChar != '/')
{
l_oTmpPath = l_oTmpPath + "/";
}
}
#if defined TARGET_OS_Windows
// Convert '/' to '\'
for (size_t i=0; i < l_oTmpPath.length(); i++) {
if(l_oTmpPath[i] == '/')
{
l_oTmpPath[i] = '\\';
}
}
#endif
sPathToModify = OpenViBE::CString(l_oTmpPath.c_str());
}
boolean CBoxAlgorithmMatlabFilter::OpenMatlabEngineSafely(void)
{
this->getLogManager() << LogLevel_Trace << "Trying to open Matlab engine\n";
this->getLogManager() << LogLevel_Trace << "Trying to open the Matlab engine\n";
#if defined TARGET_OS_Linux
m_pMatlabEngineHandle=::engOpen(m_sMatlabPath.toASCIIString());
if(!m_pMatlabEngine)
{
this->getLogManager() << LogLevel_Error << "Could not open the Matlab engine.\n" <<
"The configured path to the matlab executable was expanded as '" << m_sMatlabPath << "'.\n";
return false;
}
#elif defined TARGET_OS_Windows
__try
{
......@@ -44,18 +79,20 @@ boolean CBoxAlgorithmMatlabFilter::OpenMatlabEngineSafely(void)
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
this->getLogManager() << LogLevel_Error << "First call to MATLAB engine failed.\n"
this->getLogManager() << LogLevel_Error << "First call to the MATLAB engine failed.\n"
<< "\tTo use this box you must have MATLAB (32 bits version) installed on your computer.\n";
return false;
m_pMatlabEngineHandle = NULL;
}
#else
#endif
if(!m_pMatlabEngine)
{
this->getLogManager() << LogLevel_Error << "Could not open Matlab engine\n";
this->getLogManager() << LogLevel_Error << "Could not open the Matlab engine.\n" <<
"The configured path to the matlab bin directory was expanded as '" << m_sMatlabPath << "'.\n";
return false;
}
#else
this->getLogManager() << LogLevel_Error << "Only Linux and Windows are supported\n";
return false;
#endif
return true;
}
......@@ -78,30 +115,27 @@ boolean CBoxAlgorithmMatlabFilter::initialize(void)
ip_pMatrix.initialize(m_pStreamedMatrixEncoder->getInputParameter(OVP_GD_Algorithm_StreamedMatrixStreamEncoder_InputParameterId_Matrix));
m_ui64LatestStimulationChunkEndTime=0;
uint32 l_ui32FirstCommonIndex = 0;
getStaticBoxContext().getSettingValue(0, m_sMatlabPath);
#if defined TARGET_OS_Windows
std::string l_oTmpPath(m_sMatlabPath);
// Convert '/' to '\'
for (size_t i=0; i < l_oTmpPath.length(); i++) {
if(l_oTmpPath[i] == '/')
{
l_oTmpPath[i] = '\\';
}
if(!FS::Files::directoryExists(m_sMatlabPath) && FS::Files::fileExists(m_sMatlabPath))
{
// The path might be pointing to the executable, try to extract the directory
char l_sParentPath[MAX_PATH];
FS::Files::getParentPath(m_sMatlabPath, l_sParentPath);
m_sMatlabPath = OpenViBE::CString(l_sParentPath);
}
// Append \ to end of path if its not there already
if(l_oTmpPath.length()>0)
sanitizePath(m_sMatlabPath);
this->getLogManager() << LogLevel_Trace << "Interpreting Matlab path as '" << m_sMatlabPath << "'\n";
if(!FS::Files::directoryExists(m_sMatlabPath))
{
char l_cLastChar = l_oTmpPath.at(l_oTmpPath.length()-1);
if(l_cLastChar != '\\')
{
l_oTmpPath = l_oTmpPath + "\\";
}
m_sMatlabPath = OpenViBE::CString(l_oTmpPath.c_str());
this->getLogManager() << LogLevel_Error << "Configured Matlab path'" << m_sMatlabPath << "' does not seem to be a directory\n";
return false;
}
m_sMatlabPath = OpenViBE::CString(l_oTmpPath.c_str());
char * l_sPath = getenv("PATH");
if(l_sPath == NULL)
......
......@@ -54,13 +54,15 @@ namespace OpenViBEPlugins
void* m_pMatlabMatrixHandle;
void* m_pMatlabBCIContextHandle;
OpenViBE::CString m_sMatlabPath;
OpenViBE::CString m_sMatlabPath; // On Linux, path of the executable. On Windows, the executable directory.
OpenViBE::CString m_sProcessFunction;
OpenViBE::CString m_sInitializeFunction;
private:
OpenViBE::boolean OpenMatlabEngineSafely(void);
OpenViBE::boolean CloseMatlabEngineSafely(void);
void sanitizePath(OpenViBE::CString &sPathToModify) const;
};
class CBoxAlgorithmMatlabFilterDesc : virtual public OpenViBE::Plugins::IBoxAlgorithmDesc
......@@ -89,9 +91,9 @@ namespace OpenViBEPlugins
rBoxAlgorithmPrototype.addOutput ("Filtered streamed matrix", OV_TypeId_StreamedMatrix);
rBoxAlgorithmPrototype.addOutput ("Stimulations", OV_TypeId_Stimulations);
#if defined TARGET_OS_Linux
rBoxAlgorithmPrototype.addSetting("Matlab launch command", OV_TypeId_String, "[ssh user@host] /path/to/matlab");
rBoxAlgorithmPrototype.addSetting("Matlab executable (path)", OV_TypeId_String, "[ssh user@host] /path/to/matlab");
#elif defined TARGET_OS_Windows
rBoxAlgorithmPrototype.addSetting("Path to Matlab Executable", OV_TypeId_String, "C:/Program Files (x86)/MATLAB/R2011b/bin/win32");
rBoxAlgorithmPrototype.addSetting("Matlab executable (path)", OV_TypeId_String, "C:/Program Files (x86)/MATLAB/R2011b/bin/win32/matlab.exe");
#else
#endif
rBoxAlgorithmPrototype.addSetting("Matlab working directory", OV_TypeId_String, "${__volatile_ScenarioDir}");
......@@ -99,6 +101,7 @@ namespace OpenViBEPlugins
rBoxAlgorithmPrototype.addSetting("Process function", OV_TypeId_String, "bci_Process");
rBoxAlgorithmPrototype.addFlag(OpenViBE::Kernel::BoxFlag_IsUnstable);
rBoxAlgorithmPrototype.addFlag(OpenViBE::Kernel::BoxFlag_IsDeprecated);
return true;
}
......
......@@ -92,9 +92,15 @@ boolean CBoxAlgorithmMatlabScripting::checkFailureRoutine(boolean bResult, const
boolean CBoxAlgorithmMatlabScripting::OpenMatlabEngineSafely(void)
{
this->getLogManager() << LogLevel_Trace << "Trying to open Matlab engine\n";
this->getLogManager() << LogLevel_Trace << "Trying to open the Matlab engine\n";
#if defined TARGET_OS_Linux
m_pMatlabEngineHandle=::engOpen(m_sMatlabPath.toASCIIString());
if(!m_pMatlabEngine)
{
this->getLogManager() << LogLevel_Error << "Could not open the Matlab engine.\n" <<
"The configured path to the matlab executable was expanded as '" << m_sMatlabPath << "'.\n";
return false;
}
#elif defined TARGET_OS_Windows
__try
{
......@@ -106,13 +112,18 @@ boolean CBoxAlgorithmMatlabScripting::OpenMatlabEngineSafely(void)
<< "\tTo use this box you must have MATLAB (32 bits version) installed on your computer.\n";
m_pMatlabEngineHandle = NULL;
}
#endif
if(!m_pMatlabEngine)
{
char l_sMatlabDirectory[MAX_PATH];
FS::Files::getParentPath(m_sMatlabPath, l_sMatlabDirectory);
this->getLogManager() << LogLevel_Error << "Could not open the Matlab engine.\n" <<
"The path in the box configuration was interpreted as '" << m_sMatlabPath << "'.\n";
"The matlab binary path was reasoned to be '" << l_sMatlabDirectory << "'.\n";
return false;
}
#else
this->getLogManager() << LogLevel_Error << "Only Linux and Windows are supported\n";
return false;
#endif
return true;
}
......@@ -226,24 +237,30 @@ boolean CBoxAlgorithmMatlabScripting::initialize(void)
}
getStaticBoxContext().getSettingValue(1, m_sMatlabPath);
sanitizePath(m_sMatlabPath);
this->getLogManager() << LogLevel_Trace << "Interpreting Matlab path as '" << m_sMatlabPath << "'\n";
#if defined TARGET_OS_Windows
if(!FS::Files::directoryExists(m_sMatlabPath) && FS::Files::fileExists(m_sMatlabPath))
{
// The path might be pointing to the executable, try to extract the directory
char l_sParentPath[MAX_PATH];
FS::Files::getParentPath(m_sMatlabPath, l_sParentPath);
m_sMatlabPath = OpenViBE::CString(l_sParentPath);
}
sanitizePath(m_sMatlabPath);
this->getLogManager() << LogLevel_Trace << "Interpreting Matlab path as '" << m_sMatlabPath << "'\n";
if(!FS::Files::directoryExists(m_sMatlabPath))
{
this->getLogManager() << LogLevel_Error << "Problem with Matlab path '" << m_sMatlabPath << "'\n";
this->getLogManager() << LogLevel_Error << "Configured Matlab path '" << m_sMatlabPath << "' does not seem to be a directory\n";
return false;
}
#if defined TARGET_OS_Windows
char * l_sPath = getenv("PATH");
if(l_sPath == NULL)
{
this->getLogManager() << LogLevel_Error << "Could not access the environment variable PATH to add Matlab.\n";
this->getLogManager() << LogLevel_Error << "Could not access the environment variable PATH to add Matlab path to it.\n";
return false;
}
string l_sStrPath = string(l_sPath);
......
......@@ -49,7 +49,7 @@ namespace OpenViBEPlugins
CMatlabHelper m_oMatlabHelper;
OpenViBE::CString m_sMatlabPath;
OpenViBE::CString m_sMatlabPath; // On Linux, path of the executable. On Windows, the executable directory.
OpenViBE::CString m_sProcessFunction;
OpenViBE::CString m_sInitializeFunction;
OpenViBE::CString m_sUninitializeFunction;
......@@ -123,9 +123,13 @@ namespace OpenViBEPlugins
rBoxAlgorithmPrototype.addSetting("Box clock frequency in Hz", OV_TypeId_Integer, "64");
#if defined TARGET_OS_Linux
rBoxAlgorithmPrototype.addSetting("Matlab launch command", OV_TypeId_String, "[ssh user@host] /path/to/matlab");
rBoxAlgorithmPrototype.addSetting("Matlab executable (path)", OV_TypeId_String, "[ssh user@host] /path/to/matlab");
#elif defined TARGET_OS_Windows
rBoxAlgorithmPrototype.addSetting("Path to Matlab Executables", OV_TypeId_String, "C:/Program Files (x86)/MATLAB/R2011b/bin/win32");
// On Windows, the executable is not actually used, but its path is parsed from it and added to PATH.
// Background: Matlab's engOpen() takes a different argument on Windows and on Linux. On Windows, we need to have Matlab
// on PATH, in Linux we need to provide a full path of the executable. However, we'd like our example scenarios to give
// correct instructions to the user on both platforms, hence we use a setting that contains the information for both use-cases.
rBoxAlgorithmPrototype.addSetting("Matlab executable (path)", OV_TypeId_String, "C:/Program Files (x86)/MATLAB/R2011b/bin/win32/matlab.exe");
#else
#endif
rBoxAlgorithmPrototype.addSetting("Matlab working directory", OV_TypeId_String, "${__volatile_ScenarioDir}");
......
......@@ -103,7 +103,7 @@ boolean CMatlabHelper::setSignalInputHeader(uint32 ui32InputIndex, IMatrix * pMa
sprintf(l_sBuffer, "%i",pMatrix->getDimensionSize(1));
l_sCommand = l_sCommand + CString(l_sBuffer) + CString(",");
l_sCommand = l_sCommand + CString("{")+ l_sLabelList + CString("},");
sprintf(l_sBuffer, "%i",ui64SamplingRate);
sprintf(l_sBuffer, "%i",(int)ui64SamplingRate);
l_sCommand = l_sCommand + CString(l_sBuffer)+ CString(");");
return engEvalString(m_pMatlabEngine, (const char *) l_sCommand) == 0;
......@@ -474,7 +474,7 @@ boolean CMatlabHelper::getChannelLocalisationOutputHeader(uint32 ui32OutputIndex
mxArray * l_pDynamic = ::engGetVariable(m_pMatlabEngine,"OV_DYNAMIC");
uint32 l_ui32NbChannels = (uint32) *mxGetPr(l_pNbChannels);
boolean l_ui32Dynamic = ((uint32) *mxGetPr(l_pDynamic) == 1);
// boolean l_ui32Dynamic = ((uint32) *mxGetPr(l_pDynamic) == 1);
mwSize l_oNbCells = mxGetNumberOfElements(l_pNames);
char ** l_pNameList = new char*[l_oNbCells];
for(uint32 cell = 0; cell < l_oNbCells; cell++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment