diff --git a/docs/images/generated_aruco_marker.png b/docs/images/generated_aruco_marker.png
new file mode 100644
index 0000000..ac5f0d3
Binary files /dev/null and b/docs/images/generated_aruco_marker.png differ
diff --git a/lidarbot_aruco/README.md b/lidarbot_aruco/README.md
new file mode 100644
index 0000000..8cb3ad1
--- /dev/null
+++ b/lidarbot_aruco/README.md
@@ -0,0 +1,41 @@
+# Lidarbot Aruco package
+
+## Generate ArUco marker
+
+The `opencv-contrib-python` module needs to be installed and not `opencv-python`:
+
+```
+pip uninstall opencv-python
+pip install opencv-contrib-python
+```
+The computer might need to be restarted for the install to be effected.
+
+Next navigate to the path in the `lidarbot_aruco` directory:
+
+```
+cd ~/dev_ws/lidarbot_aruco/lidarbot_aruco
+```
+
+Then run the following script:
+
+```python
+python generate_aruco_marker.py --id 24 --type DICT_4X4_50 \
+ --output ../tags/DICT_4X4_50_id24.png
+```
+
+The script arguments:
+
+`--id` : The unique identifier of the ArUco tag — this is a required argument and ID must be a valid ID in the ArUco dictionary used to generate the tag
+
+`--type` : The name of the ArUco dictionary used to generate the tag; the default type is `DICT_4X4_50`
+
+`--output` : The path to the output image where the generated ArUco tag will be saved; this is a required argument
+
+Running the previous script opens a window with the generated ArUco tag displayed,
+
+
+
+
+
+To close the window, press the **q** key on the keyboard on the opened window.
+
diff --git a/lidarbot_aruco/lidarbot_aruco/generate_aruco_marker.py b/lidarbot_aruco/lidarbot_aruco/generate_aruco_marker.py
new file mode 100755
index 0000000..8566270
--- /dev/null
+++ b/lidarbot_aruco/lidarbot_aruco/generate_aruco_marker.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+
+# This script generates ArUco markers using OpenCV and Python
+
+# Adapted from https://automaticaddison.com/how-to-create-an-aruco-marker-using-opencv-python/
+# and https://pyimagesearch.com/2020/12/14/generating-aruco-markers-with-opencv-and-python/
+
+import cv2
+import argparse
+import numpy as np
+import sys
+
+# Construct the argument parser and parse the arguments
+ap = argparse.ArgumentParser()
+ap.add_argument(
+ "-o", "--output", required=True, help="path to output image containing ArUCo tag"
+)
+ap.add_argument(
+ "-i",
+ "--id",
+ type=int,
+ required=True,
+ help="ID of ArUCo tag to generate",
+)
+ap.add_argument(
+ "-t",
+ "--type",
+ type=str,
+ default="DICT_4X4_50",
+ help="type of ArUCo tag to generate",
+)
+args = vars(ap.parse_args())
+
+# The different ArUco dictinaries built into OpenCV
+ARUCO_DICT = {
+ "DICT_4X4_50": cv2.aruco.DICT_4X4_50,
+ "DICT_4X4_100": cv2.aruco.DICT_4X4_100,
+ "DICT_4X4_250": cv2.aruco.DICT_4X4_250,
+ "DICT_4X4_1000": cv2.aruco.DICT_4X4_1000,
+ "DICT_5X5_50": cv2.aruco.DICT_5X5_50,
+ "DICT_5X5_100": cv2.aruco.DICT_5X5_100,
+ "DICT_5X5_250": cv2.aruco.DICT_5X5_250,
+ "DICT_5X5_1000": cv2.aruco.DICT_5X5_1000,
+ "DICT_6X6_50": cv2.aruco.DICT_6X6_50,
+ "DICT_6X6_100": cv2.aruco.DICT_6X6_100,
+ "DICT_6X6_250": cv2.aruco.DICT_6X6_250,
+ "DICT_6X6_1000": cv2.aruco.DICT_6X6_1000,
+ "DICT_7X7_50": cv2.aruco.DICT_7X7_50,
+ "DICT_7X7_100": cv2.aruco.DICT_7X7_100,
+ "DICT_7X7_250": cv2.aruco.DICT_7X7_250,
+ "DICT_7X7_1000": cv2.aruco.DICT_7X7_1000,
+ "DICT_ARUCO_ORIGINAL": cv2.aruco.DICT_ARUCO_ORIGINAL,
+}
+
+
+# Main method
+def main():
+
+ # Check that we have a valid ArUco marker
+ if ARUCO_DICT.get(args["type"], None) is None:
+ print("[INFO] ArUco tag of '{}' is not supported".format(args["type"]))
+ sys.exit(0)
+
+ # Load the ArUco dictionary
+ arucoDict = cv2.aruco.getPredefinedDictionary(ARUCO_DICT[args["type"]])
+
+ # Allocate memory for the output ArUCo tag and then draw the ArUCo
+ # tag on the output image
+ print(
+ "[INFO] generating ArUCo tag type '{}' with ID '{}'".format(
+ args["type"], args["id"]
+ )
+ )
+ tag = np.zeros((300, 300, 1), dtype="uint8")
+ cv2.aruco.generateImageMarker(arucoDict, args["id"], 300, tag, 1)
+
+ # Write the generated ArUCo tag to disk and then display it to our
+ # screen
+ cv2.imwrite(args["output"], tag)
+ cv2.imshow("ArUCo Tag", tag)
+
+ # If "q" is pressed on the keyboard on the opened window with the aruco tag
+ # close the window
+ if cv2.waitKey(0) & 0xFF == ord("q"):
+ cv2.destroyAllWindows
+
+
+if __name__ == "__main__":
+ main()
diff --git a/lidarbot_aruco/package.xml b/lidarbot_aruco/package.xml
index 7545789..3fa1ece 100644
--- a/lidarbot_aruco/package.xml
+++ b/lidarbot_aruco/package.xml
@@ -12,6 +12,8 @@
ament_pep257
python3-pytest
+ usb-cam
+
ament_python
diff --git a/lidarbot_aruco/tags/DICT_4X4_50_id24.png b/lidarbot_aruco/tags/DICT_4X4_50_id24.png
new file mode 100644
index 0000000..227af79
Binary files /dev/null and b/lidarbot_aruco/tags/DICT_4X4_50_id24.png differ