Spaces:
Runtime error
Runtime error
Upload 2 files
Browse files- app.py +96 -0
- requirements.txt +3 -0
app.py
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
|
3 |
+
#from pandas import DataFrame as df
|
4 |
+
import csv
|
5 |
+
import math
|
6 |
+
|
7 |
+
def main():
|
8 |
+
st.title('Quaternion to Eular angle conversion for SLAM')
|
9 |
+
|
10 |
+
st.markdown('Only support single file conversion at this time. Will be processing batch files in the future. \n')
|
11 |
+
st.markdown('The input file should be in the format of csv where fields are separated by ";". The output will be also a csv file. \n')
|
12 |
+
st.markdown('The input field order is\n')
|
13 |
+
st.markdown('fileID; image file name; time stamp; pose_x; pose_y; pose_z; ori_w; ori_x; ori_y; ori_z.\n')
|
14 |
+
st.markdown('The unit of the input pos_x, pos_y and pos_z is meter.\n')
|
15 |
+
st.markdown('The unit of the output pos_x, pos_y and pos_z is feet, and ori_roll, ori_pitch, ori_yaw is degree.\n')
|
16 |
+
|
17 |
+
run_the_app()
|
18 |
+
|
19 |
+
@st.cache_data()
|
20 |
+
def euler_from_quaternion(x, y, z, w):
|
21 |
+
t0 = +2.0 * (w * x + y * z)
|
22 |
+
t1 = +1.0 - 2.0 * (x * x + y * y)
|
23 |
+
roll_x = math.atan2(t0, t1)
|
24 |
+
|
25 |
+
t2 = +2.0 * (w * y - z * x)
|
26 |
+
#t2 = +1.0 if t2 > +1.0 else t2
|
27 |
+
#t2 = -1.0 if t2 < -1.0 else t2
|
28 |
+
pitch_y = math.asin(t2)
|
29 |
+
|
30 |
+
t3 = +2.0 * (w * z + x * y)
|
31 |
+
t4 = +1.0 - 2.0 * (y * y + z * z)
|
32 |
+
yaw_z = math.atan2(t3, t4)
|
33 |
+
# the y here obvious points to the 90 anticlockwise to x, instead of the general definition of quaternion and Eular angles where y points to 90 degree clockwise to x
|
34 |
+
return math.degrees(roll_x), -math.degrees(pitch_y), math.degrees(yaw_z) # in degree
|
35 |
+
|
36 |
+
def run_the_app():
|
37 |
+
uploaded_files = st.file_uploader(
|
38 |
+
"Upload csv files",
|
39 |
+
type="csv",
|
40 |
+
accept_multiple_files=True)
|
41 |
+
|
42 |
+
if uploaded_files:
|
43 |
+
if st.button("Clear uploaded files"):
|
44 |
+
st.empty()
|
45 |
+
st.experimental_rerun()
|
46 |
+
|
47 |
+
with open('converted.csv', 'w', newline='', encoding='utf-8') as wf:
|
48 |
+
fieldnames = ['# pano poses v1.0: ID',
|
49 |
+
'filename',
|
50 |
+
'timestamp',
|
51 |
+
'pano_pos_x',
|
52 |
+
'pano_pos_y',
|
53 |
+
'pano_pos_z',
|
54 |
+
'pano_ori_roll',
|
55 |
+
'pano_ori_pitch',
|
56 |
+
'pano_ori_yaw'
|
57 |
+
]
|
58 |
+
writer = csv.DictWriter(wf, fieldnames=fieldnames)
|
59 |
+
writer.writeheader()
|
60 |
+
|
61 |
+
with open(uploaded_files, 'r', encoding='utf-8') as rf:
|
62 |
+
reader = csv.DictReader(rf)
|
63 |
+
|
64 |
+
for row in reader:
|
65 |
+
row_v = list(row.values())[0].split(';')
|
66 |
+
# in the input file, the quat order is ori_w,ori_x,ori_y,ori_z
|
67 |
+
roll, pitch, yaw = euler_from_quaternion(float(row_v[7]),
|
68 |
+
float(row_v[8]),
|
69 |
+
float(row_v[9]),
|
70 |
+
float(row_v[6]))
|
71 |
+
|
72 |
+
# now yaw is the angle to x, anticlockwise. But our definition is the angle to y(north), clockwise
|
73 |
+
yaw = -yaw + 90.0
|
74 |
+
if yaw < -180.0:
|
75 |
+
yaw += 360.0
|
76 |
+
elif yaw > 180.0:
|
77 |
+
yaw -= 360.0
|
78 |
+
|
79 |
+
rec = {fieldnames[0]: row_v[0],
|
80 |
+
fieldnames[1]: row_v[1][1:],
|
81 |
+
fieldnames[2]: row_v[2],
|
82 |
+
fieldnames[3]: float(row_v[3])*3.28084,
|
83 |
+
fieldnames[4]: float(row_v[4])*3.28084,
|
84 |
+
fieldnames[5]: float(row_v[5])*3.28084,
|
85 |
+
fieldnames[6]: roll,
|
86 |
+
fieldnames[7]: pitch,
|
87 |
+
fieldnames[8]: yaw}
|
88 |
+
writer.writerow(rec)
|
89 |
+
|
90 |
+
|
91 |
+
|
92 |
+
st.download_button("Download the converted files",
|
93 |
+
data = "converted.csv")
|
94 |
+
|
95 |
+
if __name__ == "__main__":
|
96 |
+
main()
|
requirements.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
streamlit
|
2 |
+
csv
|
3 |
+
math
|