Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sentence checker #4592

Draft
wants to merge 3 commits into
base: rolling
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ multiversion: Makefile
@$(BUILD) -M $@ "$(SOURCE)" "$(OUT)" $(OPTS)

lint:
sphinx-lint source
./sphinx-lint-with-ros source

test:
doc8 --ignore D001 --ignore-path build
Expand Down
109 changes: 109 additions & 0 deletions plugins/ros_checkers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/python3
from sphinxlint.checkers import checker
from sphinxlint.utils import paragraphs
import re

# Derived from https://stackoverflow.com/a/31505798
DOT = '•'
QUESTION = '✇'
EXCLAM = '‼'
SP_LOOKUP = {
'.': DOT,
'?': QUESTION,
'!': EXCLAM,
}
STOP = '¶'

# Classes and patterns
ALPHABETIC = r'([A-Za-z])'
DIGITS = '([0-9])'
NOT_BREAK = r'[^!.?]'
BREAK = r'([!.?])'
PREFIXES = r'(Mr|St|Mrs|Ms|Dr|etc|vol|cf|et al|vs|eg|Proc)\.'
SUFFIXES = r'(Inc|Ltd|Jr|Sr|Co)'
WEBSITES = r'\.(com|net|org|io|gov|edu|me|ros)'
EXTENSIONS = r'\.(xml|cfg|py|launch|frame_id|ini|md|log|h|cpp|bash|patch|gz|yaml|txt|NET|js|msg|srv|action|rst|exe)'
MULTIPLE_DOTS = r'\.{2,}'
STARTERS = r'(Mr|Mrs|Ms|Dr|Prof|Capt|Cpt|Lt|He\s|She\s|It\s|They\s|Their\s|Our\s|We\s|But\s|However\s|That\s|This\s|Wherever)'
ACRONYMS = r'([A-Z][.][A-Z][.](?:[A-Z][.])?)'
DIGITS_DOT_DIGITS = re.compile(DIGITS + '([.])' + DIGITS)
SINGLE_LETTER = re.compile(r'(\s[A-Za-z])(\.)(\s)')
DOT_PAREN = re.compile(r'\.( \()')

# RST Formatting Patterns
HYPERLINK = re.compile(r'(<[^>.!?]*)' + BREAK + r'([^>]*>)')
BACKTICK = re.compile(r'(`[^`.!?]*)' + BREAK + r'([^`]*`)')
LIST_PREFIX = re.compile(r'^(\s*[\d#]+)(\.)(.*)')
TRAILING_FORMATTING = re.compile(r'()' + BREAK + r'(\s*[\*\)]*\s*)$')


def split_into_sentences(text):
"""
Split the text into sentences.

Assumes text does not contain the special characters DOT or STOP

:param text: text to be split into sentences
:type text: str

:return: list of sentences
:rtype: list[str]
"""

text = ' ' + text + ' '

# Convert nonbreaking punctuation to special characters
for pattern in [DIGITS_DOT_DIGITS, SINGLE_LETTER,
HYPERLINK, BACKTICK, LIST_PREFIX, TRAILING_FORMATTING
]:
m = pattern.search(text)
while m:
text = text.replace(m.group(0), m.group(1) + SP_LOOKUP[m.group(2)] + m.group(3))
m = pattern.search(text)

for pattern in [PREFIXES, SUFFIXES]:
text = re.sub(pattern, '\\1' + DOT, text)
for pattern in [DOT_PAREN, WEBSITES, EXTENSIONS]:
text = re.sub(pattern, DOT + '\\1', text)

text = re.sub(MULTIPLE_DOTS, lambda match: DOT * len(match.group(0)) + STOP, text)
text = re.sub('Ph\.D\.', f'Ph{DOT}D{DOT}', text)
text = re.sub(ACRONYMS + ' ' + STARTERS,
f'\\1{STOP} \\2',
text)
text = re.sub(ALPHABETIC + '[.]' + ALPHABETIC + '[.]' + ALPHABETIC + '[.]',
f'\\1{DOT}\\2{DOT}\\3' + DOT,
text
)
text = re.sub(ALPHABETIC + '[.]' + ALPHABETIC + '[.]', f'\\1{DOT}\\2{DOT}', text)

# Convert breaking punctuation to include STOP character
# and convert special characters back to normal
for stopper, replacement in SP_LOOKUP.items():
text = text.replace(stopper, stopper + STOP)
text = text.replace(replacement, stopper)

sentences = text.split(STOP)
sentences = [s.strip() for s in sentences]

return list(filter(None, sentences))


@checker('.rst', '.md')
def check_sentence_count(file, lines, options=None):
for paragraph_lno, paragraph in paragraphs(lines):
for special_char in [DOT, STOP, QUESTION]:
if special_char in paragraph:
yield paragraph_lno, f'Contains the special character {special_char}'

if paragraph.lstrip().startswith('.. '):
continue

for i, line in enumerate(paragraph.split('\n')):
sentences = split_into_sentences(line)
if len(sentences) <= 1:
continue

sentence0_words = ' '.join(sentences[0].split(' ')[-3:])
sentence1_words = ' '.join(sentences[1].split(' ')[:3])
yield paragraph_lno + i, f'Each sentence must start on a new line. Break between "{sentence0_words}" and "{sentence1_words}"'
3 changes: 2 additions & 1 deletion source/Concepts/Basic/About-Client-Libraries.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ While the C++ and Python client libraries are maintained by the core ROS 2 team,
* `C <https://github.com/ros2/rclc>`__ ``rclc`` does not put a layer on top of rcl but complements rcl to make rcl+rclc a feature-complete client library in C. See `micro.ros.org <https://micro.ros.org/>`__ for tutorials.
* `JVM and Android <https://github.com/ros2-java>`__ Java and Android bindings for ROS 2.
* `.NET Core, UWP and C# <https://github.com/esteve/ros2_dotnet>`__ This is a collection of projects (bindings, code generator, examples and more) for writing ROS 2 applications for .NET Core and .NET Standard.
* `Node.js <https://www.npmjs.com/package/rclnodejs>`__ rclnodejs is a Node.js client for ROS 2. It provides a simple and easy JavaScript API for ROS 2 programming.
* `Node.js <https://www.npmjs.com/package/rclnodejs>`__ rclnodejs is a Node.js client for ROS 2.
It provides a simple and easy JavaScript API for ROS 2 programming.
* `Rust <https://github.com/ros2-rust/ros2_rust>`__ This is a set of projects (the rclrs client library, code generator, examples and more) that enables developers to write ROS 2 applications in Rust.

Older, unmaintained client libraries are:
Expand Down
48 changes: 26 additions & 22 deletions source/Concepts/Basic/About-Interfaces.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ This description makes it easy for ROS tools to automatically generate source co

In this document we will describe the supported types:

* msg: ``.msg`` files are simple text files that describe the fields of a ROS message. They are used to generate source code for messages in different languages.
* srv: ``.srv`` files describe a service. They are composed of two parts: a request and a response. The request and response are message declarations.
* action: ``.action`` files describe actions. They are composed of three parts: a goal, a result, and feedback.
* msg: ``.msg`` files are simple text files that describe the fields of a ROS message.
They are used to generate source code for messages in different languages.
* srv: ``.srv`` files describe a service.
They are composed of two parts: a request and a response.
The request and response are message declarations.
* action: ``.action`` files describe actions.
They are composed of three parts: a goal, a result, and feedback.
Each part is a message declaration itself.

Messages
Expand Down Expand Up @@ -70,63 +74,63 @@ Field types can be:
- `DDS type <https://design.ros2.org/articles/mapping_dds_types.html>`__
* - bool
- bool
- builtins.bool
- ``builtins.bool``
- boolean
* - byte
- uint8_t
- builtins.bytes*
- ``builtins.bytes*``
- octet
* - char
- char
- builtins.int*
- ``builtins.int*``
- char
* - float32
- float
- builtins.float*
- ``builtins.float*``
- float
* - float64
- double
- builtins.float*
- ``builtins.float*``
- double
* - int8
- int8_t
- builtins.int*
- ``builtins.int*``
- octet
* - uint8
- uint8_t
- builtins.int*
- ``builtins.int*``
- octet
* - int16
- int16_t
- builtins.int*
- ``builtins.int*``
- short
* - uint16
- uint16_t
- builtins.int*
- ``builtins.int*``
- unsigned short
* - int32
- int32_t
- builtins.int*
- ``builtins.int*``
- long
* - uint32
- uint32_t
- builtins.int*
- ``builtins.int*``
- unsigned long
* - int64
- int64_t
- builtins.int*
- ``builtins.int*``
- long long
* - uint64
- uint64_t
- builtins.int*
- ``builtins.int*``
- unsigned long long
* - string
- std::string
- builtins.str
- ``builtins.str``
- string
* - wstring
- std::u16string
- builtins.str
- ``builtins.str``
- wstring

*Every built-in-type can be used to define arrays:*
Expand All @@ -140,19 +144,19 @@ Field types can be:
- `DDS type <https://design.ros2.org/articles/mapping_dds_types.html>`__
* - static array
- std::array<T, N>
- builtins.list*
- ``builtins.list*``
- T[N]
* - unbounded dynamic array
- std::vector
- builtins.list
- ``builtins.list``
- sequence
* - bounded dynamic array
- custom_class<T, N>
- builtins.list*
- ``builtins.list*``
- sequence<T, N>
* - bounded string
- std::string
- builtins.str*
- ``builtins.str*``
- string

All types that are more permissive than their ROS definition enforce the ROS constraints in range and length by software.
Expand Down
9 changes: 6 additions & 3 deletions source/Concepts/Basic/About-Parameters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,14 @@ The services that are created by default are:
* ``/node_name/get_parameters``: Uses a service type of ``rcl_interfaces/srv/GetParameters``.
Given a list of parameter names, returns a list of parameter values associated with the parameters.
* ``/node_name/list_parameters``: Uses a service type of ``rcl_interfaces/srv/ListParameters``.
Given an optional list of parameter prefixes, returns a list of the available parameters with that prefix. If the prefixes are empty, returns all parameters.
Given an optional list of parameter prefixes, returns a list of the available parameters with that prefix.
If the prefixes are empty, returns all parameters.
* ``/node_name/set_parameters``: Uses a service type of ``rcl_interfaces/srv/SetParameters``.
Given a list of parameter names and values, attempts to set the parameters on the node. Returns a list of results from trying to set each parameter; some of them may have succeeded and some may have failed.
Given a list of parameter names and values, attempts to set the parameters on the node.
Returns a list of results from trying to set each parameter; some of them may have succeeded and some may have failed.
* ``/node_name/set_parameters_atomically``: Uses a service type of ``rcl_interfaces/srv/SetParametersAtomically``.
Given a list of parameter names and values, attempts to set the parameters on the node. Returns a single result from trying to set all parameters, so if one failed, all of them failed.
Given a list of parameter names and values, attempts to set the parameters on the node.
Returns a single result from trying to set all parameters, so if one failed, all of them failed.

Setting initial parameter values when running a node
----------------------------------------------------
Expand Down
5 changes: 4 additions & 1 deletion source/Concepts/Basic/About-Topics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,7 @@ That has two meanings in this context:

Then the code will ensure that ``field1`` is always an unsigned integer and that ``field2`` is always a string.

2. The semantics of each field are well-defined. There is no automated mechanism to ensure this, but all of the core ROS types have strong semantics associated with them. For instance, the IMU message contains a 3-dimensional vector for the measured angular velocity, and each of the dimensions is specified to be in radians/second. Other interpretations should not be placed into the message.
2. The semantics of each field are well-defined.
There is no automated mechanism to ensure this, but all of the core ROS types have strong semantics associated with them.
For instance, the IMU message contains a 3-dimensional vector for the measured angular velocity, and each of the dimensions is specified to be in radians/second.
Other interpretations should not be placed into the message.
4 changes: 3 additions & 1 deletion source/Concepts/Intermediate/About-Cross-Compilation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ How does it work ?
Cross-compiling simple software (e.g. no dependencies on external libraries) is relatively simple and only requiring a cross-compiler toolchain to be used instead of the native toolchain.

There are a number of factors which make this process more complex:
- The software being built must support the target architecture. Architecture specific code must be properly isolated and enabled during the build according to the target architecture. Examples include assembly code.
- The software being built must support the target architecture.
Architecture specific code must be properly isolated and enabled during the build according to the target architecture.
Examples include assembly code.
- All dependencies (e.g. libraries) must be present, either as pre-built or cross-compiled packages, before the target software using them is cross-compiled.
- When building software stacks (as opposed to standalone software) using build tools (e.g. colcon), it is expected that the build tool provides a mechanism to allow the developer to enable cross-compilation on the underlying build system used by each piece of software in the stack.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,24 @@ Supported RMW implementations
* - eProsima *Fast DDS*
- Apache 2
- ``rmw_fastrtps_cpp``
- Full support. Default RMW. Packaged with binary releases.
- Full support.
Default RMW.
Packaged with binary releases.
* - Eclipse *Cyclone DDS*
- Eclipse Public License v2.0
- ``rmw_cyclonedds_cpp``
- Full support. Packaged with binary releases.
- Full support.
Packaged with binary releases.
* - RTI *Connext DDS*
- commercial, research
- ``rmw_connextdds``
- Full support. Support included in binaries, but Connext installed separately.
- Full support.
Support included in binaries, but Connext installed separately.
* - GurumNetworks *GurumDDS*
- commercial
- ``rmw_gurumdds_cpp``
- Community support. Support included in binaries, but GurumDDS installed separately.
- Community support.
Support included in binaries, but GurumDDS installed separately.

For practical information on working with multiple RMW implementations, see the :doc:`"Working with multiple RMW implementations" <../../How-To-Guides/Working-with-multiple-RMW-implementations>` tutorial.

Expand Down
13 changes: 10 additions & 3 deletions source/Concepts/Intermediate/About-Executors.rst
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ The following flow diagram visualizes this scheduling semantics.
.. image:: ../images/executors_scheduling_semantics.png

This semantics was first described in a `paper by Casini et al. at ECRTS 2019 <https://drops.dagstuhl.de/opus/volltexte/2019/10743/pdf/LIPIcs-ECRTS-2019-6.pdf>`_.
(Note: The paper also explains that timer events are prioritized over all other messages. `This prioritization was removed in Eloquent. <https://github.com/ros2/rclcpp/pull/841>`_)
(Note: The paper also explains that timer events are prioritized over all other messages.
`This prioritization was removed in Eloquent. <https://github.com/ros2/rclcpp/pull/841>`_)


Outlook
Expand Down Expand Up @@ -191,6 +192,12 @@ These issues have been partially addressed by the following developments:
Further information
-------------------

* Michael Pöhnl et al.: `"ROS 2 Executor: How to make it efficient, real-time and deterministic?" <https://www.apex.ai/roscon-21>`_. Workshop at ROS World 2021. Virtual event. 19 October 2021.
* Ralph Lange: `"Advanced Execution Management with ROS 2" <https://www.youtube.com/watch?v=Sz-nllmtcc8&t=109s>`_. ROS Industrial Conference. Virtual event. 16 December 2020.
* Michael Pöhnl et al.: `"ROS 2 Executor: How to make it efficient, real-time and deterministic?" <https://www.apex.ai/roscon-21>`_.
Workshop at ROS World 2021.
Virtual event.
19 October 2021.
* Ralph Lange: `"Advanced Execution Management with ROS 2" <https://www.youtube.com/watch?v=Sz-nllmtcc8&t=109s>`_.
ROS Industrial Conference.
Virtual event.
16 December 2020.
* Daniel Casini, Tobias Blass, Ingo Lütkebohle, and Björn Brandenburg: `“Response-Time Analysis of ROS 2 Processing Chains under Reservation-Based Scheduling” <https://drops.dagstuhl.de/opus/volltexte/2019/10743/pdf/LIPIcs-ECRTS-2019-6.pdf>`_, Proc. of 31st ECRTS 2019, Stuttgart, Germany, July 2019.
Loading