Skip to content

Commit

Permalink
Run server and client in the same process
Browse files Browse the repository at this point in the history
Signed-off-by: ahcorde <[email protected]>
  • Loading branch information
ahcorde committed Apr 27, 2021
1 parent f4a3ea4 commit f5cbc24
Show file tree
Hide file tree
Showing 17 changed files with 307 additions and 55 deletions.
2 changes: 2 additions & 0 deletions include/ignition/gazebo/Server.hh
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ namespace ignition
/// \brief Destructor
public: ~Server();

public: EntityComponentManager &GetEntityComponentManager();

/// \brief Set the update period. The update period is the wall-clock time
/// between ECS updates.
/// Note that this is different from the simulation update rate. ECS
Expand Down
12 changes: 11 additions & 1 deletion include/ignition/gazebo/ServerConfig.hh
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,16 @@ namespace ignition
/// \return The full contents of the SDF string, or empty string.
public: std::string SdfString() const;

/// \brief Set if the server and GUI should run in the same process.
/// \param[in] _sameProcessAsGUI True if the server and GUI will run in
/// the same process, False otherwise
public: void SetSameProcessAsGUI(const bool &_sameProcessAsGUI);

/// \brief Get if the server and GUI are running in the same process
/// \return True if the server and GUI will run in
/// the same process, False otherwise
public: bool SameProcessAsGUI() const;

/// \brief Set the update rate in Hertz. Value <=0 are ignored.
/// \param[in] _hz The desired update rate of the server in Hertz.
public: void SetUpdateRate(const double &_hz);
Expand Down Expand Up @@ -426,7 +436,7 @@ namespace ignition
/// \return A list of plugins to load, based on above ordering
std::list<ServerConfig::PluginInfo>
IGNITION_GAZEBO_VISIBLE
loadPluginInfo(bool _isPlayback = false);
loadPluginInfo(bool _isPlayback = false, bool _sameProcessAsGUI = false);
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion include/ignition/gazebo/gui/Gui.hh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <ignition/gui/Application.hh>

#include "ignition/gazebo/config.hh"
#include "ignition/gazebo/EntityComponentManager.hh"
#include "ignition/gazebo/gui/Export.hh"

namespace ignition
Expand All @@ -42,7 +43,9 @@ namespace gui
/// \param[in] _guiConfig The GUI configuration file. If nullptr, the default
/// configuration from IGN_HOMEDIR/.ignition/gazebo/gui.config will be used.
IGNITION_GAZEBO_GUI_VISIBLE int runGui(int &_argc, char **_argv,
const char *_guiConfig);
const char *_guiConfig,
EntityComponentManager &_ecm,
bool sameProcess);

/// \brief Create a Gazebo GUI application
/// \param[in] _argc Number of command line arguments (Used when running
Expand All @@ -63,6 +66,8 @@ namespace gui
IGNITION_GAZEBO_GUI_VISIBLE
std::unique_ptr<ignition::gui::Application> createGui(
int &_argc, char **_argv, const char *_guiConfig,
EntityComponentManager &_ecm,
bool sameProcess,
const char *_defaultGuiConfig = nullptr, bool _loadPluginsFromSdf = true);

} // namespace gui
Expand Down
4 changes: 3 additions & 1 deletion include/ignition/gazebo/gui/GuiRunner.hh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <ignition/utils/ImplPtr.hh>

#include "ignition/gazebo/config.hh"
#include "ignition/gazebo/EntityComponentManager.hh"
#include "ignition/gazebo/gui/Export.hh"

namespace ignition
Expand All @@ -45,7 +46,8 @@ class IGNITION_GAZEBO_GUI_VISIBLE GuiRunner : public QObject
/// \param[in] _worldName World name.
/// \todo Move to src/gui on v6.
public: explicit IGN_DEPRECATED(5.0) GuiRunner(
const std::string &_worldName);
const std::string &_worldName, EntityComponentManager &_ecm,
bool sameProcess);

/// \brief Destructor
public: ~GuiRunner() override;
Expand Down
2 changes: 1 addition & 1 deletion include/ignition/gazebo/rendering/RenderUtil.hh
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE {
class IGNITION_GAZEBO_RENDERING_VISIBLE RenderUtil
{
/// \brief Constructor
public: explicit RenderUtil();
public: explicit RenderUtil(bool updateNewEntities);

/// \brief Destructor
public: ~RenderUtil();
Expand Down
8 changes: 8 additions & 0 deletions src/Server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,14 @@ Server::Server(const ServerConfig &_config)
/////////////////////////////////////////////////
Server::~Server() = default;

EntityComponentManager &Server::GetEntityComponentManager()
{
for (std::unique_ptr<SimulationRunner> &runner : this->dataPtr->simRunners)
{
return runner->EntityCompMgr();
}
}

/////////////////////////////////////////////////
bool Server::Run(const bool _blocking, const uint64_t _iterations,
const bool _paused)
Expand Down
21 changes: 19 additions & 2 deletions src/ServerConfig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,8 @@ class ignition::gazebo::ServerConfigPrivate
networkRole(_cfg->networkRole),
networkSecondaries(_cfg->networkSecondaries),
seed(_cfg->seed),
logRecordTopics(_cfg->logRecordTopics) { }
logRecordTopics(_cfg->logRecordTopics),
sameProcessAsGUI(_cfg->sameProcessAsGUI) { }

// \brief The SDF file that the server should load
public: std::string sdfFile = "";
Expand Down Expand Up @@ -301,6 +302,10 @@ class ignition::gazebo::ServerConfigPrivate

/// \brief Topics to record.
public: std::vector<std::string> logRecordTopics;

/// \brief Boolean to define if the server and gui run in the same process
/// True gui and server will run in the same process, False otherwise
public: bool sameProcessAsGUI;
};

//////////////////////////////////////////////////
Expand Down Expand Up @@ -346,6 +351,18 @@ std::string ServerConfig::SdfString() const
return this->dataPtr->sdfString;
}

//////////////////////////////////////////////////
void ServerConfig::SetSameProcessAsGUI(const bool &_sameProcessAsGUI)
{
this->dataPtr->sameProcessAsGUI = _sameProcessAsGUI;
}

//////////////////////////////////////////////////
bool ServerConfig::SameProcessAsGUI() const
{
return this->dataPtr->sameProcessAsGUI;
}

//////////////////////////////////////////////////
void ServerConfig::SetUpdateRate(const double &_hz)
{
Expand Down Expand Up @@ -824,7 +841,7 @@ ignition::gazebo::parsePluginsFromString(const std::string &_str)

/////////////////////////////////////////////////
std::list<ServerConfig::PluginInfo>
ignition::gazebo::loadPluginInfo(bool _isPlayback)
ignition::gazebo::loadPluginInfo(bool _isPlayback, bool _sameProcessAsGUI)
{
std::list<ServerConfig::PluginInfo> ret;

Expand Down
5 changes: 3 additions & 2 deletions src/SimulationRunner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ SimulationRunner::SimulationRunner(const sdf::World *_world,
{
ignmsg << "No systems loaded from SDF, loading defaults" << std::endl;
bool isPlayback = !this->serverConfig.LogPlaybackPath().empty();
auto plugins = ignition::gazebo::loadPluginInfo(isPlayback);
auto plugins = ignition::gazebo::loadPluginInfo(
isPlayback, this->serverConfig.SameProcessAsGUI());
this->LoadServerPlugins(plugins);
}

Expand Down Expand Up @@ -1172,7 +1173,7 @@ bool SimulationRunner::Paused() const
}

/////////////////////////////////////////////////
const EntityComponentManager &SimulationRunner::EntityCompMgr() const
EntityComponentManager &SimulationRunner::EntityCompMgr()
{
return this->entityCompMgr;
}
Expand Down
2 changes: 1 addition & 1 deletion src/SimulationRunner.hh
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ namespace ignition

/// \brief Get the EntityComponentManager
/// \return Reference to the entity component manager.
public: const EntityComponentManager &EntityCompMgr() const;
public: EntityComponentManager &EntityCompMgr();

/// \brief Return an entity with the provided name.
/// \details If multiple entities with the same name exist, the first
Expand Down
30 changes: 28 additions & 2 deletions src/cmd/cmdgazebo.rb.in
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ COMMANDS = { 'gazebo' =>
" which loads all models. It's always true \n"\
" with --network-role. \n"\
"\n"\
" --same-process Server and Client will run in the same process \n"\
"\n"\
" --network-role [arg] Participant role used in a distributed \n"\
" simulation environment. Role is one of \n"\
" [primary, secondary]. It implies --levels. \n"\
Expand Down Expand Up @@ -219,6 +221,7 @@ class Cmd
'log-compress' => 0,
'playback' => '',
'run' => 0,
'same-process' => 0,
'server' => 0,
'verbose' => '1',
'gui_config' => '',
Expand Down Expand Up @@ -261,6 +264,9 @@ class Cmd
opts.on('--levels') do
options['levels'] = 1
end
opts.on('--same-process') do
options['same-process'] = 1
end
opts.on('--record') do
options['record'] = 1
end
Expand Down Expand Up @@ -436,17 +442,37 @@ has properly set the DYLD_LIBRARY_PATH environment variables."
# Import the runGui function
Importer.extern 'int runGui(const char *)'

# Import the runCombined function
Importer.extern 'int runCombined(const char *, int, int, float, int,
const char *, int, int, const char *,
int, int, int, const char *, const char *,
const char *, const char *, const char *,
const char *, const char *)'

# If playback is specified, and the user has not specified a
# custom gui config, set the gui config to load the playback
# gui config
if (options['playback'] != '' and options['gui_config'] == '')
options['gui_config'] = "_playback_"
end

if options['same-process'] == 1

ENV['RMT_PORT'] = '1500'
Process.setproctitle('ign gazebo')
Importer.runCombined(parsed, options['iterations'], options['run'],
options['hz'], options['levels'], options['network_role'],
options['network_secondaries'], options['record'],
options['record-path'], options['record-resources'],
options['log-overwrite'], options['log-compress'],
options['playback'], options['physics_engine'],
options['render_engine_server'], options['render_engine_gui'],
options['file'], options['record-topics'].join(':'),
options['gui_config'])

# Neither the -s nor -g options were used, so run both the server
# and gui.
if options['server'] == 0 && options['gui'] == 0

elsif options['server'] == 0 && options['gui'] == 0
if plugin.end_with? ".dylib"
puts "`ign gazebo` currently only works with the -s argument on macOS.
See https://github.com/ignitionrobotics/ign-gazebo/issues/44 for more info."
Expand Down
14 changes: 10 additions & 4 deletions src/gui/Gui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@ namespace gui
//////////////////////////////////////////////////
std::unique_ptr<ignition::gui::Application> createGui(
int &_argc, char **_argv, const char *_guiConfig,
EntityComponentManager &_ecm, bool sameProcess,
const char *_defaultGuiConfig, bool _loadPluginsFromSdf)
{
auto &sharedEcm = _ecm;

ignition::common::SignalHandler sigHandler;
bool sigKilled = false;
sigHandler.AddCallback([&](const int /*_sig*/)
Expand Down Expand Up @@ -177,7 +180,7 @@ std::unique_ptr<ignition::gui::Application> createGui(
# pragma warning(push)
# pragma warning(disable: 4996)
#endif
auto runner = new ignition::gazebo::GuiRunner(worldsMsg.data(0));
auto runner = new ignition::gazebo::GuiRunner(worldsMsg.data(0), sharedEcm, sameProcess);
#ifndef _WIN32
# pragma GCC diagnostic pop
#else
Expand Down Expand Up @@ -241,7 +244,7 @@ std::unique_ptr<ignition::gui::Application> createGui(
# pragma warning(push)
# pragma warning(disable: 4996)
#endif
auto runner = new ignition::gazebo::GuiRunner(worldName);
auto runner = new ignition::gazebo::GuiRunner(worldName, sharedEcm, sameProcess);
#ifndef _WIN32
# pragma GCC diagnostic pop
#else
Expand Down Expand Up @@ -318,9 +321,12 @@ std::unique_ptr<ignition::gui::Application> createGui(
}

//////////////////////////////////////////////////
int runGui(int &_argc, char **_argv, const char *_guiConfig)
int runGui(int &_argc, char **_argv, const char *_guiConfig,
EntityComponentManager &_ecm, bool sameProcess)
{
auto app = gazebo::gui::createGui(_argc, _argv, _guiConfig);
auto &sharedEcm = _ecm;
auto app = gazebo::gui::createGui(_argc, _argv, _guiConfig,
sharedEcm, sameProcess);
if (nullptr != app)
{
// Run main window.
Expand Down
20 changes: 17 additions & 3 deletions src/gui/GuiRunner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,17 @@ using namespace gazebo;
/////////////////////////////////////////////////
class ignition::gazebo::GuiRunner::Implementation
{

public: explicit Implementation(gazebo::EntityComponentManager &_ecm)
: ecm(_ecm){}

/// \brief Update the plugins.
public: void UpdatePlugins();

/// \brief Entity-component manager.
public: gazebo::EntityComponentManager ecm;
public: gazebo::EntityComponentManager &ecm;

public: bool sameProcess;

/// \brief Transport node.
public: transport::Node node{};
Expand All @@ -61,10 +67,15 @@ class ignition::gazebo::GuiRunner::Implementation
};

/////////////////////////////////////////////////
GuiRunner::GuiRunner(const std::string &_worldName)
: dataPtr(utils::MakeUniqueImpl<Implementation>())
GuiRunner::GuiRunner(const std::string &_worldName,
EntityComponentManager &_ecm, bool _sameProcess)
: dataPtr(utils::MakeUniqueImpl<Implementation>(_ecm))
{
this->dataPtr->sameProcess = _sameProcess;

this->setProperty("worldName", QString::fromStdString(_worldName));
this->setProperty("sameProcess",
QString::fromStdString(std::to_string(_sameProcess)));

auto win = gui::App()->findChild<ignition::gui::MainWindow *>();
auto winWorldNames = win->property("worldNames").toStringList();
Expand Down Expand Up @@ -118,6 +129,9 @@ GuiRunner::~GuiRunner()
/////////////////////////////////////////////////
void GuiRunner::RequestState()
{
if (this->dataPtr->sameProcess)
return;

// set up service for async state response callback
std::string id = std::to_string(gui::App()->applicationPid());
std::string reqSrv =
Expand Down
Loading

0 comments on commit f5cbc24

Please sign in to comment.