roswasm
roswasm
is a C++ client library that defines similar interfaces to roscpp
,
and is available as part of roswasm_suite.
However, it enables your node to run in the web browser by compiling it to
Webassembly (wasm) using Emscripten. Communication with ROS happens through
rosbridge_websocket
. By depending on roswasm
in your catkin project,
it will automatically configure it to build using the Emscripten compiler and linker.
This enables building a roswasm
package as part of a larger catkin workspace,
enabling you to use message definitions from other packages, etc.
This is still early days for the project, but there is some CI and we are using
it for building a web GUI for our robot.
roswasm_suite also includes a GUI library
that facilitates writing similar web GUIs, based on imgui
I’ll include some parts of the README here to give an overview:
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
- library that serializes ROS messages to and from json -
roswasm
- contains theroswasm
client library and configures cmake to build dependent packages using Emscripten. It supports publishers, subscribers, service clients and timers -
roswasm_tutorials
- contains examples corresponding totalker
,listener
andtimers
ofroscpp
-
roswasm_webgui
- a proof of concept implementation of a ROS GUI library based onroswasm
andimgui
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.
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