Quiz#

This quiz covers the key concepts from Lecture 10: Parameters, Custom Interfaces, Services, and Actions. Topics include parameter declaration and callbacks, YAML parameter files, custom .msg/.srv/.action definitions, service server/client patterns (synchronous vs. asynchronous), action server/client patterns with feedback and cancellation, and choosing the right communication mechanism.

Note

Instructions:

  • Answer all questions to the best of your ability.

  • Multiple choice questions have exactly one correct answer.

  • True/False questions require you to determine if the statement is correct.

  • Essay questions require short written responses (2-4 sentences).

  • Click the dropdown after each question to reveal the answer.


Multiple Choice#

Question 1

What must you do before calling self.get_parameter("speed") in a ROS 2 Python node?

  1. Import ParameterDescriptor from rcl_interfaces.msg.

  2. Call self.declare_parameter("speed", <default>) to register the parameter.

  3. Start the node with --ros-args --params-file.

  4. Create a service client to the parameter server.

Answer

Bself.declare_parameter("speed", <default>).

ROS 2 requires parameters to be declared before they can be read. Calling get_parameter() on an undeclared parameter raises ParameterNotDeclaredException. The declaration registers the parameter name, default value, and type on the node. Importing ParameterDescriptor is optional and only needed for adding metadata. Starting with --params-file provides values but does not replace declaration.

Question 2

In a YAML parameter file, what is the correct key under a node name to specify its parameters?

  1. parameters:

  2. ros_parameters:

  3. ros__parameters:

  4. node_parameters:

Answer

Cros__parameters: (with double underscores).

The double-underscore convention is required by the ROS 2 parameter loading system. Using a single underscore or any other key name will cause the parameters to be silently ignored. The top-level key must match the fully qualified node name (e.g., /controller).

Question 3

Why must custom interface packages use ament_cmake instead of ament_python?

  1. Python does not support message serialization.

  2. The rosidl code generators require CMake build infrastructure to produce language-specific bindings.

  3. Custom interfaces can only be used in C++ nodes.

  4. ament_python does not support package.xml.

Answer

B – The rosidl code generators require CMake.

The ROS 2 interface generation pipeline (rosidl) compiles .msg, .srv, and .action files into Python classes and C++ headers using CMake macros (rosidl_generate_interfaces). This is a build-time requirement of the generator toolchain, not a limitation of Python itself. The generated Python classes can be imported and used in any ament_python package.

Question 4

What separates the request and response sections in a .srv file?

  1. A blank line.

  2. The keyword response:.

  3. Three dashes: ---

  4. The keyword return.

Answer

C – Three dashes: ---.

The --- separator is used in both .srv files (separating request from response) and .action files (separating goal, result, and feedback). This is a convention inherited from ROS 1 and enforced by the rosidl parser.

Question 5

What happens if you call self._client.call(request) (synchronous) from the main executor thread in a single-threaded executor?

  1. The call succeeds but takes longer than usual.

  2. A TimeoutError is raised after 5 seconds.

  3. A deadlock occurs because the blocked thread cannot process the response callback.

  4. The executor automatically switches to multi-threaded mode.

Answer

C – A deadlock occurs.

The synchronous call() method blocks the calling thread until the response arrives. In a single-threaded executor, this is the same thread responsible for processing callbacks, including the response from the service server. Since the thread is blocked waiting for a response it can never process, the node hangs indefinitely. This is why call_async() is the recommended pattern.

Question 6

In an action definition, how many sections are separated by ---?

  1. 2 – request and response.

  2. 3 – goal, result, and feedback.

  3. 3 – goal, feedback, and status.

  4. 4 – goal, acceptance, result, and feedback.

Answer

B – 3 sections: goal, result, and feedback.

An .action file is divided into three sections by two --- separators. The first section defines the goal (sent by the client), the second defines the result (returned when the action completes), and the third defines the feedback (published periodically during execution). This three-part structure distinguishes actions from services, which have only two sections.

Question 7

Which method on a GoalHandle does the action server call to indicate the goal completed successfully?

  1. goal_handle.complete()

  2. goal_handle.succeed()

  3. goal_handle.finish(success=True)

  4. goal_handle.set_result(result)

Answer

Bgoal_handle.succeed().

The GoalHandle provides terminal state methods: succeed(), canceled(), and abort(). Calling succeed() sets the goal status to STATUS_SUCCEEDED before the execute callback returns the result object. The client receives this status along with the result when it calls get_result_async().

Question 8

A parameter callback returns SetParametersResult(successful=False, reason="..."). What happens?

  1. The parameter is set anyway but a warning is logged.

  2. The parameter change is rejected and the previous value is retained.

  3. The node shuts down with an error.

  4. The parameter is set to its default value.

Answer

B – The parameter change is rejected.

When a parameter callback returns successful=False, the parameter service returns an error to the caller (CLI, launch file, or another node) and the parameter retains its previous value. The reason string is included in the error response to explain why the change was rejected. This mechanism allows nodes to validate parameter changes at runtime.


True/False#

Question 9

True or False: Parameters in ROS 2 are stored on a central parameter server shared by all nodes.

Answer

False

Parameters are node-local in ROS 2. Each node maintains its own parameter store and exposes it through automatically created parameter services (get_parameters, set_parameters, etc.). There is no central parameter server as in ROS 1. Two nodes can have parameters with the same name but completely independent values.

Question 10

True or False: A .msg file can reference message types from other packages (e.g., std_msgs/Header).

Answer

True

Custom message definitions can include fields of any type from any package listed as a dependency in package.xml and passed to the DEPENDENCIES argument of rosidl_generate_interfaces in CMakeLists.txt. std_msgs/Header and geometry_msgs/Pose are common examples.

Question 11

True or False: Action cancellation in ROS 2 is immediate – as soon as the client calls cancel_goal_async(), the server stops executing.

Answer

False

Action cancellation is cooperative. The client sends a cancel request, and the server’s cancel_callback decides whether to accept it. Even after acceptance, the execute callback must explicitly check goal_handle.is_cancel_requested and call goal_handle.canceled() to acknowledge the cancellation. The server is free to finish a critical operation before stopping.

Question 12

True or False: ros2 param dump /node_name outputs YAML that can be directly reloaded with --params-file.

Answer

True

ros2 param dump generates a YAML file in the correct format (node name as the top-level key, ros__parameters as the sub-key). This output can be saved to a file and loaded with --ros-args --params-file <file>, making it a convenient way to snapshot and restore a node’s configuration.

Question 13

True or False: A service client using call_async() will deadlock in a single-threaded executor.

Answer

False

call_async() is the asynchronous pattern that returns a Future immediately without blocking the executor thread. The executor remains free to process other callbacks, including the response when it arrives. It is the synchronous call() method that causes a deadlock in a single-threaded executor by blocking the thread that needs to process the response.


Essay Questions#

Question 14

Explain the difference between a ROS 2 service and a ROS 2 action. When would you choose one over the other? Give a concrete robotics example for each.

(2-4 sentences)

Answer Guidelines

Key points to include:

  • A service implements a synchronous request/response pattern suitable for short-duration operations. The client sends a request and blocks (or waits asynchronously) for a single response. There is no mechanism for progress updates or cancellation. Example: requesting a robot to compute inverse kinematics for a target pose.

  • An action extends the service model with feedback and cancellation for long-running tasks. The server publishes periodic feedback while executing and the client can cancel the goal at any time. Example: commanding a mobile robot to navigate to a waypoint, receiving distance-remaining updates, and canceling if an obstacle is detected.

  • Choose a service when the operation completes quickly (under ~1 s) and no progress tracking is needed. Choose an action when the operation takes noticeable time and the user or system needs visibility into progress or the ability to abort.

Question 15

Describe the purpose of a parameter callback in ROS 2. What happens if the callback returns successful=False? Why is this mechanism useful for robotic systems?

(2-4 sentences)

Answer Guidelines

Key points to include:

  • A parameter callback is invoked whenever a parameter value is changed at runtime (via CLI, service call, launch file, or another node). It receives the list of pending parameter changes and can inspect each one.

  • If the callback returns SetParametersResult(successful=False), the change is rejected and the parameter retains its previous value. The reason string is returned to the caller to explain the rejection.

  • This is critical for safety in robotic systems: a controller node can reject a proportional gain that is negative or dangerously high, preventing unstable behavior without requiring a node restart. It also enables logging all parameter changes for debugging and audit purposes.

Question 16

Why is it recommended to use ``call_async()`` instead of ``call()`` for ROS 2 service clients? Explain the deadlock scenario that can occur with call() and describe one strategy to avoid it if synchronous behavior is required.

(2-4 sentences)

Answer Guidelines

Key points to include:

  • call() blocks the calling thread until the response arrives. In a SingleThreadedExecutor, this blocks the only thread responsible for processing callbacks. Since the response callback cannot be processed by the blocked thread, the node deadlocks permanently.

  • call_async() returns a Future immediately and allows the executor to continue processing other callbacks, including the eventual response. This is safe in all executor configurations.

  • If synchronous behavior is truly required, one strategy is to call the service from a callback assigned to a ReentrantCallbackGroup inside a MultiThreadedExecutor. This ensures the blocking call runs on one thread while the response is processed on another. However, call_async() with add_done_callback() is almost always the cleaner solution.