Skip to content

Commit

Permalink
Initial commit of rosbridge_library
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathanMace committed Jul 24, 2012
1 parent c1d4261 commit 9a92221
Show file tree
Hide file tree
Showing 20 changed files with 1,908 additions and 0 deletions.
30 changes: 30 additions & 0 deletions rosbridge_library/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
cmake_minimum_required(VERSION 2.4.6)
include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)

# Set the build type. Options are:
# Coverage : w/ debug symbols, w/o optimization, w/ code-coverage
# Debug : w/ debug symbols, w/o optimization
# Release : w/o debug symbols, w/ optimization
# RelWithDebInfo : w/ debug symbols, w/ optimization
# MinSizeRel : w/o debug symbols, w/ optimization, stripped binaries
#set(ROS_BUILD_TYPE RelWithDebInfo)

rosbuild_init()

#set the default path for built executables to the "bin" directory
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
#set the default path for built libraries to the "lib" directory
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

#uncomment if you have defined messages
#rosbuild_genmsg()
#uncomment if you have defined services
#rosbuild_gensrv()

#common commands for building c++ executables and libraries
#rosbuild_add_library(${PROJECT_NAME} src/example.cpp)
#target_link_libraries(${PROJECT_NAME} another_library)
#rosbuild_add_boost_directories()
#rosbuild_link_boost(${PROJECT_NAME} thread)
#rosbuild_add_executable(example examples/example.cpp)
#target_link_libraries(example ${PROJECT_NAME})
14 changes: 14 additions & 0 deletions rosbridge_library/mainpage.dox
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
\mainpage
\htmlinclude manifest.html

\b rosbridge2

<!--
Provide an overview of your package.
-->

-->


*/
14 changes: 14 additions & 0 deletions rosbridge_library/manifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<package>
<description brief="rosbridge_library">

rosbridge_library

</description>
<author>Jonathan Mace</author>
<license>BSD</license>
<review status="unreviewed" notes=""/>
<url>http://ros.org/wiki/rosbridge_library</url>

</package>


Empty file.
Empty file.
108 changes: 108 additions & 0 deletions rosbridge_library/src/rosbridge_library/capabilities/advertise.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
from rosbridge_library.capability import Capability
from rosbridge_library.internal.publishers import manager


class Registration():
""" Keeps track of how many times a client has requested to advertise
a publisher.
A client could advertise and unadvertise a topic multiple times, and we
must make sure that the underlying publisher is only created and destroyed
at the appropriate moments
"""

def __init__(self, client_id, topic):
# Initialise variables
self.client_id = client_id
self.topic = topic
self.clients = {}

def unregister(self):
manager.unregister(self.client_id, self.topic)

def register_advertisement(self, msg_type, adv_id=None):
# Register with the publisher manager, propagating any exception
manager.register(self.client_id, self.topic, msg_type)

self.clients[adv_id] = True

def unregister_advertisement(self, adv_id=None):
if adv_id is None:
self.clients.clear()
elif adv_id in self.clients:
del self.clients[adv_id]

def is_empty(self):
return len(self.clients) == 0


class Advertise(Capability):

advertise_msg_fields = [(True, "topic", unicode), (True, "type", unicode)]
unadvertise_msg_fields = [(True, "topic", unicode)]

def __init__(self, protocol):
# Call superclas constructor
Capability.__init__(self, protocol)

# Register the operations that this capability provides
protocol.register_operation("advertise", self.advertise)
protocol.register_operation("unadvertise", self.unadvertise)

# Initialize class variables
self._registrations = {}

def advertise(self, message):
# Pull out the ID
aid = message.get("id", None)

# Process the message, catching any exceptions and logging them
try:
self._advertise(aid, message)
except Exception as exc:
self.protocol.log("error", "advertise: " + exc.message, aid)

def unadvertise(self, message):
# Pull out the ID
aid = message.get("id", None)

# Process the message, catching any exceptions and logging them
try:
self._unadvertise(aid, message)
except Exception as exc:
self.protocol.log("error", "unadvertise: " + exc.message, aid)

def _advertise(self, aid, msg):
self.basic_type_check(msg, self.advertise_msg_fields)
topic = msg["topic"]
msg_type = msg["type"]

# Create the Registration if one doesn't yet exist
if not topic in self._registrations:
client_id = self.protocol.client_id
self._registrations[topic] = Registration(client_id, topic)

# Register, propagating any exceptions
self._registrations[topic].register_advertisement(msg_type, aid)

def _unadvertise(self, aid, msg):
self.basic_type_check(msg, self.unadvertise_msg_fields)
topic = msg["topic"]

# Now unadvertise the topic
if topic not in self._registrations:
return
self._registrations[topic].unregister_advertisement(aid)

# Check if the registration is now finished with
if self._registrations[topic].is_empty():
self._registrations[topic].unregister()
del self._registrations[topic]

def finish(self):
for registration in self._registrations.values():
registration.unregister()
self._registrations.clear()
self.protocol.unregister_operation("advertise")
self.protocol.unregister_operation("unadvertise")
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from functools import partial
from rosbridge_library.capability import Capability
from rosbridge_library.internal.services import ServiceCaller


class CallService(Capability):

call_service_msg_fields = [(True, "service", unicode),
(False, "fragment_size", int), (False, "compression", unicode)]

def __init__(self, protocol):
# Call superclas constructor
Capability.__init__(self, protocol)

# Register the operations that this capability provides
protocol.register_operation("call_service", self.call_service)

def call_service(self, message):
# Pull out the ID
cid = message.get("id", None)

# Process the message, catching any exceptions and logging them
try:
self._call_service(cid, message)
except Exception as exc:
self.protocol.log("error", "call_service: " + exc.message, cid)
raise

def _call_service(self, cid, message):
# Typecheck the args
self.basic_type_check(message, self.call_service_msg_fields)

# Create the callbacks
service = message["service"]
fragment_size = message.get("fragment_size", None)
compression = message.get("compression", "none")
args = message.get("args", [])

s_cb = partial(self._success, cid, service, fragment_size, compression)
e_cb = partial(self._failure, cid)

# Kick off the service caller thread
ServiceCaller(service, args, s_cb, e_cb).start()

def _success(self, cid, service, fragment_size, compression, message):
outgoing_message = {
"op": "service_response",
"service": service,
"values": message
}
if cid is not None:
outgoing_message["cid"] = cid
# TODO: fragmentation, compression
self.protocol.send(outgoing_message)

def _failure(self, cid, exc):
self.protocol.log("error", "call_service: " + exc.message, cid)
41 changes: 41 additions & 0 deletions rosbridge_library/src/rosbridge_library/capabilities/publish.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from rosbridge_library.capability import Capability
from rosbridge_library.internal.publishers import manager


class Publish(Capability):

publish_msg_fields = [(True, "topic", unicode)]

def __init__(self, protocol):
# Call superclas constructor
Capability.__init__(self, protocol)

# Register the operations that this capability provides
protocol.register_operation("publish", self.publish)

def publish(self, message):
# Pull out the ID
pid = message.get("id", None)

# Process the message, catching any exceptions and logging them
try:
self._publish(message)
except Exception as exc:
self.protocol.log("error", "publish: " + exc.message, pid)
raise

def _publish(self, message):
self.basic_type_check(message, self.publish_msg_fields)
topic = message["topic"]

# Register as a publishing client, propagating any exceptions
client_id = self.protocol.client_id
manager.register(client_id, topic)

# Get the message if one was provided
msg = message.get("msg", {})

manager.publish(client_id, topic, msg)

def finish(self):
manager.unregister_all(self.protocol.client_id)
Loading

0 comments on commit 9a92221

Please sign in to comment.