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 {
|
||||
|
||||
/**
|
||||
* Create a single PythonInterface on main thread at
|
||||
* global scope before any Python classes.
|
||||
* Process-wide singleton owning the embedded Python interpreter.
|
||||
* 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
|
||||
{
|
||||
public:
|
||||
PythonInterface();
|
||||
virtual ~PythonInterface();
|
||||
// Pass a caller tag (e.g. class name) so the main-thread assertion
|
||||
// can report who triggered the first construction.
|
||||
static PythonInterface & instance(const std::string & caller = "");
|
||||
|
||||
PythonInterface(const PythonInterface &) = delete;
|
||||
PythonInterface & operator=(const PythonInterface &) = delete;
|
||||
|
||||
private:
|
||||
explicit PythonInterface(const std::string & caller);
|
||||
~PythonInterface();
|
||||
|
||||
pybind11::scoped_interpreter* guard_;
|
||||
pybind11::gil_scoped_release* release_;
|
||||
};
|
||||
|
||||
@@ -50,7 +50,6 @@ class Memory;
|
||||
class BayesFilter;
|
||||
class Signature;
|
||||
class Optimizer;
|
||||
class PythonInterface;
|
||||
|
||||
class RTABMAP_CORE_EXPORT Rtabmap
|
||||
{
|
||||
@@ -401,11 +400,6 @@ private:
|
||||
Transform _pathTransformToGoal;
|
||||
int _pathStuckCount;
|
||||
float _pathStuckDistance;
|
||||
|
||||
#ifdef RTABMAP_PYTHON
|
||||
PythonInterface * _python;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
} // namespace rtabmap
|
||||
|
||||
@@ -181,10 +181,13 @@ Rtabmap::Rtabmap() :
|
||||
_pathTransformToGoal(Transform::getIdentity()),
|
||||
_pathStuckCount(0),
|
||||
_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() {
|
||||
|
||||
@@ -23,6 +23,7 @@ PyDescriptor::PyDescriptor(
|
||||
dim_(Parameters::defaultPyDescriptorDim())
|
||||
{
|
||||
UDEBUG("");
|
||||
PythonInterface::instance("PyDescriptor");
|
||||
this->parseParameters(parameters);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ PyDetector::PyDetector(const ParametersMap & parameters) :
|
||||
path_(Parameters::defaultPyDetectorPath()),
|
||||
cuda_(Parameters::defaultPyDetectorCuda())
|
||||
{
|
||||
PythonInterface::instance("PyDetector");
|
||||
this->parseParameters(parameters);
|
||||
|
||||
UDEBUG("path = %s", path_.c_str());
|
||||
|
||||
@@ -30,6 +30,7 @@ PyMatcher::PyMatcher(
|
||||
iterations_(iterations),
|
||||
cuda_(cuda)
|
||||
{
|
||||
PythonInterface::instance("PyMatcher");
|
||||
path_ = uReplaceChar(pythonMatcherPath, '~', UDirectory::homeDir());
|
||||
model_ = uReplaceChar(model, '~', UDirectory::homeDir());
|
||||
UINFO("path = %s", path_.c_str());
|
||||
|
||||
@@ -8,14 +8,39 @@
|
||||
#include <rtabmap/core/PythonInterface.h>
|
||||
#include <rtabmap/utilite/ULogger.h>
|
||||
#include <rtabmap/utilite/UThread.h>
|
||||
#include <rtabmap/utilite/UConversion.h>
|
||||
#include <pybind11/embed.h>
|
||||
#include <filesystem>
|
||||
#include <thread>
|
||||
|
||||
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();
|
||||
|
||||
// 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 <rtabmap/core/SensorCaptureThread.h>
|
||||
|
||||
#ifdef RTABMAP_PYTHON
|
||||
#include "rtabmap/core/PythonInterface.h"
|
||||
#endif
|
||||
|
||||
#include "MapBuilder.h"
|
||||
|
||||
void showUsage()
|
||||
@@ -77,10 +73,6 @@ int main(int argc, char * argv[])
|
||||
ULogger::setType(ULogger::kTypeConsole);
|
||||
ULogger::setLevel(ULogger::kInfo);
|
||||
|
||||
#ifdef RTABMAP_PYTHON
|
||||
PythonInterface python; // Make sure we initialize python in main thread
|
||||
#endif
|
||||
|
||||
int driver = 0;
|
||||
if(argc < 2)
|
||||
{
|
||||
|
||||
@@ -36,10 +36,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <QApplication>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef RTABMAP_PYTHON
|
||||
#include "rtabmap/core/PythonInterface.h"
|
||||
#endif
|
||||
|
||||
#include "MapBuilderWifi.h"
|
||||
|
||||
#include "WifiThread.h"
|
||||
@@ -61,10 +57,6 @@ int main(int argc, char * argv[])
|
||||
ULogger::setType(ULogger::kTypeConsole);
|
||||
ULogger::setLevel(ULogger::kWarning);
|
||||
|
||||
#ifdef RTABMAP_PYTHON
|
||||
PythonInterface python; // Make sure we initialize python in main thread
|
||||
#endif
|
||||
|
||||
std::string interfaceName = "wlan0";
|
||||
int driver = 0;
|
||||
bool mirroring = false;
|
||||
|
||||
@@ -28,9 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <QApplication>
|
||||
#include "rtabmap/gui/DatabaseViewer.h"
|
||||
#include "rtabmap/utilite/ULogger.h"
|
||||
#ifdef RTABMAP_PYTHON
|
||||
#include <rtabmap/core/PythonInterface.h>
|
||||
#endif
|
||||
|
||||
#include <vtkObject.h>
|
||||
#include <vtkVersionMacros.h>
|
||||
@@ -53,10 +50,6 @@ int main(int argc, char * argv[])
|
||||
QSurfaceFormat::setDefaultFormat(QVTKRenderWidget::defaultFormat());
|
||||
#endif
|
||||
|
||||
#ifdef RTABMAP_PYTHON
|
||||
rtabmap::PythonInterface pythonInterface;
|
||||
#endif
|
||||
|
||||
QApplication * app = new QApplication(argc, argv);
|
||||
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/UStl.h>
|
||||
#include <rtabmap/utilite/UTimer.h>
|
||||
#ifdef RTABMAP_PYTHON
|
||||
#include <rtabmap/core/PythonInterface.h>
|
||||
#endif
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <QApplication>
|
||||
@@ -186,10 +183,6 @@ int main(int argc, char * argv[])
|
||||
printf(" --raw (images will be rectified)\n");
|
||||
}
|
||||
|
||||
#ifdef RTABMAP_PYTHON
|
||||
rtabmap::PythonInterface pythonInterface;
|
||||
#endif
|
||||
|
||||
ParametersMap parameters = Parameters::parseArguments(argc, argv);
|
||||
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/UFile.h>
|
||||
#include <rtabmap/utilite/UStl.h>
|
||||
#ifdef RTABMAP_PYTHON
|
||||
#include <rtabmap/core/PythonInterface.h>
|
||||
#endif
|
||||
#include <pcl/filters/filter.h>
|
||||
#include <pcl/io/ply_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(" pre_cleanup = %s\n", preCleanup?"true":"false");
|
||||
|
||||
#ifdef RTABMAP_PYTHON
|
||||
rtabmap::PythonInterface pythonInterface;
|
||||
#endif
|
||||
|
||||
// Just parse logging options
|
||||
Parameters::parseArguments(argc, argv);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user