Background
I noticed I have not posted anything about drones. There are plenty of Youtube videos showing all settings and functions of drones. I use a DJI Mini 4 Pro that produces extraordinary videos and images. I have mostly used way points. I stumbled upon some sites that helps you plan your flights and also creates a 3d map of the ground. What may be called photogrammetry. We will use two services to make this. We will also use free open source programs. This will not cost you any cloud tokens or monthly subscriptions. You will just use your on- prem hardware for processing. There are many different sites and programs. This is just one way. DJI also have enterprise services like Terra that might do a far better job. This post is for hobby users. We will use tthe two services below.
Opendronemap
Opendronemap is an open source project with some tools to make 3d maps of images. It does not really have to be drone images. It consists of several services all called ODM something. It might be a little bit complicated to setup. however there is also a payed app version. We will deploy it with Docker.
DJI Mapper
DJI Mapper is a tool developed by Yaros. There are other tools but I found this easy. I suppose you could do this in the DJI Fly app to but it would be quite hard.

Other tools
WSL – Windows subsystem for Windows. Becasue we want to run the application on our Windows computer.
Docker – To make the application run. With Docker Compose
Portainer – To monitor our containers
Installation
In my case I will be using WSL as my computer is Windows. Running Docker on Windows is not a good idea. I could just as well use a dedicated Linux server. I have som Intel NUC servers running but in my case the mail laptop has better CPU and GPU. The image processing takes time and we need the speed of good hardware. Another option would be to setup the WebODM on a NUC and the worker node on another machine. I might do that in the future.
WSL
The easy way of installing WSL is by typing:
wsl --install
This will install Ubuntu. There are more settings and you can find the docs here. As WSL is Linux the path of your files will be:
\\wsl$\Ubuntu
You might need this path later on. Now when you open up a terminal you will have the option of opening WSL.

Docker and Docker Compose (and the Opendronemap containers)
Docker is a way of running applications in containers. I won’t go into detail but just explain how to make it work. First read the docs here. Things might change compared to below. Open your WSL terminal first.
Set up Docker’s apt repository.
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
Install the Docker packages.
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Now Docker is installed. In general I suppose it could be a good idea to follow the official docs but in my case I wanted to get more control of what was happening and also be able to auto start the containers.
The script they are using is ./webodm.sh start and this more or less do the same thing optimizing the containers. So it is up to you. Use the script in the docs or do it like I do. Both will work. It might be easier using webodm.sh as you are able to parse arguments. Check out ./webodm.sh –help. However my way gives me more control.
I execute this:
git clone https://github.com/OpenDroneMap/WebODM
cd WebODM
Now you have everyhing in this folder. Now run “sudo nano docker-compose.yml”. Add it like this.
# This configuration does not include a processing node
# Which makes for faster setup times
#version: '2.1'
volumes:
dbdata:
appmedia:
services:
db:
image: opendronemap/webodm_db
container_name: db
expose:
- "5432"
volumes:
- ${WO_DB_DIR}:/var/lib/postgresql/data:Z
restart: unless-stopped
oom_score_adj: -100
webapp:
image: opendronemap/webodm_webapp
container_name: webapp
entrypoint: /bin/bash -c "chmod +x /webodm/*.sh && /bin/bash -c \"/webodm/wait-for-postgres.sh db /webodm/wait-for-it.sh -t 0 broker:6379 -- /webodm/start.sh\""
volumes:
- ${WO_MEDIA_DIR}:/webodm/app/media:z
ports:
- "${WO_PORT}:8000"
depends_on:
- db
- broker
- worker
environment:
- WO_PORT
- WO_HOST
- WO_DEBUG
- WO_BROKER
- WO_DEV
- WO_DEV_WATCH_PLUGINS
- WO_SECRET_KEY
restart: unless-stopped
oom_score_adj: 0
worker:
image: opendronemap/webodm_webapp
container_name: worker
entrypoint: /bin/bash -c "/webodm/wait-for-postgres.sh db /webodm/wait-for-it.sh -t 0 broker:6379 -- /webodm/wait-for-it.sh -t 0 webapp:8000 -- /webodm/worker.sh start"
volumes:
- ${WO_MEDIA_DIR}:/webodm/app/media:z
depends_on:
- db
- broker
environment:
- WO_BROKER
- WO_DEBUG
- WO_SECRET_KEY
restart: unless-stopped
oom_score_adj: 250
node-odm:
image: opendronemap/nodeodm
expose:
- "3000"
restart: unless-stopped
oom_score_adj: 500
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: always
ports:
- "9000:9000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /portainer_data:/data
We use the original compose file but with some minor differences. We add the processing node on the same machine. We disable the obsolete version row and we add portainer. Now run:
sudo docker compose up -d
This will download the containers and start them. They will be running until your computer restarts. You could just as well run Docker on a server and in this case the containers would be up and running all the time. Now you can open up http://localhost:9000. As you can see below all containers are up and running. You can restart them here. Also note the ip address of the node container. This is the docker ip address and not the local host ip. You will need this.

Opendronemap
I suppose we have already installed opendronemap components in the docker file above. It is up and running. There are many other settings like using Nvidia GPU or Micmac. You could add this in the docker file.
You can not go to http://localhost:8000/dashboard/. Create a user and password. Add a node and start testing. It could be a good idea to get back to the docs again so you can optimize the map generation.
I imported some sample images like these bananas. I just wanted to make sure it worked. Note that when you edit the node you should use the ip address of the container node. You can see this in Portainer. In my case it was 172.18.0.5. It may change! If so you can set it static.

Mapping my house
So I was ready to do a real test. First I used DJI Mapper to plan my waypoints. There are some good docs at the site so I won´t go into any details here. But some tips are.
- Make sure you use correct camera settings
- Do not modify the route after you added into Dji fly on your controller
- Use wait when taking photos in order to avoid blur as the drone is moving
There is a new version coming soon that will be able to:
Split the mission into multiple submissions
Use distance-based triggers to reduce drastically the amount of waypoints needed
Below are the settings I used. Note the delay

And the Mini 4 Pro camera settings

So the drone went up above my house and tool 39 photos. Most likely I should have been taken more and also tried with another camera angle. The photos looked like this one.

Below are the 3d map after the process in odm was finished. I did try with other settings as well but it more or less looked the same
Conclusion
Setting up ODM on WSL is quite simple. And the program runs quite fast even on my poor hardware. The main issue was my poor images. I also did a test with Reality Capture from Epic. It is also free and can be used with Unreal.