---
# System prepended metadata

title: 標記團隊開標記機台自動化流程

---


# 標記團隊開標記機台自動化流程 
[TOC]
### 目的: 
將過往開標記機台工作流程（非常多的人工）包成新的docker image，在啟動docker container時自動將開機台前置作業完成。

### 流程: 

1. 所有資料前處理程式合併`file_sort.py`並增加參數功能，以避免持續改動程式碼：
```python=
# -*- coding: utf-8 -*-
import os
import shutil
import click
import math
import pandas as pd
'''使用python click的功能帶入參數，可設定計畫名稱、場景名稱、相機編號，
避免持續改動此程式碼'''
@click.command()
@click.option('-p', '--project', 'project', help='Project name', required=True)
@click.option('-s', '--scene', 'scene', help='Scene name', required=True)
@click.option('-c', '--camera', 'camera', help='Camera number', required=True, multiple=True)

def file_sort(project, scene, camera):
'''將點雲資料與影像資料按照格式編排，以100張為一個pack單位，
省略因相機編號更動程式碼，這裡會直接讀取參數對應相機編號，進行批次處理'''
    work_dir = '/home/projects'
    data_dir = os.path.join(work_dir, 'data')
    pcd_dir = os.path.join(data_dir, project, 'pcd', scene)
    pcd_list = os.listdir(pcd_dir)
    pcd_list = sorted(pcd_list)
    pcd_nums = len(pcd_list)
    group_nums = 100
    pack_nums = int(math.ceil(pcd_nums*1.0/group_nums))
    cam_file = os.path.join(data_dir, project)+'/gmsl_to_cam'
    cam_info = pd.read_csv(cam_file, index_col='gmsl_name')
    for i in range(pack_nums):
        pack_name = 'pack_'+str(i+1)
        out_dir = os.path.join(work_dir, '3d-bat-server/public/input/NuScenes/ONE')
        sort_pcd_dir = os.path.join(out_dir,'pointclouds')
        if not os.path.isdir(sort_pcd_dir):
            os.makedirs(sort_pcd_dir)
    for j in range(group_nums):
        try:
            pcd_id = pcd_list[i*group_nums+j]
            shutil.copyfile(os.path.join(pcd_dir, pcd_id),os.path.join(sort_pcd_dir, pcd_id))
        except IndexError:
            break
    for num in camera:
        gmsl_name = 'gmsl_' + str(num)
        cam_name = cam_info.loc[gmsl_name].cam_name
        img_dir = os.path.join(data_dir, project, 'image', scene, gmsl_name)
        sort_img_dir = os.path.join(out_dir,'images', cam_name)
        if not os.path.isdir(sort_img_dir):
            os.makedirs(sort_img_dir)img_list = os.listdir(img_dir)
        img_list = sorted(img_list)
        sort_pcd_list = os.listdir(sort_pcd_dir)
        for pcd in sort_pcd_list:
            pcd_id = int(pcd.split('.')[0])
            thr = 99999999999999999999
            tmp_file = ''
            for img in img_list:
                if abs(pcd_id - int(img.split('.')[0]))<thr:
                    tmp_file = img
                    thr = abs(pcd_id - int(img.split('.')[0]))
        while (os.path.isfile(os.path.join(sort_img_dir, tmp_file))):
            tmp_file = img_list[img_list.index(tmp_file)+1]
        shutil.copyfile(os.path.join(img_dir, tmp_file),os.path.join(sort_img_dir, str(pcd_id) + '.jpg'))

if __name__ == '__main__':
file_sort()
```
2. Dockerfile撰寫，包成新的docker image：
```dockerfile=
# 將原本docker image作為base image帶入
FROM alex_3d_bat_server:yang_version
MAINTAINER syang
# 將/home/projects設為工作路徑，意即進到container裡時的路徑
WORKDIR /home/projects
# 使用ENTRYPOINT，使啟動container後，程式的進入點，是不會被覆蓋的，可搭配CMD做使用
ENTRYPOINT ["/bin/bash"]
# 開啟container後，執行"job_starter.sh"，來完成機台上架的前置作業
CMD ["job_starter.sh"]
```

3. `job_starter.sh`撰寫：
```bash=
#!/bin/bash
# 啟動container時帶入的環境變數，寫在env.list裡，要導入參數給file_sort.py
cam_list=$(echo $camera_list |tr -d '"')
ip_addr=`ifconfig eth0 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1`
python file_sort.py -p $project -s $scene $cam_list
# 啟動mongodb
./start_mongodb.sh
cp /home/projects/data/${project}/base_label_tool.js /home/projects/3d-bat-server/public/js
# 修改app.js中ip_address
sed -i 's/0.0.0.0/'$ip_addr'/g' /home/projects/3d-bat-server/app.js
sleep 5
# 啟動節點
node /home/projects/3d-bat-server/app.js
```

4. `env.list`撰寫，環境變數，需要按照需求修改：
 ```=
 project=<計畫名稱，資料來源資料夾名稱需與之同名>
scene=<場景編號>
camera_list=<相機編號，範例："-c 0 -c 1 -c 3 -c 4 -c 5 -c 6 -c 7">
 port_name=<預掛本機port name>
 ```
5. 啟動container：
```
＃ 切換root
sudo su -

# 啟動container
docker run -it -d -v /raid1:/home/projects/data --env-file ./env.list -p <port_name>:8080 --name <container_name> 3d_bat_server:yang_version
```
>-d: docker run之後detach continaer，若要再attach container，執行:```docker exec -it <container_name> bash```
>-v: 掛載本機磁碟，次範例為掛載本機`/raid1` 到container `/home/projects/data` 兩個資料夾會同步
>--env-file: 帶入環境變數
>-p: 指定本機 port 到container的 8080 port
>--name: 命名container

### 進度
6/18 規劃架構，撰寫`sort_file.py`
6/19 測試`sort_file.py` 撰寫job_starter.sh, dockerfile
6/20 測試docker image，除錯
6/22 測試docker image，碰到權限問題
6/23 處理權限問題，完成自動化上架
6/24 demo

### 未來工作

1. 持續降低人為操作，使用Git與Jenkins觸發流程
2. 降低資料集傳輸工作，資料前處理由NAS傳到DGX時平行處理
3. 群集管控container
4. 未來工作架構圖：

![](https://i.imgur.com/7lbilNJ.jpg)


###### keywords: docker; 自動化