Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
tutorials:beginner:process_modules_2 [2017/07/13 15:02] – created cpo | tutorials:beginner:process_modules_2 [2020/09/03 10:34] (current) – [Writing a process module for the turtlesim] gkazhoya | ||
---|---|---|---|
Line 3: | Line 3: | ||
**Description: | **Description: | ||
- | **Previous Tutorial:** [[tutorials: | + | **Previous Tutorial:** [[tutorials: |
- | **Next Tutorial:** [[tutorials: | + | **Next Tutorial:** [[tutorials: |
===== Process modules: an overview ===== | ===== Process modules: an overview ===== | ||
Line 26: | Line 26: | ||
Once again, some new dependencies must be declared in the tutorial files you've been working on. | Once again, some new dependencies must be declared in the tutorial files you've been working on. | ||
- | In your '' | + | In your '' |
< | < | ||
- | <build_depend> | + | <depend> |
- | + | ||
- | < | + | |
</ | </ | ||
Line 37: | Line 35: | ||
<code lisp> | <code lisp> | ||
- | (defsystem cram-beginner-tutorial | + | (defsystem cram-my-beginner-tutorial |
- | :depends-on (cram-language roslisp turtlesim-msg geometry_msgs-msg cl-transforms | + | :depends-on (cram-language roslisp turtlesim-msg |
| | ||
| | ||
Line 47: | Line 45: | ||
| | ||
| | ||
- | | + | |
| | ||
" | " | ||
" | " | ||
- | " | + | " |
</ | </ | ||
Line 80: | Line 78: | ||
</ | </ | ||
- | First, we use the '' | + | First, we use the '' |
Let's try this out. Make sure you have '' | Let's try this out. Make sure you have '' | ||
Line 116: | Line 114: | ||
<code lisp> | <code lisp> | ||
TUT> (drive 5 2) | TUT> (drive 5 2) | ||
- | [(TURTLE-PROCESS-MODULES) INFO] 1499958119.336: TurtleSim navigation invoked with motion designator `#< | + | [(TURTLE-PROCESS-MODULES) INFO] 1562698751.679: TurtleSim navigation invoked with motion designator `#<A MOTION |
+ | (TYPE DRIVING) | ||
+ | (SPEED 5) | ||
+ | (ANGLE 2)>' | ||
+ | 1 | ||
+ | </ | ||
+ | |||
+ | You should also see the turtle move in the TurtleSim window and trace the required trajectory. | ||
+ | |||
+ | |||
+ | ==== Adding more process modules for the TurtleSim ==== | ||
+ | |||
+ | When adding new motions for a robot, we can either add them to a existing process module or write a new one. A process module only ever executes one designator at a time. This is to prevent unwanted behaviour when executing multiple designators in parallel or quick succession. But when a process module is called while still executing, the incoming call will be queued and executed as soon as the current execution is finished. | ||
+ | For example, if we wanted the robot to grasp something and then stack it onto something else. If these motions were executed in parallel the arm would do neither because the commands would interfere with each other. Through the use of process modules, we don't have to worry about this. | ||
+ | So to make this decision, we need to think about resources on the robot (eg. arms or the base of the robot). | ||
+ | |||
+ | Our '' | ||
+ | |||
+ | To add the move motion to the existing process module, we add a new case to the '' | ||
+ | |||
+ | <code lisp> | ||
+ | (def-process-module turtlesim-navigation (motion-designator) | ||
+ | (roslisp: | ||
+ | " | ||
+ | motion-designator) | ||
+ | (destructuring-bind (command motion) (reference motion-designator) | ||
+ | (ecase command | ||
+ | (drive | ||
+ | | ||
+ | (turtle-motion-speed motion) | ||
+ | (turtle-motion-angle motion))) | ||
+ | (move | ||
+ | | ||
+ | </ | ||
+ | |||
+ | Since '' | ||
+ | |||
+ | |||
+ | To add the new process module, append this to your '' | ||
+ | |||
+ | <code lisp> | ||
+ | (def-process-module turtlesim-pen-control (motion-designator) | ||
+ | (roslisp: | ||
+ | " | ||
+ | motion-designator) | ||
+ | (destructuring-bind (command motion) (reference motion-designator) | ||
+ | (ecase command | ||
+ | (set-pen | ||
+ | | ||
+ | (pen-motion-r motion) | ||
+ | (pen-motion-g motion) | ||
+ | (pen-motion-b motion) | ||
+ | (pen-motion-width motion) | ||
+ | (pen-motion-off motion)))))) | ||
+ | </ | ||
+ | |||
+ | The code should look very familiar, because it's pretty close to our other process modul | ||
+ | |||
+ | |||
+ | ==== Executing process modules in parallel ==== | ||
+ | |||
+ | To demonstrate how process modules work when called in parallel, we will call the same process module twice. You can execute the following in the REPL: | ||
+ | |||
+ | <code lisp> | ||
+ | TUT> (top-level | ||
+ | (with-process-modules-running (turtlesim-navigation turtlesim-pen-control) | ||
+ | (let ((goal (desig:a motion (type moving) (goal (9 1 0)))) | ||
+ | (trajectory (desig:a motion (type driving) (speed 3) (angle 8)))) | ||
+ | (cpl:par | ||
+ | (pm-execute ' | ||
+ | (pm-execute ' | ||
+ | [(TURTLE-PROCESS-MODULES) INFO] 1500997686.711: | ||
+ | | ||
+ | (GOAL | ||
+ | (9 1 | ||
+ | 0))) {1006DBC893}>' | ||
+ | WARNING: | ||
+ | | ||
+ | {10074C0293}> | ||
+ | [(TURTLE-PROCESS-MODULES) INFO] 1500997690.065: TurtleSim navigation invoked with motion designator `#< | ||
| | ||
(SPEED | (SPEED | ||
- | 5) | + | 3) |
(ANGLE | (ANGLE | ||
- | 2)) {1006979703}>' | + | 8)) {1006DBCC73}>' |
- | 1 | + | T |
</ | </ | ||
- | You should also see the turtle move in the TurtleSim window | + | Here we use the '' |
- | == Next == | + | If we use two different process modules, they can in fact be called in parallel: |
- | Let's have a look at location designators | + | <code lisp> |
+ | TUT> (top-level | ||
+ | (with-process-modules-running (turtlesim-navigation turtlesim-pen-control) | ||
+ | (let ((goal (desig:a motion (type moving) (goal (9 9 0))))) | ||
+ | (cpl:par | ||
+ | (pm-execute | ||
+ | (dotimes (i 10) | ||
+ | (pm-execute ' | ||
+ | (let ((?r (random 255)) | ||
+ | (?g (random 255)) | ||
+ | (?b (random 255)) | ||
+ | (?width (+ 3 (random 5)))) | ||
+ | (desig:a motion (type setting-pen) (r ?r) (g ?g) (b ?b) (width ? | ||
+ | (sleep 0.5)))))) | ||
+ | [(TURTLE-PROCESS-MODULES) INFO] 1500997786.329: | ||
+ | | ||
+ | (GOAL | ||
+ | (9 9 | ||
+ | 0))) {1005164AC3}>' | ||
+ | [(TURTLE-PROCESS-MODULES) INFO] 1500997786.347: | ||
+ | SETTING-PEN) | ||
+ | (R | ||
+ | 220) | ||
+ | (G | ||
+ | 115) | ||
+ | (B | ||
+ | 14) | ||
+ | | ||
+ | 7)) {10072183E3}>' | ||
+ | |||
+ | [ ... ] | ||
+ | |||
+ | [(TURTLE-PROCESS-MODULES) INFO] 1500997791.126: | ||
+ | SETTING-PEN) | ||
+ | (R | ||
+ | 225) | ||
+ | (G | ||
+ | 228) | ||
+ | (B | ||
+ | 156) | ||
+ | | ||
+ | 3)) {1002B903C3}>' | ||
+ | T | ||
+ | </ | ||
+ | |||
+ | Here we call the navigation process module to move the turtle to the upper right corner | ||
+ | |||
+ | As stated above this behaviour is to ensure that a single resource on a robot isn't used by multiple functions at once, while not hindering the parallel execution of independent resources. But keep in mind, that this is only true for the low-level motions. If a robots arms should grasp something | ||
+ | |||
+ | |||
+ | == Next == | ||
+ | So far we called | ||
- | [[tutorials: | + | [[tutorials: |