Skip to content

Commit

Permalink
Plantuml Infrastructure (#212)
Browse files Browse the repository at this point in the history
* Add dependencies

* Complete template and examples

* Update template.puml

* Update README for Plantuml Rendering

* Move to /diagrams/

* Move diagrams to diagrams/src

* Update gitignore

* Add export settings

* Update export documentation

---------

Co-authored-by: Patrick Creighton <pcreighton429@gmail.com>
  • Loading branch information
hhenry01 and patrick-5546 authored Nov 22, 2023
1 parent 7d5a84f commit d6c7135
Show file tree
Hide file tree
Showing 9 changed files with 308 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ghcr.io/ubcsailbot/sailbot_workspace/dev:jupyter
FROM ghcr.io/ubcsailbot/sailbot_workspace/dev:plantuml2

# Copy configuration files (e.g., .vimrc) from config/ to the container's home directory
ARG USERNAME=ros
Expand Down
16 changes: 16 additions & 0 deletions .devcontainer/base-dev/base-dev.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,22 @@ RUN chmod +x /sbin/update-bashrc \
&& /bin/bash -c /sbin/update-bashrc \
&& rm /sbin/update-bashrc

# plantuml diagram support
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
default-jre graphviz \
&& wget https://github.com/plantuml/plantuml/releases/download/v1.2023.12/plantuml-asl-1.2023.12.jar \
&& mv plantuml-asl-1.2023.12.jar /usr/local/bin/plantuml-asl-1.2023.12.jar \
&& echo "#!/bin/bash\njava -jar /usr/local/bin/plantuml-asl-1.2023.12.jar \$*" > /usr/local/bin/plantuml.sh \
&& chmod +x /usr/local/bin/plantuml.sh \
&& apt-get autoremove -y \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/{apt,dpkg,cache,log} /tmp/* /var/tmp/*
ENV DEBIAN_FRONTEND=

ENV PLANTUML_TEMPLATE_PATH="/workspaces/sailbot_workspace/diagrams/template.puml"

# install some clang tools and googletest for network systems
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
Expand Down
1 change: 1 addition & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"github.copilot",
"github.vscode-github-actions",
"Gruntfuggly.todo-tree",
"jebbs.plantuml",
"jeff-hykin.better-cpp-syntax",
"KevinRose.vsc-python-indent",
"llvm-vs-code-extensions.vscode-clangd",
Expand Down
20 changes: 11 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
# ros
build/
install/
log/
/build/
/install/
/log/

# vcstool packages
src/*
!src/global_launch
!src/polaris.repos
/src/*
!/src/global_launch
!/src/polaris.repos

# configuration files
.devcontainer/config/*
!.devcontainer/config/README.md
/.devcontainer/config/*
!/.devcontainer/config/README.md

# clangd
.cache/
compile_commands.json

# microsoft c/c++ intellisense (disabled in favor of clangd)
/.vscode/c_cpp_properties.json
Expand All @@ -23,3 +22,6 @@ compile_commands.json
__pycache__/
.mypy_cache/
.pytest_cache/

# exported plantuml diagrams
/diagrams/out/
65 changes: 65 additions & 0 deletions diagrams/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# PlantUML

## Overview

The simplest way to describe PlantUML is "diagrams written with code". The main benefit of using PlantUML instead of
making diagrams in GUI-based software like draw.io or Visio is the ability to version control diagrams. Since they are
rendered based on plain text descriptions, Git can easily track edit histories. Another benefit is the easy propagation
of an organization specific diagram style. By including [template.puml](template.puml) in other puml files, we can have
a consistent style across sailbot_workspace. Simply add `!include %getenv("PLANTUML_TEMPLATE_PATH")` to your file.

## How To

### Render In VSCode (Simplest Way to View)

When you have a `.puml` file open in VSCode, there will be an icon in the top right of the tab with a magnifying glass.
Simply click it and the diagram will render to the side. Usually, it automatically updates whenever you make a change to
the `.puml` file. Occasionally, you'll need to run `PlantUML: Preview Current Diagram` in the VSCode command palette
(`ctrl+shift+p`) to manually update the rendered diagram.

### Export As Image

Exporting as an image is required for viewing PlantUML diagrams on services like Google Drive and Confluence.

If simply copying an image suffices, then [render in VSCode](#render-in-vscode-simplest-way-to-view), hover over the
rendered diagram and click the copy icon to the left of the help button. You can also export it as a PNG
by opening the VSCode command palette (`ctrl+shift+p`) and running one of the
`PlantUML: Export <...>` commands. The exported diagram(s) can be found under `diagrams/out/`.

### Create a Diagram

PlantUML supports various diagram types. This section goes over a few types in use by the Sailbot Software Team and
describes their use cases. For a full list, see the [PlantUML website](https://plantuml.com/). Examples of the diagrams
described below can be found under [src/](src/).

#### [Sequence Diagram](https://plantuml.com/sequence-diagram)

Use when describing the control sequence/flow of a module or algorithm. Its usecase is similar to flow diagrams
[PlantUML calls these activity diagrams](https://plantuml.com/activity-diagram-beta), but has some key advantages:

- Clearly organize different modules and reduces. Each module and resource can have their own category in a diagram, and
can be grouped with related modules and resources.
- Explicitly show resource usage. When a flow accesses a resource persistent across sequences, accesses can be shown
and described as part of the flow. For example, showing reads, write/appends, allocations, and clears.
- Represent simultaneous control flows. When exploiting parallelism and asynchronous operations, multiple modules can
be shown as active and described in a diagram at once.

The primary limitation of sequences diagrams is non-trivial branching (ex. if/else flows). Sequence diagrams are
clearest when the control flow has one possible path. To handle non-trivial branching, consider:

- Splitting branches into their own sequences/subsequences. Dedicate a sequence/subsequence to when a branch is true and
another where the branch is false.
- Using a [flow/activity diagram](https://plantuml.com/activity-diagram-beta).

#### [State Diagram](https://plantuml.com/state-diagram)

Primarily used for state machines, but can also be used to show how nodes in a system are connected (ex. ROS topics,
publishers, subscribers).

## Resources

- The [PlantUML website](https://plantuml.com/) is an excellent resource for how to create diagrams. Each tutorial page
is relatively short and goes over every diagram specific feature and some basic styling.
- For more advanced styling, comprehensive documentation can be found
[here](https://plantuml-documentation.readthedocs.io/en/latest/formatting/all-skin-params.html).
- The [src/](src/) folder contains some basic diagram examples that utilize the template.
37 changes: 37 additions & 0 deletions diagrams/src/sequence_diagram_ex.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@startuml sequence_diagram_ex
title Common Sequence

!include %getenv("PLANTUML_TEMPLATE_PATH")

autonumber

!startsub PARTICIPANTS
box "Common Sequence"
participant CanTransceiver as can
participant CanTransceiverRosIntf as ros_intf
end box
== Inbound ==
!endsub PARTICIPANTS

-> can : Inbound Sensor(s) [CAN]

!startsub SEQUENCE

activate can
can -> can : Convert from CAN to ROS
can -> can : Filter Sensor(s)
can -> ros_intf --++ : Transmit Sensor(s) [ROS]
ros_intf -> : Publish sensor(s) to Software ROS Network
deactivate ros_intf

== Outbound ==

ros_intf <- ++ : Command(s) from Software ROS Network (ex. Desired Heading)
can <- ros_intf --++ : Transmit Command(s) [ROS]
can -> can : Convert Command(s) from ROS to CAN
!endsub SEQUENCE

<- can : Outbound Command(s) [CAN]
deactivate can

@enduml
104 changes: 104 additions & 0 deletions diagrams/src/state_diagram_ex.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
@startuml state_diagram_ex
title Digital Watch

!include %getenv("PLANTUML_TEMPLATE_PATH")

State Regular

State StopWatch {
state PauseStopWatch
state StartStopWatch
}
note top of StopWatch
B1: Unused
B2: Continue
B3: Pause
endnote

State Timer {
State RunTimer {
State PauseTimer
State StartTimer
}
note left of RunTimer
B1: Adjust
B2: Continue
B3: Pause
end note
State SetTimer {
State SetSecondTimer
State SetMinuteTimer
State SetHourTimer
}
note bottom of SetTimer
B1: Adjust
B2: Increment
B3: Decrement

Increment and Decrement
in each Set{X}Timer
substate increments or
decrements each counter
register X.
end note
}

State SetTime {
State SetSecond
State SetMinute
State SetHour
State SetDay
State SetWeekday
State SetMonth
State SetTimeType : Cycle through enums\n24H, AM, PM
}
note top of SetTime
B1: Adjust
B2: Increment
B3: Decrement

Increment and Decrement
in each Set{X}
substate increments or
decrements each counter
register X.
end note

[*]-->Regular
note on link
Four Button Digital Watch
B0: Mode Select
B1: Unused / Adjust (depends on mode)
B2: Continue / Increment (depends on mode)
B3: Pause / Decrement (depends on mode)
end note
Regular-up->Regular : Increment all time tracking registers

Regular-down->PauseStopWatch : Mode Select
PauseStopWatch-up->StartStopWatch : Continue
StartStopWatch->StartStopWatch : Increment seconds, minutes, hours
StartStopWatch-down->PauseStopWatch : Pause
PauseStopWatch->PauseStopWatch : Pause / reset seconds, minutes, hours to 0

StopWatch-down->RunTimer : Mode Select
PauseTimer-up->StartTimer : Continue
PauseTimer-->PauseTimer : Pause / reset seconds, minutes, hours to 0
StartTimer-down->PauseTimer : Pause
StartTimer->StartTimer : Decrement seconds, minutes, hours
PauseTimer-down->SetSecondTimer : Adjust Timer
SetSecondTimer-right->SetMinuteTimer : Adjust Timer
SetMinuteTimer-up->SetHourTimer : Adjust Timer
SetHourTimer-left->SetSecondTimer : Adjust Timer
SetTimer-up->PauseTimer : Mode Select

RunTimer-right->SetTimeType : Mode Select
SetTimeType-left->SetSecond : Adjust Time
SetSecond-up->SetMinute : Adjust Time
SetMinute-up->SetHour : Adjust Time
SetHour-up->SetWeekday : Adjust Time
SetWeekday-right->SetDay : Adjust Time
SetDay-down->SetMonth : Adjust Time
SetMonth-down->SetTimeType : Adjust Time
SetTime-up->Regular : Mode Select

@enduml
67 changes: 67 additions & 0 deletions diagrams/template.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
@startuml template
' Colors picked to (try to) match docs site
' See sailbot_workspace/src/docs/docs/stylesheets/extra.css
!$SAILBOT_LIGHT_BLUE = "#73a3c7"
!$SAILBOT_BLUE = "#1665a2"
!$SAILBOT_DARK_BLUE = "#0d3d61"
!$MAX_MESSAGE_SIZE = 150
!$PADDING = 20

' autonumber ' autonumber breaks state diagrams so don't put in template
hide empty description

!procedure $set_sequence_participant_skinparams($participant)
!$BackgroundColor = $participant + "BackgroundColor"
!$BorderColor = $participant + "BorderColor"
!$FontColor = $participant + "FontColor"
!$Padding = $participant + "Padding"

$BackgroundColor $SAILBOT_DARK_BLUE
$BorderColor White
$FontColor White
$Padding $PADDING
!endprocedure

skinparam {
BoxPadding 10
MaxMessageSize $MAX_MESSAGE_SIZE
Note {
BackgroundColor $SAILBOT_BLUE
BorderColor Grey
FontColor White
Shadowing true
}
Sequence {
BoxBackgroundColor $SAILBOT_LIGHT_BLUE
Group {
BackgroundColor White
BodyBackgroundColor PowderBlue
FontColor OrangeRed
}
LifeLine {
BackgroundColor $SAILBOT_DARK_BLUE
BorderColor White
}
MessageAlign center
}
State {
BackgroundColor $SAILBOT_DARK_BLUE
FontColor White
}
Title {
BackgroundColor LightSteelBlue
BorderColor $SAILBOT_DARK_BLUE
FontSize 28
}

$set_sequence_participant_skinparams("Actor")
$set_sequence_participant_skinparams("Boundary")
$set_sequence_participant_skinparams("Collections")
$set_sequence_participant_skinparams("Control")
$set_sequence_participant_skinparams("Database")
$set_sequence_participant_skinparams("Entity")
$set_sequence_participant_skinparams("Participant")
$set_sequence_participant_skinparams("Queue")
}

@enduml
6 changes: 6 additions & 0 deletions sailbot.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,12 @@
"tag:yaml.org,2002:python/name:materialx.emoji.to_svg",
"tag:yaml.org,2002:python/name:pymdownx.superfences.fence_code_format"
],

// PlantUML diagrams extension
"plantuml.exportFormat": "png",
"plantuml.exportIncludeFolderHeirarchy": false,
"plantuml.exportOutDir": "diagrams/out",
"plantuml.exportSubFolder": false,
},
"launch": {
// Use IntelliSense to learn about possible attributes.
Expand Down

0 comments on commit d6c7135

Please sign in to comment.