Request for Ubuntu 20.04 Support on Axon Vicharak

Hello Team,

We are currently working on building an autonomous drone and are using Axon Vicharak as the SBC to handle all autonomous-related tasks. We noticed that the officially supported files and resources are available only for Ubuntu 22.04 and 24.04.

However, for our project setup, we specifically require Ubuntu 20.04. Could you please let us know if Ubuntu 20.04 can be supported on Axon Vicharak, or if there is a way to enable compatibility for our use case?

This would greatly help us in ensuring smooth integration of our autonomous stack.

Thank you

Do you require any GUI-related features, or would it be better to opt for a minimal setup in Ubuntu 20.04?

While our main requirement is to run the autonomy stack headlessly on Axon Vicharak having basic GUI support would be useful for visualization and debugging purposes (e.g., Rviz, Gazebo).

If GUI support is not available, a server/minimal version of Ubuntu 20.04 is also fine, provided it comes with an upgraded kernel and all device tree overlays enabled for full pin access. Since we plan to utilize all available pins on Axon for our drone setup, this compatibility is important.

Okay, Give me a few hours, will provide minimal Image with overlays support so that you can start work upon it. Mostly tomorrow, you will get image.

1 Like

@cycloneuav, Wokring upon it.

1 Like

Initial Beta Release of Focal eMMC Image + Kernel 5.10

In case you face any difficulties, let us know over here, so we can trace the issue in a proper manner.

1 Like

Thanks you, I’ll let you know once I test it. If I run into any issues, I’ll provide details here so we can track them down properly.

@cycloneuav,
What kind of software compatibility issues did you face in Ubuntu 22/24 in your setup?
As we recommend for longer support, it would be great it you use 24.04 LTS.

We faced compatibility constraints with our setup. Specifically, my local planner is compatible with Ubuntu 20.04, which is why we are using Ubuntu 20 as the base system.

Regarding the Raspberry Pi Camera Module V1 (5MP), we are facing the following issues on Ubuntu 20.04 Server:

Sometimes the camera shows a completely blank screen.

When an image is displayed, it is almost entirely black, with only bright light sources faintly visible.

To verify the hardware, we tested the same camera with:

Raspberry Pi OS → works correctly.

Axon’s Ubuntu 22.04 Desktop → works correctly.

So, the problem seems to be specific to Ubuntu 20.04 Server.
I’ve attached the test code for reference.
samp.py (1.2 KB)

Mostly, It’s because of packages.
Let me check it and get back to you.

1 Like

Thanks for checking into this. Since it’s been about a week, I just wanted to ask if you have an estimate on how many more days it might take to identify/fix the package issue with the Raspberry Pi Camera on Ubuntu 20.04 Server. This will help us plan our integration timeline accordingly.

Thanks for following up. We currently have quite a bit on our plate, but we will resolve it within the next 1–2 days. We appreciate your patience and understanding as we work through this. Currently, our primary focus is on enhancing the user-friendliness of the Ubuntu 22.04 Jammy and Ubuntu 24.04 Noble images, while also improving their overall stability.

1 Like

@cycloneuav, our plate is quite full at the moment, and creating an image right now wouldn’t be worthwhile, as we’re in the midst of improving everything for Ubuntu 22.04 and, more importantly, Ubuntu 24.04 LTS.

1 Like

I wanted to follow up on the camera issue I had mentioned earlier for Ubuntu 20 on Axon. I understand your focus has shifted toward Ubuntu 22.04 and 24.04, but I’d appreciate it if you could let me know whether there’s any update or workaround available for the Ubuntu 20 environment.

For Camera, you might need to install below package.

sudo apt update
sudo apt install camera-engine-rkaiq 

Reboot the device.

sudo reboot
1 Like

We recommend sending your queries for Ubuntu 20 over email with a proper list.

1 Like

Camera Support in Ubuntu 20

  1. Install the required package

    sudo apt update && sudo apt install camera-engine-rkaiq -y && sudo apt install python3-opencv -y && pip3 install flask
    

    Install gstreamer

     sudo apt install gstreamer1.0-tools 
     sudo apt install gstreamer1.0-plugins-base 
     sudo apt install gstreamer1.0-plugins-good
     sudo apt install gstreamer1.0-plugins-bad
     sudo apt install  gstreamer1.0-libav
    
  2. Enable service :

    sudo systemctl enable camera-engine-rkaiq
    sudo systemctl restart camera-engine-rkaiq
    
  3. Reboot device.

    sudo reboot
    
  4. Run code below:

Axon OV5647 Live Streamer
=========================

A lightweight Flask + OpenCV (GStreamer backend) application to stream live
MJPEG video from a V4L2 camera device such as /dev/video11 on the RK3588.

- Captures frames via GStreamer pipeline using NV12 → BGR conversion.
- Encodes frames as JPEG in a background thread.
- Serves them as an MJPEG stream at  http://<BOARD_IP>:5000/video
- Provides a simple HTML viewer at  http://<BOARD_IP>:5000/

Developed by: Vicharak
"""

import threading, time, cv2
from flask import Flask, Response, jsonify

DEV = "/dev/video11"
W, H = 2592, 1944
JPEG_QUALITY = 80

PIPELINE = (
    f"v4l2src device={DEV} io-mode=dmabuf ! "
    "queue max-size-buffers=1 leaky=downstream ! "
    f"video/x-raw,format=NV12,width={W},height={H} ! "
    "videoconvert ! video/x-raw,format=BGR ! "
    "appsink drop=1 max-buffers=2 sync=false"
)

class CaptureThread(threading.Thread):
    def __init__(self, pipeline):
        super().__init__(daemon=True)
        self.pipeline = pipeline
        self.cap = None
        self.lock = threading.Lock()
        self.running = True
        self.jpg = None

    def open(self):
        cap = cv2.VideoCapture(self.pipeline, cv2.CAP_GSTREAMER)
        return cap if cap.isOpened() else None

    def run(self):
        backoff = 0.5
        while self.running:
            if self.cap is None:
                self.cap = self.open()
                if self.cap is None:
                    time.sleep(backoff)
                    backoff = min(backoff * 2, 5)
                    continue
                backoff = 0.5
            ok, frame = self.cap.read()
            if not ok or frame is None:
                try: self.cap.release()
                except: pass
                self.cap = None
                time.sleep(0.1)
                continue
            ok, buf = cv2.imencode(".jpg", frame, [int(cv2.IMWRITE_JPEG_QUALITY), JPEG_QUALITY])
            if ok:
                with self.lock:
                    self.jpg = buf.tobytes()

    def get_jpeg(self, timeout=5.0):
        t0 = time.time()
        while time.time() - t0 < timeout and self.running:
            with self.lock:
                if self.jpg:
                    return self.jpg
            time.sleep(0.02)
        return None

    def stop(self):
        self.running = False
        try:
            if self.cap: self.cap.release()
        except: pass

cam = CaptureThread(PIPELINE)
cam.start()

app = Flask(__name__)

@app.route("/")
def index():
    return (
        "<html><head><title>Axon OV5647 Live</title></head>"
        "<body style='margin:0;background:#000;display:flex;justify-content:center;align-items:center;height:100vh;'>"
        "<img src='/video' style='width:100%;max-width:960px;object-fit:contain;background:#000'/>"
        "</body></html>"
    )

@app.route("/video")
def video():
    def gen():
        boundary = b"--frame\r\n"
        headers = b"Content-Type: image/jpeg\r\nCache-Control: no-cache\r\n\r\n"
        # wait for first frame
        first = cam.get_jpeg(timeout=10.0)
        if first is None:
            yield boundary + headers + b"\r\n"
            return
        while True:
            jpg = cam.get_jpeg(timeout=2.0)
            if jpg is None:
                time.sleep(0.05)
                continue
            yield boundary + headers + jpg + b"\r\n"
    return Response(gen(), mimetype="multipart/x-mixed-replace; boundary=frame")

@app.route("/healthz")
def healthz():
    return jsonify({"running": True, "dev": DEV, "w": W, "h": H})

if __name__ == "__main__":
    print("Pipeline:\n", PIPELINE)
    print("Serving MJPEG at http://0.0.0.0:5000/video")
    app.run(host="0.0.0.0", port=5000, debug=False, threaded=True)
  1. Run code.
python3 <File_name>,py