mirror of
https://github.com/introlab/rtabmap.git
synced 2026-10-03 16:47:47 +08:00
Refactored how/when python interpretor is created to simplify library usage
This commit is contained in:
@@ -21,16 +21,24 @@ class gil_scoped_release;
|
|||||||
namespace rtabmap {
|
namespace rtabmap {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a single PythonInterface on main thread at
|
* Process-wide singleton owning the embedded Python interpreter.
|
||||||
* global scope before any Python classes.
|
* Call PythonInterface::instance() from the main thread (typically near
|
||||||
|
* the top of main()) before any Python-using class is constructed.
|
||||||
*/
|
*/
|
||||||
class RTABMAP_CORE_EXPORT PythonInterface
|
class RTABMAP_CORE_EXPORT PythonInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PythonInterface();
|
// Pass a caller tag (e.g. class name) so the main-thread assertion
|
||||||
virtual ~PythonInterface();
|
// can report who triggered the first construction.
|
||||||
|
static PythonInterface & instance(const std::string & caller = "");
|
||||||
|
|
||||||
|
PythonInterface(const PythonInterface &) = delete;
|
||||||
|
PythonInterface & operator=(const PythonInterface &) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
explicit PythonInterface(const std::string & caller);
|
||||||
|
~PythonInterface();
|
||||||
|
|
||||||
pybind11::scoped_interpreter* guard_;
|
pybind11::scoped_interpreter* guard_;
|
||||||
pybind11::gil_scoped_release* release_;
|
pybind11::gil_scoped_release* release_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ class Memory;
|
|||||||
class BayesFilter;
|
class BayesFilter;
|
||||||
class Signature;
|
class Signature;
|
||||||
class Optimizer;
|
class Optimizer;
|
||||||
class PythonInterface;
|
|
||||||
|
|
||||||
class RTABMAP_CORE_EXPORT Rtabmap
|
class RTABMAP_CORE_EXPORT Rtabmap
|
||||||
{
|
{
|
||||||
@@ -401,11 +400,6 @@ private:
|
|||||||
Transform _pathTransformToGoal;
|
Transform _pathTransformToGoal;
|
||||||
int _pathStuckCount;
|
int _pathStuckCount;
|
||||||
float _pathStuckDistance;
|
float _pathStuckDistance;
|
||||||
|
|
||||||
#ifdef RTABMAP_PYTHON
|
|
||||||
PythonInterface * _python;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace rtabmap
|
} // namespace rtabmap
|
||||||
|
|||||||
@@ -181,10 +181,13 @@ Rtabmap::Rtabmap() :
|
|||||||
_pathTransformToGoal(Transform::getIdentity()),
|
_pathTransformToGoal(Transform::getIdentity()),
|
||||||
_pathStuckCount(0),
|
_pathStuckCount(0),
|
||||||
_pathStuckDistance(0.0f)
|
_pathStuckDistance(0.0f)
|
||||||
#ifdef RTABMAP_PYTHON
|
|
||||||
,_python(new PythonInterface())
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
|
#ifdef RTABMAP_PYTHON
|
||||||
|
// Ensure the embedded Python interpreter is up. The first call here will
|
||||||
|
// assert that it runs on the main thread; callers building Rtabmap on a
|
||||||
|
// worker thread should construct the singleton in main() beforehand.
|
||||||
|
PythonInterface::instance("Rtabmap");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Rtabmap::~Rtabmap() {
|
Rtabmap::~Rtabmap() {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ PyDescriptor::PyDescriptor(
|
|||||||
dim_(Parameters::defaultPyDescriptorDim())
|
dim_(Parameters::defaultPyDescriptorDim())
|
||||||
{
|
{
|
||||||
UDEBUG("");
|
UDEBUG("");
|
||||||
|
PythonInterface::instance("PyDescriptor");
|
||||||
this->parseParameters(parameters);
|
this->parseParameters(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ PyDetector::PyDetector(const ParametersMap & parameters) :
|
|||||||
path_(Parameters::defaultPyDetectorPath()),
|
path_(Parameters::defaultPyDetectorPath()),
|
||||||
cuda_(Parameters::defaultPyDetectorCuda())
|
cuda_(Parameters::defaultPyDetectorCuda())
|
||||||
{
|
{
|
||||||
|
PythonInterface::instance("PyDetector");
|
||||||
this->parseParameters(parameters);
|
this->parseParameters(parameters);
|
||||||
|
|
||||||
UDEBUG("path = %s", path_.c_str());
|
UDEBUG("path = %s", path_.c_str());
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ PyMatcher::PyMatcher(
|
|||||||
iterations_(iterations),
|
iterations_(iterations),
|
||||||
cuda_(cuda)
|
cuda_(cuda)
|
||||||
{
|
{
|
||||||
|
PythonInterface::instance("PyMatcher");
|
||||||
path_ = uReplaceChar(pythonMatcherPath, '~', UDirectory::homeDir());
|
path_ = uReplaceChar(pythonMatcherPath, '~', UDirectory::homeDir());
|
||||||
model_ = uReplaceChar(model, '~', UDirectory::homeDir());
|
model_ = uReplaceChar(model, '~', UDirectory::homeDir());
|
||||||
UINFO("path = %s", path_.c_str());
|
UINFO("path = %s", path_.c_str());
|
||||||
|
|||||||
@@ -8,14 +8,39 @@
|
|||||||
#include <rtabmap/core/PythonInterface.h>
|
#include <rtabmap/core/PythonInterface.h>
|
||||||
#include <rtabmap/utilite/ULogger.h>
|
#include <rtabmap/utilite/ULogger.h>
|
||||||
#include <rtabmap/utilite/UThread.h>
|
#include <rtabmap/utilite/UThread.h>
|
||||||
|
#include <rtabmap/utilite/UConversion.h>
|
||||||
#include <pybind11/embed.h>
|
#include <pybind11/embed.h>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
namespace rtabmap {
|
namespace rtabmap {
|
||||||
|
|
||||||
PythonInterface::PythonInterface()
|
namespace {
|
||||||
|
// Captured when librtabmap_core is loaded. The dynamic loader runs static
|
||||||
|
// initializers on the main thread before main(), so this records the main
|
||||||
|
// thread id (as long as the library isn't dlopen'd from a worker thread).
|
||||||
|
const std::thread::id g_mainThreadId = std::this_thread::get_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
PythonInterface & PythonInterface::instance(const std::string & caller)
|
||||||
{
|
{
|
||||||
UINFO("Initialize python interpreter");
|
// Meyers singleton: thread-safe construction in C++11, destroyed at exit.
|
||||||
|
// The constructor asserts it runs on the main thread; the caller tag
|
||||||
|
// from the first invocation is captured into the assertion message.
|
||||||
|
static PythonInterface inst(caller);
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
PythonInterface::PythonInterface(const std::string & caller)
|
||||||
|
{
|
||||||
|
UASSERT_MSG(std::this_thread::get_id() == g_mainThreadId,
|
||||||
|
uFormat("PythonInterface must be created on the main thread "
|
||||||
|
"(first construction triggered by \"%s\"). Call "
|
||||||
|
"PythonInterface::instance() early in main() before "
|
||||||
|
"any worker thread touches a Python-backed class.",
|
||||||
|
caller.empty()?"<unspecified>":caller.c_str()).c_str());
|
||||||
|
UINFO("Initialize python interpreter (triggered by \"%s\")",
|
||||||
|
caller.empty()?"<unspecified>":caller.c_str());
|
||||||
guard_ = new pybind11::scoped_interpreter();
|
guard_ = new pybind11::scoped_interpreter();
|
||||||
|
|
||||||
// Tell Python to look in this directory for DLLs
|
// Tell Python to look in this directory for DLLs
|
||||||
|
|||||||
@@ -40,10 +40,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <pcl/filters/filter.h>
|
#include <pcl/filters/filter.h>
|
||||||
#include <rtabmap/core/SensorCaptureThread.h>
|
#include <rtabmap/core/SensorCaptureThread.h>
|
||||||
|
|
||||||
#ifdef RTABMAP_PYTHON
|
|
||||||
#include "rtabmap/core/PythonInterface.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "MapBuilder.h"
|
#include "MapBuilder.h"
|
||||||
|
|
||||||
void showUsage()
|
void showUsage()
|
||||||
@@ -77,10 +73,6 @@ int main(int argc, char * argv[])
|
|||||||
ULogger::setType(ULogger::kTypeConsole);
|
ULogger::setType(ULogger::kTypeConsole);
|
||||||
ULogger::setLevel(ULogger::kInfo);
|
ULogger::setLevel(ULogger::kInfo);
|
||||||
|
|
||||||
#ifdef RTABMAP_PYTHON
|
|
||||||
PythonInterface python; // Make sure we initialize python in main thread
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int driver = 0;
|
int driver = 0;
|
||||||
if(argc < 2)
|
if(argc < 2)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,10 +36,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef RTABMAP_PYTHON
|
|
||||||
#include "rtabmap/core/PythonInterface.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "MapBuilderWifi.h"
|
#include "MapBuilderWifi.h"
|
||||||
|
|
||||||
#include "WifiThread.h"
|
#include "WifiThread.h"
|
||||||
@@ -61,10 +57,6 @@ int main(int argc, char * argv[])
|
|||||||
ULogger::setType(ULogger::kTypeConsole);
|
ULogger::setType(ULogger::kTypeConsole);
|
||||||
ULogger::setLevel(ULogger::kWarning);
|
ULogger::setLevel(ULogger::kWarning);
|
||||||
|
|
||||||
#ifdef RTABMAP_PYTHON
|
|
||||||
PythonInterface python; // Make sure we initialize python in main thread
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::string interfaceName = "wlan0";
|
std::string interfaceName = "wlan0";
|
||||||
int driver = 0;
|
int driver = 0;
|
||||||
bool mirroring = false;
|
bool mirroring = false;
|
||||||
|
|||||||
@@ -28,9 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include "rtabmap/gui/DatabaseViewer.h"
|
#include "rtabmap/gui/DatabaseViewer.h"
|
||||||
#include "rtabmap/utilite/ULogger.h"
|
#include "rtabmap/utilite/ULogger.h"
|
||||||
#ifdef RTABMAP_PYTHON
|
|
||||||
#include <rtabmap/core/PythonInterface.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <vtkObject.h>
|
#include <vtkObject.h>
|
||||||
#include <vtkVersionMacros.h>
|
#include <vtkVersionMacros.h>
|
||||||
@@ -53,10 +50,6 @@ int main(int argc, char * argv[])
|
|||||||
QSurfaceFormat::setDefaultFormat(QVTKRenderWidget::defaultFormat());
|
QSurfaceFormat::setDefaultFormat(QVTKRenderWidget::defaultFormat());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RTABMAP_PYTHON
|
|
||||||
rtabmap::PythonInterface pythonInterface;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QApplication * app = new QApplication(argc, argv);
|
QApplication * app = new QApplication(argc, argv);
|
||||||
rtabmap::DatabaseViewer * mainWindow = new rtabmap::DatabaseViewer();
|
rtabmap::DatabaseViewer * mainWindow = new rtabmap::DatabaseViewer();
|
||||||
|
|
||||||
|
|||||||
@@ -42,9 +42,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <rtabmap/utilite/UFile.h>
|
#include <rtabmap/utilite/UFile.h>
|
||||||
#include <rtabmap/utilite/UStl.h>
|
#include <rtabmap/utilite/UStl.h>
|
||||||
#include <rtabmap/utilite/UTimer.h>
|
#include <rtabmap/utilite/UTimer.h>
|
||||||
#ifdef RTABMAP_PYTHON
|
|
||||||
#include <rtabmap/core/PythonInterface.h>
|
|
||||||
#endif
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
@@ -186,10 +183,6 @@ int main(int argc, char * argv[])
|
|||||||
printf(" --raw (images will be rectified)\n");
|
printf(" --raw (images will be rectified)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RTABMAP_PYTHON
|
|
||||||
rtabmap::PythonInterface pythonInterface;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ParametersMap parameters = Parameters::parseArguments(argc, argv);
|
ParametersMap parameters = Parameters::parseArguments(argc, argv);
|
||||||
parameters.insert(ParametersPair(Parameters::kRegRepeatOnce(), "false"));
|
parameters.insert(ParametersPair(Parameters::kRegRepeatOnce(), "false"));
|
||||||
|
|
||||||
|
|||||||
@@ -37,9 +37,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <rtabmap/utilite/UTimer.h>
|
#include <rtabmap/utilite/UTimer.h>
|
||||||
#include <rtabmap/utilite/UFile.h>
|
#include <rtabmap/utilite/UFile.h>
|
||||||
#include <rtabmap/utilite/UStl.h>
|
#include <rtabmap/utilite/UStl.h>
|
||||||
#ifdef RTABMAP_PYTHON
|
|
||||||
#include <rtabmap/core/PythonInterface.h>
|
|
||||||
#endif
|
|
||||||
#include <pcl/filters/filter.h>
|
#include <pcl/filters/filter.h>
|
||||||
#include <pcl/io/ply_io.h>
|
#include <pcl/io/ply_io.h>
|
||||||
#include <pcl/io/obj_io.h>
|
#include <pcl/io/obj_io.h>
|
||||||
@@ -119,10 +116,6 @@ int main(int argc, char * argv[])
|
|||||||
printf(" keep_linked = %s\n", keepLinked?"true":"false");
|
printf(" keep_linked = %s\n", keepLinked?"true":"false");
|
||||||
printf(" pre_cleanup = %s\n", preCleanup?"true":"false");
|
printf(" pre_cleanup = %s\n", preCleanup?"true":"false");
|
||||||
|
|
||||||
#ifdef RTABMAP_PYTHON
|
|
||||||
rtabmap::PythonInterface pythonInterface;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Just parse logging options
|
// Just parse logging options
|
||||||
Parameters::parseArguments(argc, argv);
|
Parameters::parseArguments(argc, argv);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user