diff --git a/.gitignore b/.gitignore index 7d8f204d..e08ad99b 100644 --- a/.gitignore +++ b/.gitignore @@ -67,6 +67,10 @@ include/divisible/* # Local [Bb][Uu][Ii][Ll][Dd]/**/* +#pose evaluation logging +trackingPose.log +trackingPose.txt + ## >>>>>>>>> vscode >>>>>>>>> # gen diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 00000000..3463ef01 --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,16 @@ +cff-version: 2.1.0 +message: "If you use this software, please cite it as below." +authors: +- family-names: "Settimi" + given-names: "Andrea" + orcid: "https://orcid.org/0000-0001-5020-7331" +- family-names: "Naravich" + given-names: "Chutisilp" + orcid: "https://orcid.org/0009-0005-8782-732X" +- family-names: "Nazgul" + given-names: "Zholmagambetova" +title: "Software of TTool: a supervised AI-assisted Visual Pose Detector for AR Wood-working" +version: 2.1.0 +doi: 10.5281/zenodo.10093230 # to replace +date-released: 2024-01-10 +url: "https://github.com/ibois-epfl/TTool" \ No newline at end of file diff --git a/README.md b/README.md index ba73a9a0..bc09de3a 100644 --- a/README.md +++ b/README.md @@ -7,16 +7,44 @@

-# TTool -This is the repository hosting the API for TTool. TTool detects the 6dof of a fix toolhead from the feed of a fix camera view. -The contributions of this project are -- Making this program be both API and a standalone program. -- Model manager that manages different 3D models for 6DoF tracking. This allows user to change the model to be tracked at ease. -- Input pose to manipulate the 3D models for the initial pose. The initial pose is required by the SLET to begin the tracking. With input pose, the user can give a rough pose of the 3D, and have the SLET refine the pose afterward. -- Config manager to read the config YAML and managing I/O for saving the poses of the models for later. -- GLEW's OpenGL rendering. SLET is using QT5's OpenGL rendering. However, our [augmented carpentry](https://github.com/ibois-epfl/augmented-carpentry) is using GLFW. Hence, we changed the rendering back-end to suit our project. -- RESET, FREEZE, TRACK implementation. We found the correlation between the average score of the search points and the quality of the tracking. We added a thresholding to the SLET to exploit this score. As a consequece, the tracking works better on our setting of a fixed camera mounting on the toolhead. -- ML Tool head classification to detect the type of the tool from the camera. -- -# Wiki -The wiki of this project is hosted on [github](https://github.com/ibois-epfl/TTool/wiki) +

+ +

+ +🌲 `TTool` is developed at the [**Laboratory for Timber Construction**](https://www.epfl.ch/labs/ibois/) (director: Prof.Yves Weinand), at [**EPFL**](https://www.epfl.ch/en/), Lausanne, Switzerland. The project is part of the [**Augmented Carpentry Research**](https://www.epfl.ch/labs/ibois/augmented-carpentry/). + +🪚 `TTool` is an open-source **AI-powered and supervised 6DoF detector** for monocular camera. It is developed in C++ and for UNIX systems to allow **accurate end-effectors detection** during **wood-working operations** such as cutting, drilling, sawing and screwing with multiple tools. This is a fundamental component of any subtractive AR fabrication system since you can for instance, calculate and give users feedback on the correct orientation and depth to start and finish a hole or a cut. + +🖧 `TTool` is a AI-6DoF pose detector that recognizes automatically tools and allows the user to input an initial pose via an AR manipulator. The pose is then refined by a modified version of [SLET](://github.com/huanghone/SLET) (checkout our [changelog](docs/CHANGELOG.md)) and visualized as a projection onto the camera feed. + + +↳ `TTool` can be imported as a C++ API in a third project or used as an executable. It is tailored to our specific use case in timber carpentry but see the [Caveats](#caveats) section below to adapt it to your use case. + +🚀 For a quick hands-on start or more details, check out our [Wiki](https://github.com/ibois-epfl/TSlam/wiki). + + + +# How it works + +![Alt](./img/XX_fig_cutseuqence.png "Cut sequence for TTool") + +- `a`: the ML classifier detects the tool type from the camera feed and loads the corresponding 3D model. +- `b`: the user inputs an initial pose of the tool via an AR manipulator. +- `c`: the pose is refined with an edge-based algorithm. +- `d`: the pose is projected onto the camera buffer and displayed to the user. +- `e`: the user can now start the operation guided by computed feedback. + +![Alt](./img/XX_fig_UXaction_H.png "Show interface in action") + +On the left, the user can select the tool type and input an initial pose. On the right, the pose is refined and projected onto the camera feed. *The digital twin between the aligned model and the chainsaw plate (or any other tool) is preserved even when occuluded and inside the wood*. + +# Caveats +TTool was tailored to our specific use case. If you want to adapt it to your use case, you will need to change the following files: +- `CMakeLists.txt`: comment the following line, it won't use zenodo for the models, but you will have to provide the models yourself, se the wiki on how to do it. + https://github.com/ibois-epfl/TTool/blob/b357383e85708844efd9854291f0f85e521d227b/CMakeLists.txt#L12C1-L12C29 +- `assets/config.yaml`: list the models you want to use, and their path by replacing these lines: + https://github.com/ibois-epfl/TTool/blob/b357383e85708844efd9854291f0f85e521d227b/assets/config.yml#L57-L66 + Be sure to erase these lines specific to our use case: + https://github.com/ibois-epfl/TTool/blob/b357383e85708844efd9854291f0f85e521d227b/assets/config.yml#L67-L76 +- `ML classifier`: to adapt the ML classifier to your use case, you will need to train your own model. We have a template [in this repo](https://github.com/ibois-epfl/TTool-ai). + diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 2930bb1b..00000000 --- a/TODO.md +++ /dev/null @@ -1,39 +0,0 @@ -# Roadmap week-by-week - -- [x] See why pressing y also stops the tracking -- [x] Merge 1ere and 2eme stages together -- [ ] Complete all the datasets, and place it on another repository Zenodo -- [ ] In cmake config add a download link to the dataset (see as in tslam) -- [ ] add one single visualization with a transparent + shader for the model + the green thick contoursp (nomore 3 windows, just one) -- [ ] video exporter (see the TSlet video) -- [ ] design/refactor an API for TTool -- [ ] write smoke test to integrate to build (docstring) -- [ ] clean out the code that we do not use from tslet and other dependecies - -- [ ] Integration in AC (AC interface) -- [ ] Toolhead classifier -- [ ] Design an evaluation protocol to estimate the precision of our final tracked pose -- [ ] (optional) Toolhead global pose estimator - -- [x] - Reset / lower threshold 0.025 -> 0.0125 -- [x] *(URGENT)* Load the distortionCoeff, and the K parameters from the path, tracker should use the K, and distCoeff from the same vars as cameraPtr -- [x] *(URGENT)* load calibration distortion matrix from external zml file instead of hardcoded *be sure that all across the source code the same calibration file is consumed* see https://github.com/ibois-epfl/TSlam/blob/88e61aee7063de8da604e5488d5b65a138f2878a/utils/tslam_reconstruct.cc -- [x] branch with segmentation, main without segmentation -- [x] change to local axis for translation and orientation manipulation for the pose input (as in blender) (seems like local translation does not make any change, so only did rotation) -- [x] Reset it to text initial pose User *we have reset to text gt pose and reset to checkpoint pose* -- [x] Stop and freeze ('q' during the tracking) ('y' during tracking will write the pose to gt_pose and stop the tracking) 50% -- [x] Overwrite the initial pose with one keymap User ('y') -- [x] Reset the color histogram when rerun -> histogram get make of the projected frame and use that for the new histogram. each time the new tracking occur, the histogram is updated to the user input pose before the tracking start. So technicall it has already been done. -- [x] Input write locally the pose and the mask for each tool head - -- [x] Visualization keymap (help keystroke overlay) - -- [x] (Optional) visualize bbox -- [x] Try with the real calibration - -On hold -- [ ] Clear cache segmentation -- [ ] Switching between mask and camera feedqp -- [ ] Try manual segmentation mask for the circular saw -- [x] show segmentation -Note; if we don't allow the drill to reset, it worked better \ No newline at end of file diff --git a/dev_log/2023.03.20/baby_step_viewer.gif b/dev_log/2023.03.20/baby_step_viewer.gif deleted file mode 100644 index 3bc1a4fb..00000000 Binary files a/dev_log/2023.03.20/baby_step_viewer.gif and /dev/null differ diff --git a/dev_log/2023.03.27/Input.jpg b/dev_log/2023.03.27/Input.jpg deleted file mode 100644 index f90769f8..00000000 Binary files a/dev_log/2023.03.27/Input.jpg and /dev/null differ diff --git a/dev_log/2023.04.17/TSLET-integration.gif b/dev_log/2023.04.17/TSLET-integration.gif deleted file mode 100644 index 9d73c307..00000000 Binary files a/dev_log/2023.04.17/TSLET-integration.gif and /dev/null differ diff --git a/dev_log/README.md b/dev_log/README.md deleted file mode 100644 index b1087dd4..00000000 --- a/dev_log/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# 2023.03.07 - TSegment integration -With the camera loop from TTool, `segmentation` from `TSegmentation` can be inserted using `consume_image(camera_ptr->image())` - -Getting mask can be done using `get_mask()`. - -Result -![](2023.03.07/TSegment-integration.gif) - -## Next Step -- [x] TSegment according to [contribution style](https://github.com/ibois-epfl/augmented-carpentry/blob/main/CONTRIBUTING.md)Design -- [x] TSegment only exposed functions should be in public otherwise, private -- [x] TSegment [Docstring](https://github.com/ibois-epfl/TSlam/blob/main/src/reconstruction/ts_geometric_solver.hh) -- [X] TSegment passing ref (&) instead of a copy of image -- [x] TSegment fix on real camera -- [x] TSegment separate `compute mask` (public), `get mask` (public) function and getter for `cv::Mat mask` (private) -- [X] Design the TTool dataflow - -# 2023.03.13 -## Next Step -- [x] TTool::Visualizer (just for debugging no need to put too much time on it) -- [x] TTool:PoseInput (UI for user inputting initial pose) [Design] - - [ ] TTool:PoseInput Get familiar with CGAL [transformation](https://doc.cgal.org/latest/Kernel_23/classOptimal_bounding_box/index.html) and [OBB](https://doc.cgal.org/latest/Optimal_bounding_box/index.html) - - [ ] TTool:PoseInput LocalSystem class wrapping OBB and applying transformation to both OBB and actual 6D pose of the 3D Object - - [ ] TTool:PoseInput KeyMap class for handling user input from keyboard to the rotation and translation -- [x] TTool:PoseInput [Implement] - - [ ] TTool:PoseInput LocalSystem class - - [ ] TTool:PoseInput KeyMap class - -# 2023.03.20 - TTool::Visualizer -`ttool::Visualizer` is implemented. In TSLET, all the viewers are inside the `Tracker`. However, we decided not to do so as the tracker should only do the tracking. Thus, `ttool::Visualizer` does so instead. `UpdateVisualizer` is used to update all the viewers inside. -![](2023.03.20/baby_step_viewer.gif) - -# 2023.03.27 - 2023.03.28 - TTool::Input -`TTool::Input` is implemented. In order to do pose adjustment, the user can control it with keybinding -![](2023.03.27/Input.jpg) - -![](2023.03.27/IMG_2117.gif) - -# 2023.04.17 - Tracker -`TSLET` is included in the TTool. For now it it relatively the same as original repo TSLET where we call `Tracker` and use it. The change is `PreProcess`, `EstimatePoses`, `PostProcess` must receive frame image. This was we can pass the segmentation result to the `Tracker` to track the segmentation mask instead. `Tracker::Init()` is not used anymore, as we are no longer passing a camera pointer to the tracker. - -Here, the initial pose is intentionally set to be a bit off. After the TSegment has the mask, the tracking starts (frame id increases again), and the pose is then fine tuned. -![](2023.04.17/TSLET-integration.gif) - -Information about dependencies related to `Tracker` -``` -tracker.hh - #include "object3d.hh" - #include "object3d.cc" - - #include "template_view.hh" - #include "template_view.cc" - - #include "tclc_histograms.hh" - #include "tclc_histograms.cc" - - #include "signed_distance_transform2d.hh" - #include "signed_distance_transform2d.cc" - - -tracker.cc - #include "histogram.hh" // This is the crucial part of the tracker - #include "histogram.cc" // This is the crucial part of the tracker - - #include "search_line.hh" // This is the crucial part of the tracker - #include "search_line.cc" // This is the crucial part of the tracker - - #include "tracker_sle.hh" - #include "tracker_sle.cc" - - #include "m_func.hh" - #include "m_func.cc" -``` \ No newline at end of file diff --git a/dev_log/main_readme/detect_track.gif b/dev_log/main_readme/detect_track.gif deleted file mode 100644 index 3e40a1cd..00000000 Binary files a/dev_log/main_readme/detect_track.gif and /dev/null differ diff --git a/dev_log/main_readme/input_track.gif b/dev_log/main_readme/input_track.gif deleted file mode 100644 index 00d70af0..00000000 Binary files a/dev_log/main_readme/input_track.gif and /dev/null differ diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md new file mode 100644 index 00000000..6eeaa723 --- /dev/null +++ b/docs/CHANGELOG.md @@ -0,0 +1,7 @@ +Change Log to SLET in v.2.1.0: +- Model manager that manages different 3D models for 6DoF tracking. This allows user to change the model to be tracked at ease. +- Input pose to manipulate the 3D models for the initial pose. The initial pose is required by the SLET to begin the tracking. With input pose, the user can give a rough pose of the 3D, and have the SLET refine the pose afterward. +- Config manager to read the config YAML and managing I/O for saving the poses of the models for later. +- GLEW's OpenGL for rendering. SLET is using QT5's OpenGL rendering. However, our [augmented carpentry](https://github.com/ibois-epfl/augmented-carpentry) is using GLFW. Hence, we changed the rendering back-end to suit our project. +- RESET, FREEZE, TRACK implementation. We found the correlation between the average score of the search points and the quality of the tracking. We added a thresholding to the SLET to exploit this score. As a consequece, the tracking works better on our setting of a fixed camera mounting on the toolhead. +- ML Tool head classification to detect the type of the tool from the camera. \ No newline at end of file diff --git a/img/XX_fig_UXaction_H.png b/img/XX_fig_UXaction_H.png new file mode 100644 index 00000000..b66fda8f Binary files /dev/null and b/img/XX_fig_UXaction_H.png differ diff --git a/img/XX_fig_cutseuqence.png b/img/XX_fig_cutseuqence.png new file mode 100644 index 00000000..9b8fd0a3 Binary files /dev/null and b/img/XX_fig_cutseuqence.png differ diff --git a/img/logo_linux_green.png b/img/logo_linux_green.png index 7859acf3..95e7e335 100644 Binary files a/img/logo_linux_green.png and b/img/logo_linux_green.png differ diff --git a/img/logo_linux_green_original.png b/img/logo_linux_green_original.png new file mode 100644 index 00000000..7859acf3 Binary files /dev/null and b/img/logo_linux_green_original.png differ diff --git a/trackingPose.log b/trackingPose.log deleted file mode 100644 index bb2f8f8e..00000000 --- a/trackingPose.log +++ /dev/null @@ -1,90 +0,0 @@ -timestamp: Jul 14 2023 11:00:03 -config_file: /home/tpp/IBOIS/TTool/assets/config.yml -model_files: - modelID (1)/home/tpp/IBOIS/TTool/assets/toolheads/circular_saw_blade_makita_190/model.obj - modelID (2)/home/tpp/IBOIS/TTool/assets/toolheads/chain_saw_blade_f_250/model.obj - modelID (3)/home/tpp/IBOIS/TTool/assets/toolheads/auger_drill_bit_20_235/model.obj - modelID (4)/home/tpp/IBOIS/TTool/assets/toolheads/twist_drill_bit_32_165/model.obj - modelID (5)/home/tpp/IBOIS/TTool/assets/toolheads/self_feeding_bit_40_90/model.obj - modelID (6)/home/tpp/IBOIS/TTool/assets/toolheads/self_feeding_bit_50_90/model.obj - modelID (7)/home/tpp/IBOIS/TTool/assets/toolheads/saber_saw_blade_makita_t/model.obj - modelID (8)/home/tpp/IBOIS/TTool/assets/toolheads/brad_point_drill_bit_20_150/model.obj - modelID (9)/home/tpp/IBOIS/TTool/assets/toolheads/spade_drill_bit_25_150/model.obj -objectID: 1 -pose: - 0.985986 -0.0246229 0.165003 0.000500194 - -0.161226 0.113568 0.980357 -5.01866e-05 - -0.0428786 -0.993222 0.108004 0.141164 - 0 0 0 1 -objectID: 1 -pose: - 0.98606 -0.0193851 0.165256 0.000527938 - -0.161848 0.118726 0.979643 -0.000157116 - -0.0386109 -0.992735 0.113931 0.141731 - 0 0 0 1 -objectID: 1 -pose: - 0.98615 -0.00169704 0.165848 0.000757799 - -0.164299 0.126725 0.978232 -0.000321611 - -0.0226772 -0.991933 0.124689 0.14181 - 0 0 0 1 -objectID: 1 -pose: - 0.986119 0.00190434 0.166031 0.0006781 - -0.164754 0.135546 0.976972 3.44939e-07 - -0.0206444 -0.990766 0.133976 0.141961 - 0 0 0 1 -objectID: 1 -pose: - 0.986042 -0.00216793 0.166482 0.000580053 - -0.164457 0.143328 0.975911 -9.29842e-05 - -0.0259772 -0.98967 0.140969 0.142117 - 0 0 0 1 -objectID: 1 -pose: - 0.985652 -0.00148434 0.168784 0.000541997 - -0.166566 0.153254 0.974043 -0.00022728 - -0.0273127 -0.988182 0.150806 0.142386 - 0 0 0 1 -objectID: 1 -pose: - 0.98526 -0.00575901 0.170966 0.000453262 - -0.167773 0.162541 0.972329 -0.000182094 - -0.0333886 -0.986682 0.159176 0.142918 - 0 0 0 1 -objectID: 1 -pose: - 0.985677 -0.00650948 0.168516 0.000370604 - -0.164932 0.171235 0.971322 -0.000309483 - -0.0351787 -0.985205 0.167707 0.143133 - 0 0 0 1 -objectID: 1 -pose: - 0.985669 -0.00844493 0.168479 0.0003856 - -0.164453 0.174345 0.97085 -0.000216361 - -0.0375724 -0.984645 0.170455 0.143186 - 0 0 0 1 -objectID: 1 -pose: - 0.985789 -0.00718672 0.167836 0.000309522 - -0.163587 0.186147 0.968803 -0.000293715 - -0.0382047 -0.982492 0.182323 0.143559 - 0 0 0 1 -objectID: 1 -pose: - 0.985724 -0.00820841 0.168167 0.000342253 - -0.163563 0.190193 0.968021 -9.28031e-05 - -0.0399302 -0.981709 0.186133 0.143647 - 0 0 0 1 -objectID: 1 -pose: - 0.985869 -0.00527419 0.167432 0.000474108 - -0.163049 0.199051 0.966325 0.000115494 - -0.0384242 -0.979972 0.195376 0.143932 - 0 0 0 1 -objectID: 1 -pose: - 0.98578 -0.00865659 0.167818 0.000522051 - -0.163034 0.19271 0.967612 -0.000182693 - -0.0407166 -0.981214 0.188556 0.144101 - 0 0 0 1 diff --git a/trackingPose.txt b/trackingPose.txt deleted file mode 100644 index f890cb69..00000000 --- a/trackingPose.txt +++ /dev/null @@ -1,125 +0,0 @@ -config_file: /home/tpp/IBOIS/TTool/assets/config.yml -model_files: - modelID (1)/home/tpp/IBOIS/TTool/assets/toolheads/circular_saw_blade_makita_190/model.obj - modelID (2)/home/tpp/IBOIS/TTool/assets/toolheads/chain_saw_blade_f_250/model.obj - modelID (3)/home/tpp/IBOIS/TTool/assets/toolheads/auger_drill_bit_20_235/model.obj - modelID (4)/home/tpp/IBOIS/TTool/assets/toolheads/twist_drill_bit_32_165/model.obj - modelID (5)/home/tpp/IBOIS/TTool/assets/toolheads/self_feeding_bit_40_90/model.obj - modelID (6)/home/tpp/IBOIS/TTool/assets/toolheads/self_feeding_bit_50_90/model.obj - modelID (7)/home/tpp/IBOIS/TTool/assets/toolheads/saber_saw_blade_makita_t/model.obj - modelID (8)/home/tpp/IBOIS/TTool/assets/toolheads/brad_point_drill_bit_20_150/model.obj - modelID (9)/home/tpp/IBOIS/TTool/assets/toolheads/spade_drill_bit_25_150/model.obj -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 -objectID: 1 -pose: - 1 0 0 0 - 0 0.0348995 -0.999391 0.08 - 0 0.999391 0.0348995 1.27 - 0 0 0 1 diff --git a/dev_log/2023.03.07/TSegment-integration.gif b/vid/mosaic.gif similarity index 54% rename from dev_log/2023.03.07/TSegment-integration.gif rename to vid/mosaic.gif index d69754b8..fe754a41 100644 Binary files a/dev_log/2023.03.07/TSegment-integration.gif and b/vid/mosaic.gif differ diff --git a/dev_log/2023.03.27/IMG_2117.gif b/vid/mosaic.mp4 similarity index 68% rename from dev_log/2023.03.27/IMG_2117.gif rename to vid/mosaic.mp4 index 3ad97898..45323707 100644 Binary files a/dev_log/2023.03.27/IMG_2117.gif and b/vid/mosaic.mp4 differ