Generating UML Class Diagram from C++ Header File using PlantUML


This post shows a way to generate a UML class diagram from C++ header file(s) using PlantUML [1] and hpp2plantuml [2].

 

Assumptions

  • Debian-based linux distribution (I used Ubuntu 20.04)

 

Steps
1. Install hpp2plantuml
hpp2plantuml is used to convert C++ header file to PlantUML. 

1-1. Install pip if not already installed.

sudo apt install python3-pip -y

1-2. Install hpp2plantuml with pip.

pip install hpp2plantuml

 

2. Install plantuml
plantuml command is used to generate a image from a PlantUML file.

2-1. Install plantuml with apt.

sudo apt install plantuml -y

 

3. Test
In this post, I use a sample c++ header file from hpp2plantuml repo to demonstrate.

3-1. Download a sample header file.

wget https://github.com/thibaultmarin/hpp2plantuml/blob/v0.8.2/tests/simple_classes_1_2.hpp

3-2. Convert the sample C++ header file to a PlantUML file.

hpp2plantuml -i simple_classes_1_2.hpp -o output.puml

3-3. Generate a class diagram image from the PlantUML file.

plantuml -tsvg output.puml

You can change the image format with the output file format option.

 

References
[1] PlantUML
[2] hpp2plantuml – GitHub

 

Showing Video Image on Tkinter Window with OpenCV


This is an example of minimal tkinter application that shows video image on the window using OpenCV.

 

Prerequisites

  • Python 3

 

Required Packages

Install packages if not already.

1. Python Imaging Library (Pillow)

pip install Pillow

2. OpenCV

pip install opencv-python

 

Code 

import tkinter as tk
from PIL import Image, ImageTk
import cv2

class MainWindow():
    def __init__(self, window, cap):
        self.window = window
        self.cap = cap
        self.width = self.cap.get(cv2.CAP_PROP_FRAME_WIDTH)
        self.height = self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
        self.interval = 20 # Interval in ms to get the latest frame

        # Create canvas for image
        self.canvas = tk.Canvas(self.window, width=self.width, height=self.height)
        self.canvas.grid(row=0, column=0)

        # Update image on canvas
        self.update_image()

    def update_image(self):
        # Get the latest frame and convert image format
        self.image = cv2.cvtColor(self.cap.read()[1], cv2.COLOR_BGR2RGB) # to RGB
        self.image = Image.fromarray(self.image) # to PIL format
        self.image = ImageTk.PhotoImage(self.image) # to ImageTk format

        # Update image
        self.canvas.create_image(0, 0, anchor=tk.NW, image=self.image)

        # Repeat every 'interval' ms
        self.window.after(self.interval, self.update_image)

if __name__ == "__main__":
    root = tk.Tk()
    MainWindow(root, cv2.VideoCapture(0))
    root.mainloop()

 

Execute the program like this:

python3 video_on_tkinter.py

 

If you want to get the image from a video file instead of a camera, specify the file name like this:

    MainWindow(root, cv2.VideoCapture('test.mp4'))

 

 

References
[1] How to update an image on a Canvas? — Stack Overflow
[2] How do you run your own code alongside Tkinter’s event loop? — Stack Overflow
[3] Displaying a video feed with OpenCV and Tkinter — pyimagesearch
[4] Python OpenCV – show a video in a Tkinter window — Solarian Programmer

 

 

Creating AltBeacon with Raspberry Pi using BlueZ Example Code (updated)

This post shows steps to create an AltBeacon [1] with Raspberry Pi, by modifying BlueZ BLE Advertisement example code (i.e. “example-advertisement).

*If you want to create Apple’s iBeacon [2], please see this post.

 

Prerequisites (parentheses indicate my environment)

  • Raspberry Pi (Raspberry Pi4 B with Raspbian Buster 2019-06-20)
  • Internet access
    To download BlueZ example code. Here is a Wi-Fi Setup steps. If you downloaded already, you can work offline.

 

Steps
1. Downloading BlueZ
1-1. Download BlueZ source code archive.

wget www.kernel.org/pub/linux/bluetooth/bluez-5.50.tar.xz

1-2. Extract the archive file.

tar xvf bluez-5.50.tar.xz

1-3. Make sure that the sample code works. [Optional]

./bluez-5.50/test/example-advertisement

Output should be like this:

$ ./bluez-5.50/test/example-advertisement
GetAll
returning props
Advertisement registered

 

2. Modify BLE Advertisement Example Code
2-1. Copy the example code.

cp ./bluez-5.50/test/example-advertisement ./example-altbeacon

2-2. Open the file and look for TestAdvertisement class.

2-3. Replace ‘__init__’ method:

    def __init__(self, bus, index):
        Advertisement.__init__(self, bus, index, 'peripheral')
        self.add_service_uuid('180D')
        self.add_service_uuid('180F')
        self.add_manufacturer_data(0xffff, [0x00, 0x01, 0x02, 0x03, 0x04])
        self.add_service_data('9999', [0x00, 0x01, 0x02, 0x03, 0x04])
        self.add_local_name('TestAdvertisement')
        self.include_tx_power = True
        self.add_data(0x26, [0x01, 0x01, 0x00])

with:

    def __init__(self, bus, index):
        company_id =  0x0118
        type =       [0xBE, 0xAC]
        id1 =        [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                      0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16]
        id2 =        [0x11, 0x22]
        id3 =        [0x33, 0x44]
        rssi_at_1m = [0xB3]
        feature  =   [0x00]
        Advertisement.__init__(self, bus, index, 'peripheral')
        self.add_manufacturer_data(company_id, type + id1 + id2 + id3 + rssi_at_1m + feature)

 

3. Test
3-1. Run the code. The console output should be same as Step 1-3.

./example-altbeacon

3-2. Find your AltBeacon running on Raspberry Pi using a beacon scanner app. I used nRF Connect on an Android phone.

 

Summary
If everything goes well, the Raspberry Pi should be broadcasting AltBeacon message and you can find it with a scanner app. Some of the AltBeacon data can be configured on Step 2-3 for your application. Here is a brief explanation of those data.

  • ‘company_id’
    Company Identifiers are defined by Bluetooth SIG [3].
  • ‘beacon_type’
    It must be ‘0xBEAC’ for AltBeacon.
  • ‘id1’
    Application unique UUID.
  • id2‘ and ‘id3
    Additional unique IDs which correspond iBeacon’s Major Number and Minor Number respectively.
  • ‘rssi_at_1m’
    Value of received signal strength at 1 meter from the device. It must be calibrated for each device when it’s deployed.

AltBeacon is an open source version of Apple’s iBeacon. It has the same functionality as iBeacon, and the two have similar data structure as below.

*2 : Bluetooth 4.0 Core Specification, Volume 3, Part C, Appendix C, 18.1 Flags
*4 Manufacture dependent value
*5 Application dependent value
*6 Device dependent value

 

References
[1] AltBeacon
[2] iBeacon – Apple Developer
[3] Company Identifiers – Bluetooth SIG
[4] BlueZ Release Notes

 

 

Creating iBeacon with Raspberry Pi using BlueZ Example Code (updated)

This post shows steps to create an iBeacon with Raspberry Pi, by modifying BlueZ BLE Advertisement example code (i.e. “example-advertisement).

Note:
Even though it uses Bluetooth Low Energy standard, iBeacon is Apple’s proprietary protocol and making/deploying iBeacon devices requires the license from Apple [1]. The scope of this post is limited to getting familiar with BlueZ advertising example code and iBeacon format for experimental purpose.

*If you want to create AltBeacon [2], which is kind of an open source version of iBeacon, please see this post.

 

Prerequisites (parentheses indicate my environment)

  • Raspberry Pi (Raspberry Pi4 B with Raspbian Buster 2019-06-20)
  • Internet access
    To download BlueZ example code. Here is a Wi-Fi Setup steps. If you downloaded already, you can work offline.

 

Steps
1. Downloading BlueZ
1-1. Download BlueZ source code archive.

wget www.kernel.org/pub/linux/bluetooth/bluez-5.50.tar.xz

1-2. Extract the archive file.

tar xvf bluez-5.50.tar.xz

1-3. Make sure that the sample code works. [Optional]

./bluez-5.50/test/example-advertisement

Output should be like this:

$ ./bluez-5.50/test/example-advertisement
GetAll
returning props
Advertisement registered

 

2. Modify BLE Advertisement Example Code
2-1. Copy the example code.

cp ./bluez-5.50/test/example-advertisement ./example-ibeacon

2-2. Open the file and look for TestAdvertisement class.

2-3. Replace ‘__init__’ method:

    def __init__(self, bus, index):
        Advertisement.__init__(self, bus, index, 'peripheral')
        self.add_service_uuid('180D')
        self.add_service_uuid('180F')
        self.add_manufacturer_data(0xffff, [0x00, 0x01, 0x02, 0x03, 0x04])
        self.add_service_data('9999', [0x00, 0x01, 0x02, 0x03, 0x04])
        self.add_local_name('TestAdvertisement')
        self.include_tx_power = True
        self.add_data(0x26, [0x01, 0x01, 0x00])

with:

    def __init__(self, bus, index):
        company_id =   0x004C
        beacon_type = [0x02, 0x15]
        uuid =        [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 
                       0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16]
        major =       [0x11, 0x22]
        minor =       [0x33, 0x44]
        tx_power =    [0xB3]
        Advertisement.__init__(self, bus, index, 'peripheral')
        self.add_manufacturer_data(company_id, beacon_type + uuid + major + minor + tx_power)

 

3. Test
3-1. Run the code. The console output should be same as Step 1-3.

./example-ibeacon

3-2. Find your ibeacon running on Raspberry Pi using a beacon scanner app. I used nRF Connect on an Android phone.

 

 

Summary
If everything goes well, the Raspberry Pi should be broadcasting iBeacon message and you can find it with a scanner app. Some of the iBeacon data can be configured on Step 2-3 for your application. Here is a brief explanation of those data.

  • ‘company_id’
    Company Identifiers are defined by Bluetooth SIG [3]. For iBeacon, it must be Apple’s ID (i.e. 0x004C).
  • ‘beacon_type’
    It must be ‘0x0215’ which means Proximity Beacon.
  • ‘uuid’
    Proximity UUID is an application unique ID.
  • major‘ and ‘minor
    Major Number and Minor Number are application dependent values which can be used to identify more precise location, etc.
  • ‘tx_power’
    Tx Power is a device dependent value. It must be calibrated for each device when it’s deployed.

iBeacon and AltBeacon have the similar functionality and data structure as below.

*2 : Bluetooth 4.0 Core Specification, Volume 3, Part C, Appendix C, 18.1 Flags
*4 Manufacture dependent value
*5 Application dependent value
*6 Device dependent value

 

References
[1] iBeacon – Apple Developer
[2] AltBeacon
[3] Company Identifiers – Bluetooth SIG
[4] BlueZ Release Notes