roswasm_suite¶
Libraries for compiling C++ ROS nodes to Webassembly using Emscripten. Allows you to write C++ ROS nodes similar to how you would otherwise, and to then have them run in a webbrowser and communicate with ROS through rosbridge_websocket
.
Dependencies¶
Emscripten tested with version
1.39.10
but latest should dorosbridge_suite after the commit adding cbor-raw compression, latest
develop
should do: .. code-block:: bashgit clone https://github.com/RobotWebTools/rosbridge_suite -b develop # in workspace src folder
Building¶
catkin build
is recommended, since catkin_make
might leak configurations to other packages.
Make sure to source the Emscripten environment
before building the package:
source /path/to/emsdk/emsdk_env.sh
catkin build
Packages¶
- ``roscpp_json_serialize` <https://github.com/nilsbore/roswasm_suite/tree/master/roscpp_json_serialize>`_ - library that serializes ROS messages to and from json
- ``roswasm` <https://github.com/nilsbore/roswasm_suite/tree/master/roswasm>`_ - contains the
roswasm
client library and configures cmake to build dependent packages using Emscripten. It supports publishers, subscribers, service clients and timers - ``roswasm_tutorials` <https://github.com/nilsbore/roswasm_suite/tree/master/roswasm_tutorials>`_ - contains examples corresponding to
talker
,listener
andtimers
of ``roscpp` <https://github.com/ros/ros_tutorials/tree/noetic-devel/roscpp_tutorials>`_ - ``roswasm_webgui` <https://github.com/nilsbore/roswasm_suite/tree/master/roswasm_webgui>`_ - a proof of concept implementation of a ROS GUI library based on
roswasm
and ``imgui` <https://github.com/ocornut/imgui>`_
Writing a roswasm node¶
The roswasm
client library presents an API similar to roscpp
, with the
main differences being that most interfaces are heap allocated, and that Emscripten
manages the event loop. Below is a shortened version of the corresponding
listener
example implementation.
#include <emscripten.h>
#include <roswasm/roswasm.h>
#include <std_msgs/String.h>
roswasm::NodeHandle* n;
roswasm::Subscriber* sub;
void chatterCallback(const std_msgs::String& msg)
{
printf("I heard: [%s]\n", msg.data.c_str());
}
void loop() {}
extern "C" int main(int argc, char** argv)
{
n = new roswasm::NodeHandle();
sub = n->subscribe<std_msgs::String>("chatter", chatterCallback);
emscripten_set_main_loop(loop, 10, 1);
return 0;
}
For more complete examples, see the ``roswasm_tutorials` package <https://github.com/nilsbore/roswasm_suite/tree/master/roswasm_tutorials>`_.
Building a roswasm package¶
The roswasm
library uses catkin
to build an emscripten project.
All you have to do in your package that is using roswasm
is to add
it as a dependency in your cmake
file and link against
${roswasm_LIBRARIES}
. It will automatically set the Emscripten
em++
compiler as the default for building and linking nodes.
Note that you have to install and source the emscripten SDK before
building your workspace. The following minimal cmake
file includes
a guard to check that Emscripten is present.
cmake_minimum_required(VERSION 2.8.3)
project(listener)
find_package(catkin REQUIRED COMPONENTS roscpp roswasm std_msgs)
catkin_package()
if (DEFINED ENV{EMSDK})
include_directories(${catkin_INCLUDE_DIRS})
add_executable(listener src/listener.cpp)
set_target_properties(listener PROPERTIES OUTPUT_NAME "listener.js")
target_link_libraries(listener ${roswasm_LIBRARIES})
configure_file(www/listener.html ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_BIN_DESTINATION}/listener.html COPYONLY)
endif()
Running an Emscripten node¶
Run node separately¶
Before starting any of the roswasm nodes, you need to have one instance of rosbridge_websocket
running:
roslaunch rosbridge_server rosbridge_websocket.launch
After building your node, you can run it similar to the following command:
rosrun roswasm run.py _pkg:=roswasm_tutorials _node:=listener.html _display_port:=8080
This will start a webserver and allow you to view the page at localhost:8080
.
If you want to see the output from the node, open the browser debug console.
Combined launch file (alternative)¶
There is a also a convenience launch file to run both rosbridge_websocket
as well as your roswasm
node at the same time:
roslaunch roswasm run_server.launch pkg:=roswasm_tutorials node:=listener.html