roslibpy 中文文档

作者:Gramazio Kohler Research
译者:Wu Hsin
授权:该文档遵循 CC BY-SA 4.0 许可协议。

注解

该文档为非官方中文文档。 官方文档可以在此获得

Python ROS Bridge library,简称 roslibpy,提供了用 Python 或 IronPython 与开源机器人平台 ROS 进行通信的一个途径。该项目使用 WebSockets 与 rosbridge 2.0 建立连接,提供了 publishing、subscribing、service calls、actionlib、TF 等 ROS 中的基本功能。

rospy 不同,该项目不需要在本地搭建 ROS 环境,为 Linux 以外的平台使用 ROS 带来了方便。

roslibpy 的 API 构建参考了 roslibjs 的结构。

截至 2019 年 6 月 8 日,roslibpy 的版本更新至 0.6.0,亦为本中文文档所对应版本。

简介

Python ROS Bridge library,简称 roslibpy,提供了用 Python 或 IronPython 与开源机器人平台 ROS 进行通信的一个途径。该项目使用 WebSockets 与 rosbridge 2.0 建立连接,提供了 publishing、subscribing、service calls、actionlib、TF 等 ROS 中的基本功能。

rospy 不同,该项目不需要在本地搭建 ROS 环境,为 Linux 以外的平台使用 ROS 带来了方便。

roslibpy 的 API 构建参考了 roslibjs 的结构。

主要特性

  • 话题 (Topic) 的发布和订阅;
  • 服务 (Service) 的发布和查询;
  • ROS 参数管理 (get/set/delete);
  • ROS API 服务;
  • Actionlib 支持;
  • 通过 tf2_web_republisher 实现 TF Client。

Roslibpy 可以在 Python 2.7、Python 3.x 和 IronPython 2.7 上运行。

安装

使用pip命令安装 roslibpy:

pip install roslibpy

对于 IronPython 来说,pip命令略有不同:

ipy -X:Frames -m pip install --user roslibpy

文档

完整版英文官方文档见此

本文档为中文非官方文档。

贡献

确保您的本地环境配置正确:

  • 将仓库 roslibpy 克隆到本地;

  • 创建一个虚拟环境;

  • 安装开发依赖:

    pip install -r requirements-dev.txt
    

现在你可以开始编程了!

在开发过程中,使用 pyinvoke 来简化重复操作:

  • invoke clean: 清除所有生成的内容;
  • invoke check: 运行多种代码和文档风格检查;
  • invoke docs: 生成文档;
  • invoke test: 用一个命令迅速运行所有的测试和检查;
  • invoke: 显示可供调用的任务。

更多的细节请参考贡献者指南

发布项目

准备好发布 roslibpy 的新版本了吗?接下来是发布新版本的步骤:

  • 我们使用 semver,即我们按照如下方式迭代版本:

    • patch: 修复 BUG;
    • minor: 增加向下兼容的 Feature;
    • major: 向下兼容的修改。
  • 所有的更改都要记录在 CHANGELOG.rst 中!

  • 准备好了吗?用下面的命令来发布新版本:

    invoke release [patch|minor|major]
    
  • Profit!

Credits

本模块是基于 roslibjs 实现的,在很大程度上,它是到 Python 的逐行移植,只在其它惯用代码范式更有意义的地方才进行修改,所以很大一部分功劳要归于 roslibjs 的作者

快速上手

roslibpy 上手非常简单。在接下来的例子中你将看到如何使用它与一个 ROS 环境相连接。

注解

在连接的过程中,确保在你网络中的 ROS 服务器配置并打开了 rosbridge serverTF2 web republisher(具体请戳 ROS 设置

这些例子假定了 ROS 服务器运行在同一台主机上。对于不在同一台主机的情况,只需要将host参数从'localhost'改为 ROS master 的 IP 地址

注解

port参数必须设定为9090,因为rosbridge的默认端口号是9090。如果想改变端口号,可参考这里

第一个例子

用以下命令导入roslibpy:

>>> import roslibpy

用以下命令初始化连接:

>>> ros = roslibpy.Ros(host='localhost', port=9090)
>>> ros.run()

是不是很简单?

让我们检查一下连接状态:

>>> ros.is_connected
True

耶( •̀ ω •́ )y 我们的第一个例子成功跑通!

融会贯通

让我们以 Python 文件的形式建立一个完整的例子。

新建一个文件并命名为ros-hello-world.py,然后复制粘贴以下内容:

import roslibpy

client = roslibpy.Ros(host='localhost', port=9090)
client.run()
print('Is ROS connected?', client.is_connected)
client.terminate()

在命令行中输入以下命令运行该程序:

$ python ros-hello-world.py

这个程序运行起来之后,会尝试建立与 ROS 的连接,连接建立后打印输出信息,并终止连接。

控制事件循环

在之前的例子里,我们通过调用run()来开启与 ROS 的连接,这样会在后台开启一个事件循环。在某些情况下,我们希望在前台更明确地处理主事件循环,roslibpy.Ros 提供了一个run_forever()方法来做这件事。

如果我们如果使用这个方法启动事件循环,则需要事先设置好所有连接处理配置。我们使用roslibpy.Ros.on_ready()来做这件事。

接下来的代码片段用run_forever()on_ready()实现了与之前的例子同样的功能:

from __future__ import print_function
import roslibpy

client = roslibpy.Ros(host='localhost', port=9090)
client.on_ready(lambda: print('Is ROS connected?', client.is_connected))
client.run_forever()

注解

run()run_forever()的区别在于,前者新开一个单独的线程来处理事件,而后者会阻塞当前线程。

Hello World: 话题(Topics)

ROS 中的Hello World例子是开启两个节点,并利用话题的订阅/发布来建立通讯。这两个节点(一个 talker 和一个 listener)非常简单,但是透过它们可以便于理解在 ROS 框架下的分布式系统中,两个进程之间的通信是如何工作的。

接下来,我们用 roslibpy 来建立一个简单的话题通讯。

一个 talker 节点

接下来的例子是开启一个 ROS 节点并循环发布信息(按下Ctrl+C来终止)。

import time

import roslibpy

client = roslibpy.Ros(host='localhost', port=9090)
client.run()

talker = roslibpy.Topic(client, '/chatter', 'std_msgs/String')

while client.is_connected:
    talker.publish(roslibpy.Message({'data': 'Hello World!'}))
    print('Sending message...')
    time.sleep(1)

talker.unadvertise()

client.terminate()

注解

这里以 ROS 中的 std_msgs/String 消息类型为例,其它消息类型也可以利用 Python 字典的方式构建,参考这个例子

一个 listener 节点

Listener 端的代码如下:

from __future__ import print_function
import roslibpy

client = roslibpy.Ros(host='localhost', port=9090)
client.run()

listener = roslibpy.Topic(client, '/chatter', 'std_msgs/String')
listener.subscribe(lambda message: print('Heard talking: ' + message['data']))

try:
    while True:
        pass
except KeyboardInterrupt:
    client.terminate()

运行例程

打开一个终端,开启 talker 节点:

$ python ros-hello-world-talker.py

打开另一个终端,开启 listener 节点:

$ python ros-hello-world-listener.py

注解

两个文件的位置不必在一起,它们可以在不同的路径、甚至不同的计算机中,只要保证是同一个 Ros master 即可。

使用服务(Services)

节点之间的另一种通讯方式是通过 ROS 服务来进行。

服务一般需要定义请求和回应的类型,为了简单,下面的例子使用了现成的get_loggers服务:

import roslibpy

client = roslibpy.Ros(host='localhost', port=9090)
client.run()

service = roslibpy.Service(client, '/rosout/get_loggers', 'roscpp/GetLoggers')
request = roslibpy.ServiceRequest()

print('Calling service...')
result = service.call(request)
print('Service response: {}'.format(result['loggers']))

client.terminate()

创建服务(Services)

只要服务类型的定义存在于您的 ROS 环境中,就可以创建新服务。

下面的例子展示了如何创建一个简单的服务,它使用ROS 中定义的标准服务类型之一(std_srvs/SetBool):

import roslibpy

def handler(request, response):
    print('Setting speed to {}'.format(request['data']))
    response['success'] = True
    return True

client = roslibpy.Ros(host='localhost', port=9090)

service = roslibpy.Service(client, '/set_ludicrous_speed', 'std_srvs/SetBool')
service.advertise(handler)
print('Service advertised.')

client.run_forever()
client.terminate()

下载该脚本,并输入如下命令:

$ python ros-service.py

程序开始运行,期间服务会一直处于活动状态(按下Ctrl+C来终止)。

不要关闭这个服务,下载并运行以下代码示例来调用服务,以验证服务是否正常工作:

下载后在一个新的终端中键入以下命令:

$ python ros-service-call-set-bool.py

注解

现在您已经掌握了 roslibpy 的基础知识,更多细节请查看 API 文档

Actions

除了话题和服务之外,ROS还提供 Actions,它们被用于长时间运行的任务,比如导航,因为它们是非阻塞的,并且允许任务执行时被抢占和取消。

roslibpy 既支持 action 客户端,也可以通过 roslibpy.actionlib.SimpleActionServer提供 action 服务器。

下面的例子使用斐波那契 action,该 action 的定义可在 actionlib_tutorials 中查看。

Action 服务器

让我们从斐波那契服务器的定义开始:

import roslibpy
import roslibpy.actionlib

client = roslibpy.Ros(host='localhost', port=9090)
server = roslibpy.actionlib.SimpleActionServer(client, '/fibonacci', 'actionlib_tutorials/FibonacciAction')

def execute(goal):
    print('Received new fibonacci goal: {}'.format(goal['order']))

    seq = [0, 1]

    for i in range(1, goal['order']):
        if server.is_preempt_requested():
            server.set_preempted()
            return

        seq.append(seq[i] + seq[i - 1])
        server.send_feedback({'sequence': seq})

    server.set_succeeded({'sequence': seq})


server.start(execute)
client.run_forever()

下载后键入以下命令:

$ python ros-action-server.py

在程序运行时,action 服务器将保持活动状态(按下Ctrl+C来终止)。

如果您想在下一个示例中测试这个窗口,请不要关闭它。

Action 客户端

现在,让我们看看如何为新创建的服务器编写一个 action 客户端。

下面的程序显示了一个简单的 action 客户端:

from __future__ import print_function
import roslibpy
import roslibpy.actionlib

client = roslibpy.Ros(host='localhost', port=9090)
client.run()

action_client = roslibpy.actionlib.ActionClient(client,
                                                '/fibonacci',
                                                'actionlib_tutorials/FibonacciAction')

goal = roslibpy.actionlib.Goal(action_client,
                               roslibpy.Message({'order': 8}))

goal.on('feedback', lambda f: print(f['sequence']))
goal.send()
result = goal.wait(10)
action_client.dispose()

print('Result: {}'.format(result['sequence']))

下载后键入以下命令:

$ python ros-action-client.py

您将立即看到我们的 action 服务器的所有中间计算,并在最后一行显示生成的斐波那契数列。

这个例子非常简单,使用了 roslibpy.actionlib.Goal.wait() 函数,以使代码更易于阅读。一个更鲁棒的处理方法是使用回调把结果连接到 result 事件。

API 文档

此模块依赖 Robot Web Tools 所开发的 ROS bridge suite, 通过 WebSockets 实现与 ROS 的交互。

ROS bridge protocol 使用 JSON 格式信息传输 publishing, subscribing, service calls, actionlib, TF 等 ROS 中的功能。

ROS 设置

使用本模块,必须在 ROS 环境中配置并运行rosbridge

首次连接之前,在 ROS master所在环境用以下命令安装rosbridge suite:

sudo apt-get install -y ros-kinetic-rosbridge-server
sudo apt-get install -y ros-kinetic-tf2-web-republisher

在以后的每次连接之前,都要确保预先开启了以下服务:

roslaunch rosbridge_server rosbridge_websocket.launch
rosrun tf2_web_republisher tf2_web_republisher

注解

执行roslaunch命令时,会自动运行roscore命令,因此使用启动文件运行节点时不需要新开终端运行roscore

连接 ROS

与 ROS 的连接是由Ros类来处理的。除了连接和信息处理,在需要的时候它也会自动重连。

其他需要与 ROS 进行连接的类会将此实例作为其构造函数的参数接收。

class roslibpy.Ros(host, port=None, is_secure=False)

Connection manager to ROS server.

call_in_thread(callback)

Call the given function in a thread.

The threading implementation is deferred to the factory.

Args:
callback (callable): Callable function to be invoked.
call_later(delay, callback)

Call the given function after a certain period of time has passed.

Args:
delay (int): Number of seconds to wait before invoking the callback. callback (callable): Callable function to be invoked when ROS connection is ready.
close()

Disconnect from ROS master.

connect()

Connect to ROS master.

emit(event_name, *args)

Trigger a named event.

get_action_servers(callback, errback=None)

Retrieve list of action servers in ROS.

get_message_details(message_type, callback, errback=None)

Retrieve details of a message type in ROS.

get_node_details(node, callback, errback=None)

Retrieve list subscribed topics, publishing topics and services of a specific node name.

get_nodes(callback, errback=None)

Retrieve list of active node names in ROS.

get_params(callback, errback=None)

Retrieve list of param names from the ROS Parameter Server.

get_service_request_details(type, callback, errback=None)

Retrieve details of a ROS Service Request.

get_service_response_details(type, callback, errback=None)

Retrieve details of a ROS Service Response.

get_service_type(service_name, callback, errback=None)

Retrieve the type of a service in ROS.

get_services(callback, errback=None)

Retrieve list of active service names in ROS.

get_services_for_type(service_type, callback, errback=None)

Retrieve list of services in ROS matching the specified type.

get_topic_type(topic, callback, errback=None)

Retrieve the type of a topic in ROS.

get_topics(callback, errback=None)

Retrieve list of topics in ROS.

get_topics_for_type(topic_type, callback, errback=None)

Retrieve list of topics in ROS matching the specified type.

id_counter

Generate an auto-incremental ID starting from 1.

Returns:
int: An auto-incremented ID.
is_connected

Indicate if the ROS connection is open or not.

Returns:
bool: True if connected to ROS, False otherwise.
off(event_name, callback=None)

Remove a callback from an arbitrary named event.

Args:
event_name (str): Name of the event from which to unsubscribe. callback: Callable function. If None, all callbacks of the event will be removed.
on(event_name, callback)

Add a callback to an arbitrary named event.

Args:
event_name (str): Name of the event to which to subscribe. callback: Callable function to be executed when the event is triggered.
on_ready(callback, run_in_thread=True)

Add a callback to be executed when the connection is established.

If a connection to ROS is already available, the callback is executed immediately.

Args:
callback: Callable function to be invoked when ROS connection is ready. run_in_thread (bool): True to run the callback in a separate thread, False otherwise.
run(timeout=None)

Kick-starts a non-blocking event loop.

Args:
timeout: Timeout to wait until connection is ready.
run_forever()

Kick-starts a blocking loop to wait for events.

Depending on the implementations, and the client applications, running this might be required or not.

send_on_ready(message)

Send message to the ROS Master once the connection is established.

If a connection to ROS is already available, the message is sent immediately.

Args:
message (Message): ROS Bridge Message to send.
send_service_request(message, callback, errback)

Send a service request to the ROS Master once the connection is established.

If a connection to ROS is already available, the request is sent immediately.

Args:
message (Message): ROS Bridge Message containing the request. callback: Callback invoked on successful execution. errback: Callback invoked on error.
terminate()

Signals the termination of the main event loop.

ROS 主要概念

话题

ROS 是一个通信框架。 在 ROS 里面, 不同的 节点 通过 messages 与其它节点通信。ROS messagesMessage类中实现,并通过Topics发布/订阅模型来传输。

class roslibpy.Message(values=None)

Message objects used for publishing and subscribing to/from topics.

A message is fundamentally a dictionary and behaves as one.

class roslibpy.Topic(ros, name, message_type, compression=None, latch=False, throttle_rate=0, queue_size=100, queue_length=0)

Publish and/or subscribe to a topic in ROS.

Args:
ros (Ros): Instance of the ROS connection. name (str): Topic name, e.g. /cmd_vel. message_type (str): Message type, e.g. std_msgs/String. compression (str): Type of compression to use, e.g. png. Defaults to None. throttle_rate (int): Rate (in ms between messages) at which to throttle the topics. queue_size (int): Queue size created at bridge side for re-publishing webtopics. latch (bool): True to latch the topic when publishing, False otherwise. queue_length (int): Queue length at bridge side used when subscribing.
advertise()

Register as a publisher for the topic.

is_advertised

Indicate if the topic is currently advertised or not.

Returns:
bool: True if advertised as publisher of this topic, False otherwise.
is_subscribed

Indicate if the topic is currently subscribed or not.

Returns:
bool: True if subscribed to this topic, False otherwise.
publish(message)

Publish a message to the topic.

Args:
message (Message): ROS Bridge Message to publish.
subscribe(callback)

Register a subscription to the topic.

Every time a message is published for the given topic, the callback will be called with the message object.

Args:
callback: Function to be called when messages of this topic are published.
unadvertise()

Unregister as a publisher for the topic.

unsubscribe()

Unregister from a subscribed the topic.

服务

除了话题的发布/订阅模型,ROS 还通过Services类提供了一套请求/响应模型。

class roslibpy.Service(ros, name, service_type)

Client/server of ROS services.

This class can be used both to consume other ROS services as a client, or to provide ROS services as a server.

Args:
ros (Ros): Instance of the ROS connection. name (str): Service name, e.g. /add_two_ints. service_type (str): Service type, e.g. rospy_tutorials/AddTwoInts.
advertise(callback)

Start advertising the service.

This turns the instance from a client into a server. The callback will be invoked with every request that is made to the service.

If the service is already advertised, this call does nothing.

Args:
callback: Callback invoked on every service call. It should accept two parameters: service_request and
service_response. It should return True if executed correctly, otherwise False.
call(request, callback=None, errback=None, timeout=None)

Start a service call.

The service can be used either as blocking or non-blocking. If the callback parameter is None, then the call will block until receiving a response. Otherwise, the service response will be returned in the callback.

Args:
request (ServiceRequest): Service request. callback: Callback invoked on successful execution. errback: Callback invoked on error. timeout: Timeout for the operation, in seconds. Only used if blocking.
Returns:
object: Service response if used as a blocking call, otherwise None.
is_advertised

Service servers are registered as advertised on ROS.

This class can be used to be a service client or a server.

Returns:
bool: True if this is a server, False otherwise.
unadvertise()

Unregister as a service server.

class roslibpy.ServiceRequest(values=None)

Request for a service call.

class roslibpy.ServiceResponse(values=None)

Response returned from a service call.

参数服务器

ROS 提供了用于在不同节点之间分享数据的参数服务器。该服务通过Param类来实现。

class roslibpy.Param(ros, name)

A ROS parameter.

Args:
ros (Ros): Instance of the ROS connection. name (str): Parameter name, e.g. max_vel_x.
delete(callback=None, errback=None)

Delete the parameter.

Args:
callback: Callable function to be invoked when the operation is completed. errback: Callback invoked on error.
get(callback=None, errback=None)

Fetch the current value of the parameter.

Args:
callback: Callable function to be invoked when the operation is completed. errback: Callback invoked on error.
set(value, callback=None, errback=None)

Set a new value to the parameter.

Args:
value: Value to set the parameter to. callback: Callable function to be invoked when the operation is completed. errback: Callback invoked on error.

Actionlib

另一个与 ROS 建立通讯的方法是通过 actionlib 栈。ROS 中的 Actions 允许执行可抢占任务,即可以被客户端中断的任务。

Actions 通过ActionClient类来使用,它可以添加Goals类。每个 goal 都可以发射出可侦听的事件,以便接收者对来自 Action 服务器的更新作出反应。可被发射的事件有四种:statusresultfeedbacktimeout

class roslibpy.actionlib.Goal(action_client, goal_message)

Goal for an action server.

After an event has been added to an action client, it will emit different events to indicate its progress:

  • status: fires to notify clients on the current state of the goal.
  • feedback: fires to send clients periodic auxiliary information of the goal.
  • result: fires to send clients the result upon completion of the goal.
  • timeout: fires when the goal did not complete in the specified timeout window.
Args:
action_client (ActionClient): Instance of the action client associated with the goal. goal_message (Message): Goal for the action server.
cancel()

Cancel the current goal.

is_finished

Indicate if the goal is finished or not.

Returns:
bool: True if finished, False otherwise.
send(result_callback=None, timeout=None)

Send goal to the action server.

Args:
timeout (int): Timeout for the goal's result expressed in seconds. callback (callable): Function to be called when a result is received. It is a shorthand for hooking on the result event.
wait(timeout=None)

Block until the result is available.

If timeout is None, it will wait indefinitely.

Args:
timeout (int): Timeout to wait for the result expressed in seconds.
Returns:
Result of the goal.
class roslibpy.actionlib.ActionClient(ros, server_name, action_name, timeout=None, omit_feedback=False, omit_status=False, omit_result=False)

Client to use ROS actions.

Args:
ros (Ros): Instance of the ROS connection. server_name (str): Action server name, e.g. /fibonacci. action_name (str): Action message name, e.g. actionlib_tutorials/FibonacciAction. timeout (int): Deprecated. Connection timeout, expressed in seconds.
add_goal(goal)

Add a goal to this action client.

Args:
goal (Goal): Goal to add.
cancel()

Cancel all goals associated with this action client.

dispose()

Unsubscribe and unadvertise all topics associated with this action client.

class roslibpy.actionlib.SimpleActionServer(ros, server_name, action_name)

Implementation of the simple action server.

The server emits the following events:

  • goal: fires when a new goal has been received by the server.
  • cancel: fires when the client has requested the cancellation of the action.
Args:
ros (Ros): Instance of the ROS connection. server_name (str): Action server name, e.g. /fibonacci. action_name (str): Action message name, e.g. actionlib_tutorials/FibonacciAction.
is_preempt_requested()

Indicate whether the client has requested preemption of the current goal.

send_feedback(feedback)

Send feedback.

Args:
feedback (dict): Dictionary of key/values of the feedback message.
set_preempted()

Set the current action to preempted (cancelled).

set_succeeded(result)

Set the current action state to succeeded.

Args:
result (dict): Dictionary of key/values to set as the result of the action.
start(action_callback)

Start the action server.

Args:
action_callback: Callable function to be invoked when a new goal is received. It takes one paramter containing the goal message.
class roslibpy.actionlib.GoalStatus

Valid goal statuses.

TF

ROS 提供了一个非常强大的转换库,叫做 TF2,允许用户随时跟踪多个坐标系。 roslibpy 库通过TFClient类与 tf2_web_republisher 连接来提供对它的访问。

class roslibpy.tf.TFClient(ros, fixed_frame='/base_link', angular_threshold=2.0, translation_threshold=0.01, rate=10.0, update_delay=50, topic_timeout=2000.0, server_name='/tf2_web_republisher', repub_service_name='/republish_tfs')

A TF Client that listens to TFs from tf2_web_republisher.

Args:
ros (Ros): Instance of the ROS connection. fixed_frame (str): Fixed frame, e.g. /base_link. angular_threshold (float): Angular threshold for the TF republisher. translation_threshold (float): Translation threshold for the TF republisher. rate (float): Rate for the TF republisher. update_delay (int): Time expressed in milliseconds to wait after a new subscription to update the TF republisher's list of TFs. topic_timeout (int): Timeout parameter for the TF republisher expressed in milliseconds. repub_service_name (str): Name of the republish tfs service, e.g. /republish_tfs.
dispose()

Unsubscribe and unadvertise all topics associated with this instance.

subscribe(frame_id, callback)

Subscribe to the given TF frame.

Args:
frame_id (str): TF frame identifier to subscribe to. callback (callable): A callable functions receiving one parameter with transform data.
unsubscribe(frame_id, callback)

Unsubscribe from the given TF frame.

Args:
frame_id (str): TF frame identifier to unsubscribe from. callback (callable): The callback function to remove.
update_goal()

Send a new service request to the tf2_web_republisher based on the current list of TFs.

贡献者指南

我们非常欢迎更多贡献者的参与到这个项目中来。

代码贡献

我们欢迎任何人 pull request!这里有一份改善代码的快速指南:

  1. Fork并 clone 这个仓库

  2. 用你喜欢的工具创建一个虚拟环境(如virtualenvconda等);

  3. 安装开发依赖:

    pip install -r requirements-dev.txt
    
  4. 确保所有的测试通过:

    invoke test
    
  5. 把你的更改更新到主分支(或从主分支分叉的其它分支);

  6. 再次确保所有的测试通过:

    invoke test
    
  7. 把你的名字添加到AUTHORS.rst里面;

  8. Commit+push你的改变到 GitHub 仓库;

  9. 通过 GitHub 页面新建一个pull request

在开发过程中,使用 pyinvoke 来简化重复操作:

  • invoke clean: 清除所有生成的内容;
  • invoke check: 运行多种代码和文档风格检查;
  • invoke docs: 生成文档;
  • invoke test: 用一个命令迅速运行所有的测试和检查;
  • invoke: 显示可供调用的任务。

文档贡献

文档总是多多益善,无论是作为介绍/示例/使用文档的一部分,还是 docstrings 里面的 API 文档。

文档使用 reStructuredText 撰写,并用 Sphinx 生成 HTML 格式的输出。

在你更改本地文档之后,运行以下命令来重新生成它:

invoke docs

报告 BUG

在你想要报告一个 BUG 的时候,请包括以下内容:

  • 操作系统名称及版本;
  • ROS 版本;
  • 任何可能有助于排除故障的、有关你的本地配置的细节;
  • 重现这个 BUG 的详细步骤。

Feature 的建议与反馈

提供反馈最好的方式是新开一个 GitHub issue。如果你提出一个新的 feature,请:

  • 详细解释它的工作机理;
  • 使其涉及的范围尽可能小,以便实现。

关于作者

官方文档(英文)作者

本文档作者

更新日志

对该项目的所有显著更改都将记录在此文件中。

该 changelog 的格式基于 Keep a Changelog。本项目遵守语义版本控制 (Semantic Versioning)

0.6.0:

Changed

  • For consistency, timeout parameter of Goal.send() is now expressed in seconds, instead of milliseconds.

Deprecated

  • The timeout parameter of ActionClient() is ignored in favor of blocking until the connection is established.

Fixed

  • Raise exceptions when timeouts expire on ROS connection or service calls.

Added

  • Support for calling a function in a thread from the Ros client.
  • Added implementation of a Simple Action Server.
0.5.0:

Changed

  • The non-blocking event loop runner now waits for the connection to be established in order to minimize the need for on_ready handlers.

Added

  • Support blocking and non-blocking service calls.

Fixed

  • Fixed an internal unsubscribing issue.
0.4.1:

Fixed

  • Resolve reconnection issues.
0.4.0:

Added

  • Add a non-blocking event loop runner
0.3.0:

Changed

  • Unsubscribing from a listener no longer requires the original callback to be passed.
0.2.1:

Fixed

  • Fix JSON serialization error on TF Client (on Python 3.x)
0.2.0:

Added

  • Add support for IronPython 2.7

Changed

  • Handler on_ready now defaults to run the callback in thread

Deprecated

  • Rename run_event_loop to the more fitting run_forever
0.1.1:

Fixed

  • Minimal documentation fixes
0.1.0:

Added

  • Initial version

后记

从发现并使用 roslibpy 这个库,到决定把它的文档翻译成中文,其实心血来潮的成分更大一点。最初是有两个动机,一是发现中文互联网上有关这个库的资料少得可怜,只有寥寥几条语焉不详的教程,所以动了通过写文档来将其介绍给更多中文用户的心思;二是恰好想折腾一番,一直觉得写技术文档是一个很神秘的事情,搞得自己跃跃欲试。

断断续续地构建这个文档,前后恰好花了一周的时间,其中大部分时间消耗在了 Sphinx + reStructuredText + readthedocs 的各种挖坑与踩坑上,剩下的小部分时间才是用在文档翻译上面的。经过一周的速成,现在基本是个半吊子水平,以后如果再写技术文档,相信会顺利很多。

这种参与社区建设的感觉其实是非常令人愉悦的,我的工作虽然不大,但是将来可能会帮助到无数的人,所以我认为是有意义的。最后,如果这个文档帮助到了你,请去 GitHub 给这个文档的仓库点一个 star,作为对我的鼓励吧~

>> roslibpy 官方仓库:roslibpy <<

>> 本文档仓库:roslibpy-docs-zh <<

Wu Hsin

2019.4.26.

2019.6.8. edited.

Until the end of the world.