diff --git a/cellulo-qml-plugin b/cellulo-qml-plugin deleted file mode 160000 index efdb94f..0000000 --- a/cellulo-qml-plugin +++ /dev/null @@ -1 +0,0 @@ -Subproject commit efdb94f4e6535c2b9a1c21f3d509a52be8dbf295 diff --git a/cellulo-qml-plugin b/cellulo-qml-plugin new file mode 120000 index 0000000..b09baf9 --- /dev/null +++ b/cellulo-qml-plugin @@ -0,0 +1 @@ +../cellulo-qml-plugin/ \ No newline at end of file diff --git a/cellulo-unity.pri b/cellulo-unity.pri index 7afac3d..fedd22c 100644 --- a/cellulo-unity.pri +++ b/cellulo-unity.pri @@ -1,52 +1,50 @@ QT += quick bluetooth CONFIG += qt c++11 nostrip linux:!android { CONFIG += link_pkgconfig packagesExist(bluez){ PKGCONFIG += bluez DEFINES += BT_MULTIADAPTER_SUPPORT message("BlueZ found, enabling Bluetooth multiadapter support.") } else{ message("BlueZ not found, disabling Bluetooth multiadapter support.") } } android{ QT += androidextras } DEFINES += CELLULOUNITY_LIBRARY # The following define makes your compiler emit warnings if you use # any feature of Qt which has been marked as deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ $$PWD/cellulounity.cpp \ $$PWD/cellulothread.cpp \ $$PWD/cellulorobotwrapper.cpp \ - $$PWD/CelluloUnity_Cellulo.cpp \ - $$PWD/cellulopoolclient.cpp + $$PWD/CelluloUnity_Cellulo.cpp HEADERS += \ $$PWD/cellulounity.h \ $$PWD/cellulo-unity_global.h \ $$PWD/cellulothread.h \ $$PWD/cellulorobotwrapper.h \ - $$PWD/CelluloUnity_Cellulo.h \ - $$PWD/cellulopoolclient.h + $$PWD/CelluloUnity_Cellulo.h LIBS += -lcelluloplugin -L$$[QT_INSTALL_QML]/Cellulo -L./ INCLUDEPATH += $$PWD/cellulo-qml-plugin/src $$PWD/cellulo-qml-plugin/include diff --git a/cellulo-unity.pro b/cellulo-unity.pro index a6c7ec9..e59f428 100644 --- a/cellulo-unity.pro +++ b/cellulo-unity.pro @@ -1,19 +1,21 @@ #------------------------------------------------- # # Project created by QtCreator 2018-07-30T12:15:05 # #------------------------------------------------- # including base file include(cellulo-unity.pri) TARGET = cellulo-unity TEMPLATE = lib CONFIG += debug unix { target.path = /usr/lib INSTALLS += target } + +HEADERS += diff --git a/cellulo-unity.pro.user.22 b/cellulo-unity.pro.user.22 new file mode 100644 index 0000000..dd3b1a3 --- /dev/null +++ b/cellulo-unity.pro.user.22 @@ -0,0 +1,335 @@ + + + + + + EnvironmentId + {bde6ebf8-4fa3-41e9-b52b-779c68ef39b0} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.11.0 clang 64bit Manual + Desktop Qt 5.11.0 clang 64bit Manual + {70511eb7-425e-4bab-9a92-25c5b3f8fa68} + 0 + 0 + 0 + + /Users/ulysse/Desktop/cellulo/cellulo-unity/build + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /Users/ulysse/Desktop/cellulo/build-cellulo-unity-Desktop_Qt_5_11_0_clang_64bit_Manual-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + /Users/ulysse/Desktop/cellulo/build-cellulo-unity-Desktop_Qt_5_11_0_clang_64bit_Manual-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + 0 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy Configuration + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + Custom Executable + + ProjectExplorer.CustomExecutableRunConfiguration + + 3768 + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/cellulobluetoothscannerwrapper.cpp b/cellulobluetoothscannerwrapper.cpp new file mode 100644 index 0000000..39145fc --- /dev/null +++ b/cellulobluetoothscannerwrapper.cpp @@ -0,0 +1,13 @@ +#include "cellulobluetoothscannerwrapper.h" + +void CelluloBluetoothScannerWrapper::init_() +{ + scanner = new CelluloBluetoothScanner; + qDebug() << "SCANNER Object created"; +} + +void CelluloBluetoothScannerWrapper::deinit_() +{ + client->deleteLater(); + client = nullptr; +} diff --git a/cellulopoolclient.h b/cellulobluetoothscannerwrapper.h similarity index 67% rename from cellulopoolclient.h rename to cellulobluetoothscannerwrapper.h index d44999f..b6958a1 100644 --- a/cellulopoolclient.h +++ b/cellulobluetoothscannerwrapper.h @@ -1,45 +1,45 @@ -#ifndef CELLULOPOOLCLIENT_H -#define CELLULOPOOLCLIENT_H +#ifndef CELLULOBLUETOOTHSCANNERWRAPPER_H +#define CELLULOBLUETOOTHSCANNERWRAPPER_H #include #include -#include "cellulo-qml-plugin/src/comm/relay/CelluloRobotPoolClient.h" +#include "cellulo-qml-plugin/src/comm/CelluloBluetoothScanner.h" #include #include -using Cellulo::CelluloRobotPoolClient; +using Cellulo::CelluloBluetoothScanner; using Cellulo::CelluloBluetooth; -class CelluloPoolClientWrapper : public QObject +class CelluloBluetoothScannerWrapper : public QObject { Q_OBJECT Q_INVOKABLE void init_(); Q_INVOKABLE void deinit_(); - CelluloRobotPoolClient *client; + CelluloBluetoothScanner *scanner; QVector robots; public: CelluloPoolClientWrapper(); QVector getRobots() { return robots; } int robots_N; public slots: void init() { QMetaObject::invokeMethod(this, "init_", Qt::BlockingQueuedConnection); } void deinit() { QMetaObject::invokeMethod(this, "deinit_", Qt::BlockingQueuedConnection); } void onNewRobot(CelluloBluetooth* robot); }; -#endif // CELLULOPOOLCLIENT_H +#endif // CELLULOBLUETOOTHSCANNERWRAPPER_H diff --git a/cellulopoolclient.cpp b/cellulopoolclient.cpp deleted file mode 100644 index af26564..0000000 --- a/cellulopoolclient.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "cellulopoolclient.h" - -void CelluloPoolClientWrapper::init_() -{ - client = new CelluloRobotPoolClient; - connect(client, &CelluloRobotPoolClient::newRobotFound, this, &CelluloPoolClientWrapper::onNewRobot); - qDebug() << "POOL Object created"; -} - -void CelluloPoolClientWrapper::deinit_() -{ - client->deleteLater(); - client = nullptr; -} - -CelluloPoolClientWrapper::CelluloPoolClientWrapper() -{ - robots_N = 0; -} - -void CelluloPoolClientWrapper::onNewRobot(CelluloBluetooth* robot) { - qDebug() << "ATTENTION ROBOT FOUND " << robot->getMacAddr(); - robots.push_back(robot); - robots_N++; -} diff --git a/cellulothread.cpp b/cellulothread.cpp index b14a653..70788f6 100644 --- a/cellulothread.cpp +++ b/cellulothread.cpp @@ -1,22 +1,21 @@ #include "cellulothread.h" #include -#include "cellulo-qml-plugin/src/comm/relay/CelluloRobotPoolClient.h" CelluloThread::CelluloThread() { } void CelluloThread::run() { qDebug() << "CelluloThread::run..."; argc = 1; argv[0] = strdup("CelluloThread"); argv[1] = nullptr; qDebug() << "CelluloThread creating QCoreApp"; QCoreApplication app(argc, argv); application = &app; qDebug() << "Starting the event loop..."; app.exec(); } diff --git a/cellulounity.cpp b/cellulounity.cpp index 7f273a1..ec9a625 100644 --- a/cellulounity.cpp +++ b/cellulounity.cpp @@ -1,194 +1,204 @@ #include "cellulounity.h" #include "cellulothread.h" #include "cellulorobotwrapper.h" -#include "cellulopoolclient.h" #include -// thread with an event loop -CelluloThread* thread = nullptr; - -// pool client wrapper -CelluloPoolClientWrapper* client = nullptr; +using Cellulo::CelluloBluetoothScanner; +using Cellulo::CelluloBluetooth; -// number of used by Unity robots -int used_robots; +CelluloThread* thread = nullptr; +CelluloBluetoothScanner* scanner = nullptr; -// TODO: use a less ugly way of creating thread (call at library loading) +/* + * Library initialization + */ void initialize() { - if(thread == nullptr) { - qDebug() << "creating thread..."; + if (thread == nullptr) { + qDebug() << "Creating thread..."; thread = new CelluloThread; - qDebug() << "starting thread..."; + qDebug() << "Starting thread..."; thread->start(); } // initializing the library again... - if(client != nullptr) { - qDebug() << "Client deinit..."; - client->deinit(); - qDebug() << "Deleting client..."; - client->deleteLater(); + if (scanner != nullptr) { + qDebug() << "Deleting scanner..."; + scanner->deleteLater(); qDebug() << "Setting ptr to nullptr"; - client = nullptr; + scanner = nullptr; } - if(client == nullptr) { - qDebug() << "creating pool..."; - client = new CelluloPoolClientWrapper; + if (scanner == nullptr) { + qDebug() << "Creating scanner..."; + scanner = new CelluloBluetoothScanner; - qDebug() << "moving pool to thread..."; - client->moveToThread(thread); + qDebug() << "Moving scanner to thread..."; + scanner->moveToThread(thread); + } +} - qDebug() << "initializing pool..."; - client->init(); +/* + * Scanner bindings + */ - qDebug() << "Pool OK"; +void startScanning() { + if (scanner == nullptr) { + qDebug() << "Cannot start scanning because initialize() was not called"; + return; + } + qDebug() << "Starting scanner..."; + scanner->start(); +} - // number of used by Unity robots - used_robots = 0; +void stopScanning() { + if (scanner == nullptr) { + qDebug() << "Cannot stop scanning because initialize() was not called"; + return; } + qDebug() << "Stopping scanner..."; + scanner->stop(); } -int64_t newRobot() -{ - if(client == nullptr) { - qDebug() << "Cannot create a new robot because initialize() was not called"; - return 0; // an error message will be shown in C# code +void clearScanResults() { + if(scanner == nullptr) { + qDebug() << "Cannot clear scan results because initialize() was not called"; + return; + } + qDebug() << "Clearing scanner results..."; + scanner->clear(); +} + +int getScanResultsLength() { + if (scanner == nullptr) { + qDebug() << "Cannot get scan results length because initialize() was not called"; + return -1; + } + return scanner->getFoundRobots().length(); +} + +const char * getScanResultAtIndex(int index) { + if (scanner == nullptr) { + qDebug() << "Cannot get scan result at index" << index << "because initialize() was not called"; + return nullptr; } + QByteArray utf8 = scanner->getFoundRobots().at(index).toUtf8(); + return utf8.constData(); +} + +/* + * Robot creation + */ - if(used_robots >= client->robots_N) { - qDebug() << "Cannot create a new robot because the pool is exhausted. Connect to more and restart the app."; - return 0; // an error message will be shown in C# code +int64_t newRobotFromMAC(const char * address) { + if (scanner == nullptr) { + qDebug() << "Cannot create a new robot because initialize() was not called"; + return 0; } - // obtaining a fee robot from pool - Cellulo::CelluloBluetooth* robot1 = client->getRobots().at(used_robots++); + qDebug() << "Creating bluetooth object..."; + CelluloBluetooth* bluetooth = new CelluloBluetooth(); + + qDebug() << "Moving bluetooth object to thread..."; + bluetooth->moveToThread(thread); - // wrapping it - qDebug() << "Wrapping robot" << robot1; - CelluloRobotWrapper* robot = new CelluloRobotWrapper(robot1); + qDebug() << "Moving bluetooth timers to thread..."; + bluetooth->moveTimersToThread(thread); - qDebug() << "moving robot to thread..."; + qDebug() << "Setting robot MAC address" << address; + bluetooth->setMacAddr(QString::fromUtf8(address)); + + qDebug() << "Setting automatic connect"; + bluetooth->setAutoConnect(1); + + qDebug() << "Creating robot object..."; + CelluloRobotWrapper* robot = new CelluloRobotWrapper(bluetooth); + + qDebug() << "Moving robot to thread..."; robot->moveToThread(thread); - qDebug() << "initializing robot..."; + qDebug() << "Initializing robot..."; robot->init(); qDebug() << "Got wrapped robot" << robot; // TODO: use something less ugly than that return (int64_t) robot; } -// TODO: check if *robot is actually a robot object +/* + * Robot bindings + */ -void setGoalVelocity(int64_t robot, float vx, float vy, float w) -{ +void setGoalVelocity(int64_t robot, float vx, float vy, float w) { ((CelluloRobotWrapper*) robot)->setGoalVelocity(vx, vy, w); } -void setGoalPose(int64_t robot, float x, float y, float theta, float v, float w) -{ +void setGoalPose(int64_t robot, float x, float y, float theta, float v, float w) { ((CelluloRobotWrapper*) robot)->setGoalPose(x, y, theta, v, w); } -void setGoalPosition(int64_t robot, float x, float y, float v) -{ +void setGoalPosition(int64_t robot, float x, float y, float v) { ((CelluloRobotWrapper*) robot)->setGoalPosition(x, y, v); } -void clearTracking(int64_t robot) -{ +void clearTracking(int64_t robot) { ((CelluloRobotWrapper*) robot)->clearTracking(); } -void clearHapticFeedback(int64_t robot) -{ +void clearHapticFeedback(int64_t robot) { ((CelluloRobotWrapper*) robot)->clearHapticFeedback(); } -void setVisualEffect(int64_t robot, int64_t effect, int64_t r, int64_t g, int64_t b, int64_t value) -{ +void setVisualEffect(int64_t robot, int64_t effect, int64_t r, int64_t g, int64_t b, int64_t value) { ((CelluloRobotWrapper*) robot)->setVisualEffect(effect, QColor(r, g, b), value); } -void setCasualBackdriveAssistEnabled(int64_t robot, int64_t enabled) -{ +void setCasualBackdriveAssistEnabled(int64_t robot, int64_t enabled) { ((CelluloRobotWrapper*) robot)->setCasualBackdriveAssistEnabled(enabled); } -void setHapticBackdriveAssist(int64_t robot, float xAssist, float yAssist, float thetaAssist) -{ +void setHapticBackdriveAssist(int64_t robot, float xAssist, float yAssist, float thetaAssist) { ((CelluloRobotWrapper*) robot)->setHapticBackdriveAssist(xAssist, yAssist, thetaAssist); } -void reset(int64_t robot) -{ +void reset(int64_t robot) { ((CelluloRobotWrapper*) robot)->reset(); } -void simpleVibrate(int64_t robot, float iX, float iY, float iTheta, int64_t period, int64_t duration) -{ +void simpleVibrate(int64_t robot, float iX, float iY, float iTheta, int64_t period, int64_t duration) { ((CelluloRobotWrapper*) robot)->simpleVibrate(iX, iY, iTheta, period, duration); } -float getX(int64_t robot) -{ +float getX(int64_t robot) { return ((CelluloRobotWrapper*) robot)->robot->getX(); } -float getY(int64_t robot) -{ +float getY(int64_t robot) { return ((CelluloRobotWrapper*) robot)->robot->getY(); } -float getTheta(int64_t robot) -{ +float getTheta(int64_t robot) { return ((CelluloRobotWrapper*) robot)->robot->getTheta(); } -int64_t getKidnapped(int64_t robot) -{ +int64_t getKidnapped(int64_t robot) { Cellulo::CelluloBluetooth* robot1 = (Cellulo::CelluloBluetooth*) ((CelluloRobotWrapper*) robot)->robot; return robot1->getKidnapped(); } -void destroyRobot(int64_t robot) -{ +void destroyRobot(int64_t robot) { qDebug() << "Removing callback..."; ((CelluloRobotWrapper*) robot)->kidnappedCallback = nullptr; qDebug() << "Calling deinit..."; ((CelluloRobotWrapper*) robot)->deinit(); } -void setKidnappedCallback(int64_t robot, callback_t callback) -{ - ((CelluloRobotWrapper*) robot)->kidnappedCallback = callback; -} - -int64_t robotsRemaining() -{ - if(client == nullptr) { - qDebug() << "Cannot get robotsRemaining() because initialize() was not called"; - return 0; - } - - if(client == nullptr) - return 0; - return client->robots_N - used_robots; +const char * getMacAddr(int64_t robot) { + return ((CelluloRobotWrapper*) robot)->robot->getMacAddr().toUtf8().constData(); } - -int64_t totalRobots() -{ - if(client == nullptr) { - qDebug() << "Cannot get totalRobots() because initialize() was not called"; - return 0; - } - - if(client == nullptr) - return 0; - return client->robots_N; +int getConnectionStatus(int64_t robot) { + return ((CelluloRobotWrapper*) robot)->robot->getConnectionStatus(); } diff --git a/cellulounity.h b/cellulounity.h index 9815c00..7d728a5 100644 --- a/cellulounity.h +++ b/cellulounity.h @@ -1,36 +1,48 @@ #ifndef CELLULOUNITY_H #define CELLULOUNITY_H +#include "cellulo-qml-plugin/src/comm/CelluloBluetoothScanner.h" #include typedef void (*callback_t)(); extern "C" { - // cellulo + // Library initialization void initialize(); - int64_t newRobot(); - void destroyRobot(int64_t robot); + // Scanner bindings + void startScanning(); + void stopScanning(); + void clearScanResults(); + int getScanResultsLength(); + const char * getScanResultAtIndex(int index); + + // Robot creation + int64_t newRobotFromMAC(const char * address); + // Robot bindings void setGoalVelocity(int64_t robot, float vx, float vy, float w); void setGoalPose(int64_t robot, float x, float y, float theta, float v, float w); void setGoalPosition(int64_t robot, float x, float y, float v); void clearTracking(int64_t robot); void clearHapticFeedback(int64_t robot); void setVisualEffect(int64_t robot, int64_t effect, int64_t r, int64_t g, int64_t b, int64_t value); void setCasualBackdriveAssistEnabled(int64_t robot, int64_t enabled); void setHapticBackdriveAssist(int64_t robot, float xAssist, float yAssist, float thetaAssist); void reset(int64_t robot); void simpleVibrate(int64_t robot, float iX, float iY, float iTheta, int64_t period, int64_t duration); float getX(int64_t robot); float getY(int64_t robot); float getTheta(int64_t robot); int64_t getKidnapped(int64_t robot); - void setKidnappedCallback(int64_t robot, callback_t callback); - int64_t robotsRemaining(); - int64_t totalRobots(); + void destroyRobot(int64_t robot); + + // Debug + const char * getMacAddr(int64_t robot); + int getConnectionStatus(int64_t robot); + } #endif // CELLULOUNITY_H diff --git a/libcelluloplugin.dylib b/libcelluloplugin.dylib new file mode 100755 index 0000000..20471e9 Binary files /dev/null and b/libcelluloplugin.dylib differ