GSoC/2020/StatusReports/KitaeKim: Difference between revisions

From KDE Community Wiki
< GSoC‎ | 2020‎ | StatusReports
 
(64 intermediate revisions by the same user not shown)
Line 1: Line 1:
[[File:Kirogi Goose 800x655.png|frame|center]]
== Imporove MAVLink integration of Kirogi ==
== Imporove MAVLink integration of Kirogi ==


The Kirogi is Ground Control Station(GCS) for controlling Unmanned Vehicles like drones which is developed recently.
The Kirogi is a Ground Control Station(GCS) for managing Unmanned Aerial Vehicles like drones.


It's comparatively young project so it dose not support all standards of MAVLink protocol which is the famous protocol between GCS and UAVs yet.
It's comparatively young project so it dose not support all standards of MAVLink protocol which is used to communicate with drone's firmware like PX4 and Ardupilot.


My goal is to imporove MAVLink protocol integration of Kirogi so that it supports all functionalities of the MAVLink protocol.
The goal is to imporove MAVLink protocol integration of Kirogi so that it supports most functionalities of the protocol.


'''Mentors:''' Tomaz Canabrava, Eike Hein, Patrick José Pereira, Sung Jae Cho
'''Mentors:''' Tomaz Canabrava, Eike Hein, Patrick José Pereira, Sung Jae Cho
Line 12: Line 14:
=== Community Bonding Period ===
=== Community Bonding Period ===


The first thing i did during this period is studying about MAVLink protocol.
# Study about MAVLink protocol. ''- Done''
# Read code of Kirogi and QGroundControl in comparison. ''- Done''
# Study about Qt and C++ development. ''- In progress''


I studied about it before GSoC begins but i felt that i need to study about it more.
The first thing i did during this period is studying more about MAVLink protocol.
 
Through this, i got familiarized much more with the protocol and become able to think clearly what i should implement.


The MAVLink protocol packet is structured in this way:
The MAVLink protocol packet is structured in this way:
Line 22: Line 24:
[[File:A mavlink packet structure.png|frame|center]]<ref>https://mavlink.io/en/</ref>
[[File:A mavlink packet structure.png|frame|center]]<ref>https://mavlink.io/en/</ref>


The protocol uses sub-protocols to extend it's functionality. The sub-protocols are identified using 'MSG ID' section of the packet.
This protocol uses sub-protocols to extend it's functionality. Those are identified using 'MSG ID' section of the packet. Additional information for sub-protocol is transported through 'PAYLOAD' section of the packet.


The sub-protocols use 'PAYLOAD' section to transport information for the sub-protocol. (e.g., arguments for the sub-protocol)
First feature that will be implemented during phase 1 is integration of heartbeat protocol.


The thing i need to focus on about the protocol during phase 1 is:
The heartbeat protocol is one of MAVLink's sub-protocols. It is used to identify existence of vehicle along with its properties. This allows us to discover vehicle connected to the network and notice when they have been disconnected. It also allows us to handle incoming messages appropriately based on type of the vehicle and route messages to system on different interface.


# '''Heartbeat Protocol:''' It is used to identify existence of system along with its system id, component id, vehicle type, component type, flight mode and flight stack. This allows us to discover system connected to the network and notice when they have been disconnected and handle incoming messages appropriately based on type of vehicle and route messages to system on different interface.
Second thing i did during this period is reading code of Kirogi and QGroundControl in comparison. The QGroundControl is a standard de facto control station for MAVLink drones.
# '''Message Channel:''' It is used by helper functions provided by MAVLink library. The MAVLink library manages buffers per channels internally.<ref>mavlink_helpers.h</ref> So we need to manage channels to manage multiple vehicles. It seems one channel per one connection is suffice.


The protocol can control up to 255 vehicles at the same time because 'SYS ID' section of the packet is 1 byte size.
The QGroundControl has MultiVehicleManager and LinkManager which are used to manage vehicles and links as name suggests. The MultiVehicleManager creates vehicle object when incoming message has unknown system id. The vehicle object contains information of the actual vehicle like system id and connection status. The LinkManager creates link object when user wants to establish new connection. Both have pointer to ToolBox which contains pointer to main components like MultiVehicleManager and LinkManager so they can reference each other when it's needed.


So i will implement vehicle manager for managing multiple vehicles during the phase 1. The vehicle manager should be able to identify vehicles based on the heartbeat message, manage vehicle's channel and parse incoming messages based on the vehicle's channel.
The Kirogi aims to support various firmwares including PX4 and Ardupilot. For that, it uses KPlugin.


Second thing i did during this period is reading code of Kirogi and QGroundControl in comparison. QGroundControl is the most famous GCS for the MAVLink out there.
Kirogi's UI is general to all plugins. I felt that this generality prevent me to implement various features for plugins. It would be modified to load some plugin-specific elements at runtime in future.


Through this i learned about MAVLink protocol much more and the way the QGroundControl supports the protocol.
Main components of MAVLink plugin are MAVLinkVehicle and MAVLinkConnection. The MAVLinkVehicle contains information of the actual vehicle. This class has method to processes incoming message and manage connection. The MAVLinkConnection contains QUdpSocket and method to receive and parse incoming messages. Other plugins of Kirogi have same structure.


The QGroundControl has MultiVehicleManager and LinkManager class which are used to manage vehicles and links.
It seems implementing all functionalities of MAVLink not breaking general structure of Kirogi is quite challenging.


The MultiVehicleManager creates vehicle object when incoming message has unknown system id just like what i wrote on the proposal. The vehicle object contains information for the vehicle like system id.
=== Coding Period Phase 1 ===


The link in QGroundControl contains actual interface like QSerialPort and information for that like port number.
# Improve integration of command protocol. ''- Done''
# Implement vehicle manager for managing multiple vehicles. ''- Done''
# Write unit tests of implementation. ''- Cancelled''
# Write a documentation about implementation. ''- Done''
# Study about Qt and C++ development. ''- Keep doing''


The LinkManager creates link object when user wants to create new one. One thing interesting is that the link class inherits QThread so that it can run on new thread by creating it. But the Kirogi community's developers are quite skeptical about this because one or up to three thread seems enough to handle incoming messages of 255 vehicles.
Command protocol specifies that every commands should be followed by ack message from the vehicle that receives the command. If no ack message was received, GCS should resend message until it reaches max count. This feature was implemented before GSoC begins.


Both have pointer to toolbox which contains pointer to MultiVehicleManager, LinkManager, MAVLinkProtocol and name a few. So they can reference each other when it's needed.
New MAVLinkVehicleManager class creates vehicle object when incoming message has unknown system id. It stores vehicle object in MAVLinkVehicleModel class. This class inherits from QAbstractList so that in can provide list of vehicles to UI.


The link passes incoming message to MAVLinkProtocol class. It dose MAVLink-specific jobs like parsing packet to message or checking packet sequence and measuring packet lost using 'SEQ' section of the packet. It passes the parsed message to every component like vehicle object or LinkManager. This looks quite inefficient because every components need to process message to check if it's destination is itself.
The Kirogi use KPlugin XT but it can't configure plugin-specific options. The MAVLinkConnectionConfig class is for configuring MAVLink's UDP/TCP/Serial connection. This class is connected to UI so that users can configure options using methods.


The Kirogi aims to support various firmwares like tello, parrot, ardupilot and px4. For that purpose it uses KPlugin to load functionalities dynamically in runtime.
About the future works, Kirogi's UI is generic to every plugins but it seems some plugins need it's own UI. In example, Plan Manager for MAVLink plugin. My conclusion is that I can't implement UI that is really generic to all plugins so I need to load some of UI elements at runtime based on the plugin. 'Check List', 'Global Drawer', 'Navigation Map', 'Settings' pages would be appropriate places to load those elements.


One thing interesting is that the Kirogi's Ui is general to all of plugins. The Kirogi uses same QML code for the Ui and loads information from abstract classes like AbstractVehicle. Plugin-specific classes inherit those abstract classes.
Some miscellaneous works like renaming some redundant variables or modifying existing classes are done during this phase.


This generality was obstacle to me because it seems, for me, different model needs different Ui. I'm still thinking about this.
I was planning to adopt Test-Driven development at the first time, but it seems there are many other things to learn like how drone's firmware works so that I have not enough time to study and adopt it.


MAVLink plugin of Kirogi consists of two main components:
=== Coding Period Phase 2 ===
 
* Support TCP and Serial connection. ''- Done''
* Implement UI for selecting multiple vehicles. ''- Done''
* Divide PR into smaller pieces. ''- In progress''
* Write a documentation about implementation. ''- Done''
* Study about Qt and C++ development. ''- Keep doing''
 
Because there's no code for TCP and Serial connection in Kirogi's codebase, I created classes for
connection abstraction including 'ConnectionConfiguration', 'TcpConfiguraiton' and so on.


# '''MAVLinkVehicle:''' This is used to store information of vehicle. This also processes incoming message and manage connection.
There's an 'AbstractConnection' class for connection abstraction but if we want to manage it's
# '''MAVLinkConnection:''' This is used to establish connection. This class receives and parses incoming message and passes it to MAVLinkVehicle. Currently it supports UDP connection only.
properties at Kirogi's base level(libkirogi and QML), we have to provide a generic way to manage
connection's property.


It's apparent that we need more classes to manage multiple vehicles and connections.
We can't just use same connection class for all plugins because the way how connection-related
procedures defined depends on the type of drone.


The challenging thing is that i need to implement all functionalities not breaking the general structure of Kirogi. Or i need to modify other plugins too. I can modify all plugins because i have much time and effort to spend on this but i think it's better to not or minimally touch them because what assigned to me is MAVLink plugin and other plugins are not mine. And modifying already working code can create bugs.
At the first time, I was thinking to implement things like 'AbstractUdpConnection',
'AbstractTcpConnection' that defines common properties of those connections and implement plugin's
connection inheriting them.


=== Coding Period Phase 1 ===
But I found that some connections need more than one types of methods to operate. In example, some
connection may use TCP for handshaking and UDP for communicating.
 
So I decided to mix 'AbstractConnection' and some kind of connection configuration class to
implement plugin's connection. In this way, we can implement 'ArbitraryConnection' mixing
'AbstractConnection' with 'UdpConfiguration' and 'TcpConfiguration' which inherits
'ConnectionConfiguration'.
 
I implemented connection classes for mavlink like 'MAVLinkUdpConnection', 'MAVLinkTcpConnection' and
'MAVLinkSerialConnection' using them.
 
I also wrote code for managing multiple connections as well although it's not a thing that I planned
do at this phase. That's because I thought that I had to think about implementations that make use
of connection-related classes I wrote while actually writing them.
 
I also implemented basic drawler for selecting vehicle inside of 'Check List' element.
 
I was doing everything in one branch and created one PR for everything which results in that my
mentors couldn't review my work efficiently. So I started break things into smaller pieces.


Main goals of this phase are:
=== Coding Period Phase 3 ===


# Implement command queue to send and receive commands properly. ''- Done''
* Divide PR into smaller pieces. ''- Done''
# Implement vehicle manager for managing multiple vehicles. ''- Done''
* Implement connection manager for managing multiple connections. ''- Done''
# Write unit tests of implementation. ''- To be done''
* Implement UI for managing multiple connections. ''- Not done''
# Write documentations about implementation. ''- To be done''
* Write a documentation about implementation. ''- Done''
* Study about Qt and C++ development. ''- Keep doing''


The command queue was implemented before GSoC begins. Command Protocol specifies that every commands should be followed by ack message. If no ack message was received, GCS should resend message until it reaches max count.
I divided the branch that I mentioned previous progress report into four smaller branches.


The MAVLinkVehicleManager class is implemented during this phase. It creates vehicle object when incoming message has unknown system id. It stores vehicle object in MAVLinkVehicleModel class. This class inherits QAbstractList so that in can provide list of vehicles to QML Ui in future.
One for basic chamges for all of other branches, others for connection abstraction, vehicle
management and connection management. Latter three branches depend on first one and one for
connection management depends on conneciton abstraction.


The idea is simple. MAVLinkVehicleManager class processes message before MAVLinkVehicle class and creates vehicle object based on it. It passes message to vehicle object if message has known system id.
I also implemented connection manager for managing multiple connections. new
'AbstractConnectionModel' class, which is used for managing connections, creates new configuration
with default value when user wants to create new connection. Then user can edit it and create
connection based on the configuraiton.


I thought about future works during this period too. The Kirogi's Ui is generic to every plugins but it seems i need to implement plugin-specific Ui. In example, Plan Manager Ui for MAVLink plugin. My conclusion is that i can't implement really generic Ui so i need to load Ui components at runtime. Patrick and Tomaz created MR about this.
When user wants to edit existing one, it duplicates configuration of selected connection and user
can edit it. When user choose to save it, the model copies value that user wrote into existing
connection's configuration.


The Kirogi's Ui loads information from currentVehicle variable in main.qml. This variable changes it's value based on signal vehicleAdded from plugin. So it would enough to emit vehicleAdded when user wants to change current vehicle. The signal vehicleAdded is renamed to currentVehicleChanged for that purpose.
The reason why I decided to copy values rather than replacing existing connection with new
connection is because there maybe a vehicle that uses connection that is being edited. In that case,
it's more easier copy values than replacing connection object and make vehicle to use it.


And i implemented MAVLinkConnectionConfig class. Kirogi is using KPlugin XT for configuring but it can't configure options per plugins. The MAVLinkConnectionConfig class is for configuring MAVLink's UDP/TCP/Serial connection which will be implemented in future. This class provides information and methods to QML Ui so that users can configure options.
This class also provides list of available serial port. Some invalid ports will be filtered to
prevent users to select them.


Writing unit tests and documentations will be finished before phase 2 begins.
I was thinking to implement basic UI for managing connections but I didn't. because my mentors
pointed out that it's better to manage vehicles and connections in more generic way rather than
implementing managers for each plugin. In this way, users can control different types of vehicles
like parrot bebop and pixhawk at the same time. It seems good idea for me so I'll start implementing
UI for manging vehicles and connections after backend architecture for that feature gets specifed.


Some miscellaneous works like renaming some redundant variables or modifying existing classes are done during this phase.
=== Blog Writings ===


=== Coding Period Phase 2 ===
* [https://www.develoot.me/improve-mavlink-integration-of-kirogi-progress-report-1/ Improve MAVLink Integration of Kirogi – Progress Report 1]
* [https://www.develoot.me/improve-mavlink-protocol-integration-progress-report-2/ Improve MAVLink Integration of Kirogi – Progress Report 2]
* [https://www.develoot.me/improve-mavlink-integration-of-kirogi-progress-report-3/ Improve MAVLink Integration of Kirogi – Progress Report 3]


Main goals of this phase are:
== Branches and PRs ==


# Connect vehicle model to Ui so that user can select vehicle to control. ''- To be done''
* [https://invent.kde.org/utilities/kirogi/-/merge_requests/126 Improve basic integration of mavlink protocol]
# Implement TCP and Serial connection. ''- To be done''
* [https://invent.kde.org/develoot/kirogi/-/tree/01-mavlink-connection-types 01-mavlink-connection-types]
# Implement connection manager for managing multiple connections. ''- To be done''
* [https://invent.kde.org/develoot/kirogi/-/tree/02-mavlink-vehicle-model 02-mavlink-vehicle-model]
# Write unit tests of implementation. ''- To be done''
* [https://invent.kde.org/develoot/kirogi/-/tree/03-mavlink-connection-model 03-mavlink-connection-model]
# Write documentation about implementation. ''- To be done''


== Related Links ==
== Related Links ==
Line 105: Line 157:
* [https://docs.google.com/document/d/1J0uazpHGZaybt9lW7UqP8c4xnRVXMbqxOMJqTNBHsZg/edit?usp=sharing Proposal: Improve MAVLink integration of Kirogi]
* [https://docs.google.com/document/d/1J0uazpHGZaybt9lW7UqP8c4xnRVXMbqxOMJqTNBHsZg/edit?usp=sharing Proposal: Improve MAVLink integration of Kirogi]
* [https://invent.kde.org/develoot/kirogi Kitae Kim / Kirogi]
* [https://invent.kde.org/develoot/kirogi Kitae Kim / Kirogi]
* [https://mavlink.io/en/ MAVLink Developer Guide]


== Contacts ==
== Contacts ==

Latest revision as of 01:40, 31 August 2020

Imporove MAVLink integration of Kirogi

The Kirogi is a Ground Control Station(GCS) for managing Unmanned Aerial Vehicles like drones.

It's comparatively young project so it dose not support all standards of MAVLink protocol which is used to communicate with drone's firmware like PX4 and Ardupilot.

The goal is to imporove MAVLink protocol integration of Kirogi so that it supports most functionalities of the protocol.

Mentors: Tomaz Canabrava, Eike Hein, Patrick José Pereira, Sung Jae Cho

Progress Reports

Community Bonding Period

  1. Study about MAVLink protocol. - Done
  2. Read code of Kirogi and QGroundControl in comparison. - Done
  3. Study about Qt and C++ development. - In progress

The first thing i did during this period is studying more about MAVLink protocol.

The MAVLink protocol packet is structured in this way:

[1]

This protocol uses sub-protocols to extend it's functionality. Those are identified using 'MSG ID' section of the packet. Additional information for sub-protocol is transported through 'PAYLOAD' section of the packet.

First feature that will be implemented during phase 1 is integration of heartbeat protocol.

The heartbeat protocol is one of MAVLink's sub-protocols. It is used to identify existence of vehicle along with its properties. This allows us to discover vehicle connected to the network and notice when they have been disconnected. It also allows us to handle incoming messages appropriately based on type of the vehicle and route messages to system on different interface.

Second thing i did during this period is reading code of Kirogi and QGroundControl in comparison. The QGroundControl is a standard de facto control station for MAVLink drones.

The QGroundControl has MultiVehicleManager and LinkManager which are used to manage vehicles and links as name suggests. The MultiVehicleManager creates vehicle object when incoming message has unknown system id. The vehicle object contains information of the actual vehicle like system id and connection status. The LinkManager creates link object when user wants to establish new connection. Both have pointer to ToolBox which contains pointer to main components like MultiVehicleManager and LinkManager so they can reference each other when it's needed.

The Kirogi aims to support various firmwares including PX4 and Ardupilot. For that, it uses KPlugin.

Kirogi's UI is general to all plugins. I felt that this generality prevent me to implement various features for plugins. It would be modified to load some plugin-specific elements at runtime in future.

Main components of MAVLink plugin are MAVLinkVehicle and MAVLinkConnection. The MAVLinkVehicle contains information of the actual vehicle. This class has method to processes incoming message and manage connection. The MAVLinkConnection contains QUdpSocket and method to receive and parse incoming messages. Other plugins of Kirogi have same structure.

It seems implementing all functionalities of MAVLink not breaking general structure of Kirogi is quite challenging.

Coding Period Phase 1

  1. Improve integration of command protocol. - Done
  2. Implement vehicle manager for managing multiple vehicles. - Done
  3. Write unit tests of implementation. - Cancelled
  4. Write a documentation about implementation. - Done
  5. Study about Qt and C++ development. - Keep doing

Command protocol specifies that every commands should be followed by ack message from the vehicle that receives the command. If no ack message was received, GCS should resend message until it reaches max count. This feature was implemented before GSoC begins.

New MAVLinkVehicleManager class creates vehicle object when incoming message has unknown system id. It stores vehicle object in MAVLinkVehicleModel class. This class inherits from QAbstractList so that in can provide list of vehicles to UI.

The Kirogi use KPlugin XT but it can't configure plugin-specific options. The MAVLinkConnectionConfig class is for configuring MAVLink's UDP/TCP/Serial connection. This class is connected to UI so that users can configure options using methods.

About the future works, Kirogi's UI is generic to every plugins but it seems some plugins need it's own UI. In example, Plan Manager for MAVLink plugin. My conclusion is that I can't implement UI that is really generic to all plugins so I need to load some of UI elements at runtime based on the plugin. 'Check List', 'Global Drawer', 'Navigation Map', 'Settings' pages would be appropriate places to load those elements.

Some miscellaneous works like renaming some redundant variables or modifying existing classes are done during this phase.

I was planning to adopt Test-Driven development at the first time, but it seems there are many other things to learn like how drone's firmware works so that I have not enough time to study and adopt it.

Coding Period Phase 2

  • Support TCP and Serial connection. - Done
  • Implement UI for selecting multiple vehicles. - Done
  • Divide PR into smaller pieces. - In progress
  • Write a documentation about implementation. - Done
  • Study about Qt and C++ development. - Keep doing

Because there's no code for TCP and Serial connection in Kirogi's codebase, I created classes for connection abstraction including 'ConnectionConfiguration', 'TcpConfiguraiton' and so on.

There's an 'AbstractConnection' class for connection abstraction but if we want to manage it's properties at Kirogi's base level(libkirogi and QML), we have to provide a generic way to manage connection's property.

We can't just use same connection class for all plugins because the way how connection-related procedures defined depends on the type of drone.

At the first time, I was thinking to implement things like 'AbstractUdpConnection', 'AbstractTcpConnection' that defines common properties of those connections and implement plugin's connection inheriting them.

But I found that some connections need more than one types of methods to operate. In example, some connection may use TCP for handshaking and UDP for communicating.

So I decided to mix 'AbstractConnection' and some kind of connection configuration class to implement plugin's connection. In this way, we can implement 'ArbitraryConnection' mixing 'AbstractConnection' with 'UdpConfiguration' and 'TcpConfiguration' which inherits 'ConnectionConfiguration'.

I implemented connection classes for mavlink like 'MAVLinkUdpConnection', 'MAVLinkTcpConnection' and 'MAVLinkSerialConnection' using them.

I also wrote code for managing multiple connections as well although it's not a thing that I planned do at this phase. That's because I thought that I had to think about implementations that make use of connection-related classes I wrote while actually writing them.

I also implemented basic drawler for selecting vehicle inside of 'Check List' element.

I was doing everything in one branch and created one PR for everything which results in that my mentors couldn't review my work efficiently. So I started break things into smaller pieces.

Coding Period Phase 3

  • Divide PR into smaller pieces. - Done
  • Implement connection manager for managing multiple connections. - Done
  • Implement UI for managing multiple connections. - Not done
  • Write a documentation about implementation. - Done
  • Study about Qt and C++ development. - Keep doing

I divided the branch that I mentioned previous progress report into four smaller branches.

One for basic chamges for all of other branches, others for connection abstraction, vehicle management and connection management. Latter three branches depend on first one and one for connection management depends on conneciton abstraction.

I also implemented connection manager for managing multiple connections. new 'AbstractConnectionModel' class, which is used for managing connections, creates new configuration with default value when user wants to create new connection. Then user can edit it and create connection based on the configuraiton.

When user wants to edit existing one, it duplicates configuration of selected connection and user can edit it. When user choose to save it, the model copies value that user wrote into existing connection's configuration.

The reason why I decided to copy values rather than replacing existing connection with new connection is because there maybe a vehicle that uses connection that is being edited. In that case, it's more easier copy values than replacing connection object and make vehicle to use it.

This class also provides list of available serial port. Some invalid ports will be filtered to prevent users to select them.

I was thinking to implement basic UI for managing connections but I didn't. because my mentors pointed out that it's better to manage vehicles and connections in more generic way rather than implementing managers for each plugin. In this way, users can control different types of vehicles like parrot bebop and pixhawk at the same time. It seems good idea for me so I'll start implementing UI for manging vehicles and connections after backend architecture for that feature gets specifed.

Blog Writings

Branches and PRs

Related Links

Contacts

Email: [email protected]

LinkedIn: https://www.linkedin.com/in/kitae-kim-511032182/

Footnotes