C4 Yaklaşımı ile Mimari Gösterim
C4 Modeli görsel olarak güçlü bir şekilde mimariyi ifade etmeye yönelik geliştirilmiş bir modelleme dilidir. C4 (Context, Containers, Components, and Code) modeli Kapsam, Konteyner, Komponent ve Kod (Türkçesi de K4 oluyor bu durumda) seviyesi diyagramlardan oluşmaktadır. Bu diyagramlar yazılım mimarları ve yazılım geliştiricilerine tasarımlarını farklı seviyedeki paydaşlarla etkin bir şekilde paylaşma fırsatı vermektedir. C4 Modelinde her seviye farklı bir soyutlama seviyesini göstermekte ve en üst soyutlamadan daha detaylı anlatıma doğru zoom etmek mümkündür. Böylelikle farklı teknik seviyedeki paydaş ile farklı diyagram üzerinden iletişim kurabilirsiniz.
Daha önceki Mimari Dokümantasyon yazısında da bahsettiğim üzere mimari gösterimde yaygın olarak UML diyagramları kullanılmaktadır. UML diyagramları yazılımcı seviyesi detayları gösterme konusunda güçlü olmasına karşılık üst seviye gösterimler konusunda zayıf kalmaktadır. Bu sebeple hemen hepimiz bu diyagramları Power Point’te renkli/resimli kutular olarak çizmeyi tercih etmekteyiz. Bu açıdan ben C4 Modelinin diyagramlarını gerçekten kullanışlı buldum. Bir yazılım mimarı olarak gerekitğinde UML gerektiğinde C4 modeli kullanılabileceğini düşünmekteyim.
Ben C4 modelini hazırlar iken Plant UML den faydalandım. PlantUML skript tabanlı UML ve benzeri diyagramları çizmeye yarayan bir araçtır. Script yapısı basit ve kolay öğrenilebilir bir yapıdadır. Sürükle bırak yaklaşımına göre biraz zorlanabilirsiniz fakat bu çizimleri Confuence sayfasına PlantUML plugini yardımı ile ekleyebildiğinizi gördüğünüzde bu zorluğa değdiğini düşüneceksiniz. Çevik yazılım geliştiren firmalar yazlım mimarilerini Word dokümanı yerine Confluence ortamında tutmayı tercih etmektedir. Confluence üzerinden paylaşılan mimari diyagramlara bütün proje paydaşları kolayca erişebilir. Proje paydaşları bu çizimlerde değişiklik istediğinde bu scriptleri güncelleyerek değişiklikleri yansıtabilirler.
Bu yazıda C4 kapsamındaki diyagramların temel özelliklerini otonom araç kütüphanesi olan Autoware Auto ve onun kullandığı Robot Operating System (ROS2) yi modelleyerek anlattım. Bunu tercih etmemin sebebi C4 modelinin gömülü sistemler için kullanılabilirliğini görmek içindi. C4 Modelinin web sitesinde bir bankacılık uygulaması için gayet özenli yapılmış bir modelleme örneği mevcuttur.
Kapsam Diyagramı (Context Diagram)
Kapsam diyagramları geliştireceğimiz yazılımın kullanıldığı ortamda diğer sistem ve yazılımlarla etkileşimini göstermektedir. Bu diyagramda bizim yazılım ortada yer almakta ve diğer sistemlerle etkileşimi gösterilmektedir. Bu diyagram teknik, teknik olmayan bütün proje paydaşları arası iletişim için kullanılır. Aşağıda Autoware Auto yazılımının entegratör ile ve ROS2 ile ilişkisi verilmiştir.
Yukarıda gösterilen diyagramın PlantUML scripti aşağıda verilmiştir:
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml
' uncomment the following line and comment the first to use locally
' !include C4_Context.puml
title System Context diagram for AutoWare Auto and ROS2
Person(Integrator, "Integrator", "Autonomous Vehicle Developer")System(Autoware_Auto,"Autoware Auto", " Autoware is the world's first all-in-one open-source software for self-driving vehicles hosted under the Autoware Foundation. The Autoware.Auto project, based on ROS 2, is the next generation successor of the Autoware.AI project, based on ROS 1.")System(Ros2 , "ROS2", "Robot Operating System (ROS) is a set of open source algorithms, hardware driver software and tools developed to develop robot control software. ROS includes mature open source libraries to be used for navigation, control, motion planning, vision and simulation purposes.")
System_Ext(DDS, "DDS", "Data Distribution Service (DDS) is a data centric publish/subscribe middleware used for data transmission in distributed real time systems. ")Rel(Integrator, Autoware_Auto, "Utilizes")
Rel_Neighbor(Autoware_Auto, Ros2 , "Based on")Rel(Ros2 , DDS, "communication middleware")
@enduml
Konteyner Diyagramı (Container Diagram)
Konteyner Diyagramı üst seviye uygulama birimlerimiz, veri tabanı, başkası tarafından geliştirilmiş yazılımlar ve bunlar arasındaki ilişkileri gösterir. Bu diyagramlar üst seviye yazılım mimarisini gösterme konusunda çok başarılıdır. Bu konteynerler kendi başına çalışabilen ve farklı yere taşınabilen birimleri ifade etmektedir. Bu konteynerler arası veri iletişimi DDS, REST, AMQP, gRPC vb. iletişim teknolojisi ile yapılmaktadır. Bu diyagram ile komponentlerin çalıştığı sunucu/işlemcileri, yedekleme ve hata durumunda devreye girme gibi yapıları gösterebiliriz. Bu seviye diyagramları yazılım ekibindeki geliştirici, test mühendisi ve Devops gibi roller arası iletişim için kullanılabilir. Aşağıdaki çizimde Autoware Auto içinde yer alacak farklı yazılım bileşenleri ve aralarındaki ilişki gösterilmiştir. Bu konteyner Diyagramını çizmek için kutularla çizilmiş Autoware Auto mimarisini temel aldım. (https://www.autoware.org/post/autoware-auto-v1-0-0-release)
Yukarıda gösterilen diyagramın PlantUML scripti aşağıda verilmiştir:
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
' uncomment the following line and comment the first to use locally
' !include C4_Container.puml
' LAYOUT_TOP_DOWN()
' LAYOUT_AS_SKETCH()
LAYOUT_WITH_LEGEND()
title Container diagram for Autoware Auto
Container(Sensing, "Sensing", "Autoware mainly recognizes road environments with the help of LIDAR scanners and cameras.")
Container(Localization, "Localization", "The localization contains nodes and libraries which provide an estimate regarding the location of the vehicle using various methods and algorithms")
Container(Perception, "Perception", "filters and segmentation. The filters are nodes and libraries which are part of the filtering pipeline for sensor data. Nodes work as standalone filtering modules or cascaded with other filtering algorithms working on the same sensor data types. Enable sensor data to be grouped into clusters or objects of interest which can provide downstream procsses more information about the environment.")
Container(Planning, "Planning", "Produce a trajectory towards a provided goal. Involved in the planning process in order to alleviate the complexity of the path-planning optimization problem.")
Container(Control, "Control", "Nodes and libraries related to the controller functionalities of the vehicle. They enable the autonomous vehicle to follow a reference trajectory appropriately by converting the input trajectory into longitudinal and lateral commands.")
Container(VehicleInterface, "Vehicle Interface", "Sensor/Actuator Drivers")
System_Ext(Vehicle, "Vehicle", "The Autonomous Vehicle")
System_Ext(Sensors, "Sensors", "Lidar, Camera, GPS etc.")
Rel(Sensors, Sensing, "Socket, Serial etc.")
Rel(Sensing, Perception, "Sensing Data")
Rel_Neighbor(Perception, Planning, "Surrounding Environment")
Rel_Neighbor(Planning, Control, "Trajectory")
Rel(Control, VehicleInterface, "Vehicle Commands")
Rel(VehicleInterface,Control, "Steering, Velocity Feedback")
BiRel(VehicleInterface, Vehicle, "Can, Socket, Serial")
Rel(Sensing, Localization, "Current Position and Velocity")
Rel(Localization,Perception, "Current Position and velocity")
Rel(Localization,Planning, "Current Position and velocity")
Rel(Localization, Control, "Current Position and velocity")
Rel(VehicleInterface, Localization, "VehicleSensor")
@enduml
Komponent Diyagramı (Component Diagram)
Komponent diyagramları servis seviyesine inerek ilgili servisin yazılım bileşenlerini ve bunların arasındaki ilişkileri gösterir. Bu diyagram yazılım mimari ve geliştiriciler arası iletişim için kullanılır. C4 modelinde komponentler tek başına çalışabilir birimler değildir.
Yukarıda gösterilen diyagramın PlantUML scripti aşağıda verilmiştir:
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml
' uncomment the following line and comment the first to use locally
' !include C4_Component.puml
LAYOUT_WITH_LEGEND()
title Component Diagram for ROS2 based Autoware Auto Application
Component_Ext(DDS, "DDS Middleware library", "DDS Library from DDS vendor")
Container(usercode, "User Code", "C++", "User code for Vehicle Interface, Perception, Planning etc.")
Container_Boundary(app, "ROS2 Components") {
Component(rmw, "RMW", "C++", "ROS middleware Interface")
Component(rcl, "rcl", "C++", "ROS Client Library")
Component(rclCPP, "rclCPP", "C++", "ROS Client Library C++ Wrapper.")
Rel(rmw, DDS, "Uses","Api")
Rel(usercode, rclCPP, "Uses","Api")
Rel(rclCPP, rcl, "Uses","Api")
Rel(rcl, rmw, "Uses","Api")
}
@enduml
Kod (Code)
C4 modeli kod seviyesi için ayrıca diyagram tanımlamamış ve bu seviye diyagramların UML ile çizilmesini önermiştir. Bu kapsamda sınıf (class), ardışık işlem (sequence) ve durum (state) diyagramları kod seviyesi diyagramlar olarak kullanıla bilmektedir.
Yukarıda gösterilen diyagramın PlantUML scripti aşağıda verilmiştir:
@startuml
participant User_Code
participant RCLCpp
participant RCL
participant RMW
participant DDS
autonumber
User_Code->RCLCpp: Publisher::Publish
RCLCpp->RCL: rcl_publish
RCL->RMW: rmw_publish
RMW->DDS: data_writer.write
@enduml
PlantUML C4 modelinin yanı sıra bütün UML diyagramlarını desteklemektedir. Bu diyagramları da yukarıdakine benzer şekilde skript dili ile oluşturmak mümkün olacaktır. Bu diyagram scriptlerini de Confluence sayfasına eklene bilmektedir. İlgili diyagramlar için PlantUML sitesine bakabilirsiniz.
C4 Diayagramları:
https://github.com/hkutluca/yazilimmimarileri/tree/master/ROS2