Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow JoypadControlServer to run single thread #3101

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/release/master.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Fixes

* Configuration files installed by the `yarp_configure_plugins_installation` CMake macro are now relocatable (https://github.com/robotology/yarp/issues/2445, ).
* Improved `ffmpeg` port monitor to allow using different couples of coders/decodes
* Improved `yarpdev` closing behavior for devices implementing the `iService` interface

New Features
------------
Expand Down
34 changes: 34 additions & 0 deletions src/devices/deviceBundler/DeviceBundler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ bool DeviceBundler::open(yarp::os::Searchable& config)
return false;
}

ret = m_pdev_wrapper.view(m_iService);
if (ret)
{
yCInfo(DEVICEBUNDLER, "The device implements the IService iterface");
}

ret = m_iWrapper->attach(&m_pdev_subdevice);
if (!ret)
{
Expand All @@ -93,6 +99,7 @@ bool DeviceBundler::close()
{
m_iWrapper->detach();
m_iWrapper = nullptr;
m_iService = nullptr;
}

if (m_pdev_wrapper.isValid())
Expand All @@ -107,3 +114,30 @@ bool DeviceBundler::close()

return true;
}

bool DeviceBundler::startService()
{
if (m_iService)
{
return m_iService->startService();
}
return true; //If not implemented, emulate running in background
}

bool DeviceBundler::updateService()
{
if (m_iService)
{
return m_iService->updateService();
}
return false;
}

bool DeviceBundler::stopService()
{
if (m_iService)
{
return m_iService->stopService();
}
return false;
}
8 changes: 8 additions & 0 deletions src/devices/deviceBundler/DeviceBundler.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <yarp/dev/DeviceDriver.h>
#include <yarp/dev/PolyDriver.h>
#include <yarp/dev/IWrapper.h>
#include <yarp/dev/ServiceInterfaces.h>
#include "DeviceBundler_ParamsParser.h"

/**
Expand All @@ -25,6 +26,7 @@
*/

class DeviceBundler : public yarp::dev::DeviceDriver,
public yarp::dev::IService,
public DeviceBundler_ParamsParser
{
public:
Expand All @@ -39,10 +41,16 @@ class DeviceBundler : public yarp::dev::DeviceDriver,
bool open(yarp::os::Searchable& config) override;
bool close() override;

// yarp::dev::IService methods
virtual bool startService() override;
virtual bool updateService() override;
virtual bool stopService() override;

private:
yarp::dev::PolyDriver m_pdev_wrapper;
yarp::dev::PolyDriver m_pdev_subdevice;
yarp::dev::IWrapper* m_iWrapper=nullptr;
yarp::dev::IService* m_iService=nullptr;
};

#endif // YARP_DEVICEBUNDLER_H
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ bool JoypadControlServer::open(yarp::os::Searchable& config)
return false;
}

m_lastRunTime = yarp::os::Time::now();

m_rpcPortName = m_name + "/rpc:i";
m_portButtons.name = m_name + "/buttons:o";
m_portAxis.name = m_name + "/axis:o";
Expand All @@ -262,10 +264,11 @@ bool JoypadControlServer::attach(PolyDriver* poly)
yCError(JOYPADCONTROLSERVER) << "Attached device has no valid IJoypadController interface.";
return false;
}

PeriodicThread::setPeriod(m_period);
if (!PeriodicThread::start()) {
return false;
if (!m_use_single_thread) {
PeriodicThread::setPeriod(m_period);
if (!PeriodicThread::start()) {
return false;
}
}

openPorts();
Expand Down Expand Up @@ -549,6 +552,10 @@ void JoypadControlServer::profile()

void JoypadControlServer::run()
{
if (m_use_single_thread && yarp::os::Time::now() - m_lastRunTime < m_period) {
return;
}

if(m_use_separate_ports)
{
if (m_portButtons.valid)
Expand Down Expand Up @@ -698,6 +705,23 @@ void JoypadControlServer::run()
}
}

bool JoypadControlServer::startService()
{
return !m_use_single_thread;
}

bool JoypadControlServer::updateService()
{
if (m_use_single_thread)
run();
return true;
}

bool JoypadControlServer::stopService()
{
return close();
}

bool JoypadControlServer::close()
{
detachAll();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <yarp/os/PeriodicThread.h>
#include <yarp/dev/DeviceDriver.h>
#include <yarp/dev/IJoypadController.h>
#include <yarp/dev/ServiceInterfaces.h>
#include <yarp/dev/WrapperSingle.h>
#include <yarp/dev/PolyDriver.h>
#include <yarp/dev/PolyDriverList.h>
Expand Down Expand Up @@ -47,6 +48,7 @@ class JoypadControlServer :
public yarp::dev::DeviceDriver,
public yarp::dev::WrapperSingle,
public yarp::os::PeriodicThread,
public yarp::dev::IService,
public JoypadControlServer_ParamsParser
{
typedef yarp::dev::IJoypadController::JoypadCtrl_coordinateMode coordsMode;
Expand All @@ -68,6 +70,7 @@ class JoypadControlServer :
JoyPort<Vector> m_portTrackball;
yarp::os::BufferedPort<JoyData> m_godPort; //TODO: single port purpose
coordsMode m_coordsMode = yarp::dev::IJoypadController::JypCtrlcoord_CARTESIAN;
double m_lastRunTime = 0.0;


bool openAndAttachSubDevice(yarp::os::Searchable& prop);
Expand All @@ -89,6 +92,9 @@ class JoypadControlServer :
bool threadInit() override;
void threadRelease() override;
void run() override;
bool startService() override;
bool updateService() override;
bool stopService() override;
};

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// This is an automatically generated file. Please do not edit it.
// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON.

// Generated on: Thu Mar 7 17:59:50 2024
// Generated on: Mon Apr 8 10:24:20 2024


#include "JoypadControlServer_ParamsParser.h"
Expand All @@ -32,6 +32,7 @@ std::vector<std::string> JoypadControlServer_ParamsParser::getListOfParams() con
params.push_back("name");
params.push_back("use_separate_ports");
params.push_back("profile");
params.push_back("use_single_thread");
return params;
}

Expand Down Expand Up @@ -104,6 +105,20 @@ bool JoypadControlServer_ParamsParser::parseParams(const yarp::os::Searchab
prop_check.unput("profile");
}

//Parser of parameter use_single_thread
{
if (config.check("use_single_thread"))
{
m_use_single_thread = config.find("use_single_thread").asBool();
yCInfo(JoypadControlServerParamsCOMPONENT) << "Parameter 'use_single_thread' using value:" << m_use_single_thread;
}
else
{
yCInfo(JoypadControlServerParamsCOMPONENT) << "Parameter 'use_single_thread' using DEFAULT value:" << m_use_single_thread;
}
prop_check.unput("use_single_thread");
}

/*
//This code check if the user set some parameter which are not check by the parser
//If the parser is set in strict mode, this will generate an error
Expand Down Expand Up @@ -144,9 +159,10 @@ std::string JoypadControlServer_ParamsParser::getDocumentationOfDeviceParam
doc = doc + std::string("'name': Prefix name of the ports opened by the JoypadControlServer\n");
doc = doc + std::string("'use_separate_ports': set it to 1 to use separate ports (buttons, axes, trackballs, hats) and 0 to stream all in one single port\n");
doc = doc + std::string("'profile': print the joypad data for debugging purpose\n");
doc = doc + std::string("'use_single_thread': If true, the device is updated when calling updateService rather than using a separate thread.\n");
doc = doc + std::string("\n");
doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n");
doc = doc + " yarpdev --device JoypadControlServer --period 0.01 --name /robotName/joypad --use_separate_ports true --profile false\n";
doc = doc + " yarpdev --device JoypadControlServer --period 0.01 --name /robotName/joypad --use_separate_ports true --profile false --use_single_thread false\n";
doc = doc + std::string("Using only mandatory params:\n");
doc = doc + " yarpdev --device JoypadControlServer --name /robotName/joypad\n";
doc = doc + std::string("=============================================\n\n"); return doc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// This is an automatically generated file. Please do not edit it.
// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON.

// Generated on: Thu Mar 7 17:59:50 2024
// Generated on: Mon Apr 8 10:24:20 2024


#ifndef JOYPADCONTROLSERVER_PARAMSPARSER_H
Expand All @@ -29,10 +29,11 @@
* | - | name | string | - | /robotName/joypad | 1 | Prefix name of the ports opened by the JoypadControlServer | - |
* | - | use_separate_ports | bool | - | true | 0 | set it to 1 to use separate ports (buttons, axes, trackballs, hats) and 0 to stream all in one single port | - |
* | - | profile | bool | - | false | 0 | print the joypad data for debugging purpose | - |
* | - | use_single_thread | bool | - | false | 0 | If true, the device is updated when calling updateService rather than using a separate thread. | - |
*
* The device can be launched by yarpdev using one of the following examples (with and without all optional parameters):
* \code{.unparsed}
* yarpdev --device JoypadControlServer --period 0.01 --name /robotName/joypad --use_separate_ports true --profile false
* yarpdev --device JoypadControlServer --period 0.01 --name /robotName/joypad --use_separate_ports true --profile false --use_single_thread false
* \endcode
*
* \code{.unparsed}
Expand Down Expand Up @@ -62,11 +63,13 @@ class JoypadControlServer_ParamsParser : public yarp::dev::IDeviceDriverParams
const std::string m_name_defaultValue = {"/robotName/joypad"};
const std::string m_use_separate_ports_defaultValue = {"true"};
const std::string m_profile_defaultValue = {"false"};
const std::string m_use_single_thread_defaultValue = {"false"};

double m_period = {0.01};
std::string m_name = {"/robotName/joypad"};
bool m_use_separate_ports = {true};
bool m_profile = {false};
bool m_use_single_thread = {false};

bool parseParams(const yarp::os::Searchable & config) override;
std::string getDeviceClassName() const override { return m_device_classname; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
* | | name | string | - | /robotName/joypad | Yes | Prefix name of the ports opened by the JoypadControlServer | - |
* | | use_separate_ports | bool | - | true | No | set it to 1 to use separate ports (buttons, axes, trackballs, hats) and 0 to stream all in one single port | - |
* | | profile | bool | - | false | No | print the joypad data for debugging purpose | - |
* | | use_single_thread | bool | - | false | No | If true, the device is updated when calling updateService rather than using a separate thread. | - |
3 changes: 1 addition & 2 deletions src/libYARP_dev/src/yarp/dev/Drivers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,6 @@ DriverCreator* Drivers::Private::load(const char *name) {
}

static std::string terminatorKey;
static bool terminated = false;
static void handler (int)
{
Time::useSystemClock();
Expand All @@ -343,7 +342,6 @@ static void handler (int)
}
if (!terminatorKey.empty()) {
yCInfo(DRIVERS, "[try %d of 3] Trying to shut down %s", ct, terminatorKey.c_str());
terminated = true;
Terminator::terminateByName(terminatorKey.c_str());
} else {
yCInfo(DRIVERS, "Aborting...");
Expand Down Expand Up @@ -529,6 +527,7 @@ int Drivers::yarpdev(int argc, char *argv[]) {
service = nullptr;
}
}
bool terminated = false;
while (dd.isValid() && !(terminated||(terminee&&terminee->mustQuit()))) {
if (service!=nullptr) {
double now = Time::now();
Expand Down
Loading