Skip to content

Commit d65a2bd

Browse files
committed
Adding manual controls to move swarm in unison and display altitude in div marker.
1 parent 87a836c commit d65a2bd

File tree

2 files changed

+61
-3
lines changed

2 files changed

+61
-3
lines changed

cnc/streamlit/overview.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from streamlit_folium import st_folium
1313
from folium.plugins import MiniMap
1414
from util import stream_to_dataframe, connect_redis, connect_zmq, get_drones, menu, COLORS, authenticated
15+
from st_keypressed import st_keypressed
1516

1617
if "map_server" not in st.session_state:
1718
st.session_state.map_server = "Google Hybrid"
@@ -27,6 +28,18 @@
2728
st.session_state.inactivity_time = 1 #min
2829
if "trail_length" not in st.session_state:
2930
st.session_state.trail_length = 500
31+
if "armed" not in st.session_state:
32+
st.session_state.armed = False
33+
if "roll_speed" not in st.session_state:
34+
st.session_state.roll_speed = 50
35+
if "yaw_speed" not in st.session_state:
36+
st.session_state.yaw_speed = 45
37+
if "thrust_speed" not in st.session_state:
38+
st.session_state.thrust_speed = 50
39+
if "pitch_speed" not in st.session_state:
40+
st.session_state.pitch_speed = 50
41+
if "gimbal_speed" not in st.session_state:
42+
st.session_state.gimbal_speed = 50
3043

3144
st.set_page_config(
3245
page_title="Commander",
@@ -129,7 +142,7 @@ def draw_map():
129142
text = folium.DivIcon(
130143
icon_size="null", #set the size to null so that it expands to the length of the string inside in the div
131144
icon_anchor=(-20, 30),
132-
html=f'<div style="color:white;font-size: 12pt;font-weight: bold;background-color:{COLORS[marker_color]};">{drone_name}&nbsp;({int(row["battery"])}%)</div>',
145+
html=f'<div style="color:white;font-size: 12pt;font-weight: bold;background-color:{COLORS[marker_color]};">{drone_name}&nbsp;({int(row["battery"])}%) [{row["altitude"]:.2f}m]</div>',
133146

134147
)
135148
plane = folium.Icon(
@@ -210,6 +223,10 @@ def draw_map():
210223
)
211224

212225
st.session_state.trail_length = tiles_col[3].number_input(":straight_ruler: **:gray[Trail Length]**", step=500, min_value=500, max_value=2500, value=st.session_state.trail_length)
226+
mode = ":joystick: **:green[Manual (armed)]**" if st.session_state.armed else ":joystick: **:red[Manual (disarmed)]**"
227+
with tiles_col[4]:
228+
st.caption(mode)
229+
st.checkbox(key="armed", label="Arm Drone?")
213230

214231
col1, col2 = st.columns([3, 1])
215232
with col1:
@@ -255,3 +272,46 @@ def draw_map():
255272
on_click=rth,
256273
)
257274

275+
st.session_state.key_pressed = st_keypressed()
276+
if st.session_state.armed and st.session_state.selected_drones is not None:
277+
req = cnc_pb2.Extras()
278+
req.commander_id = os.uname()[1]
279+
req.cmd.for_drone_id = json.dumps([d for d in st.session_state.selected_drones])
280+
#req.cmd.manual = True
281+
if st.session_state.key_pressed == "t":
282+
req.cmd.takeoff = True
283+
st.info(f"Instructed {req.cmd.for_drone_id} to takeoff.")
284+
elif st.session_state.key_pressed == "g":
285+
req.cmd.land = True
286+
st.info(f"Instructed {req.cmd.for_drone_id} to land.")
287+
else:
288+
pitch = roll = yaw = thrust = gimbal_pitch = 0
289+
if st.session_state.key_pressed == "w":
290+
pitch = 1 * st.session_state.pitch_speed
291+
elif st.session_state.key_pressed == "s":
292+
pitch = -1 * st.session_state.pitch_speed
293+
elif st.session_state.key_pressed == "d":
294+
roll = 1 * st.session_state.roll_speed
295+
elif st.session_state.key_pressed == "a":
296+
roll = -1 * st.session_state.roll_speed
297+
elif st.session_state.key_pressed == "i":
298+
thrust = 1 * st.session_state.thrust_speed
299+
elif st.session_state.key_pressed == "k":
300+
thrust = -1 * st.session_state.thrust_speed
301+
elif st.session_state.key_pressed == "l":
302+
yaw = 1 * st.session_state.yaw_speed
303+
elif st.session_state.key_pressed == "j":
304+
yaw = -1 * st.session_state.yaw_speed
305+
elif st.session_state.key_pressed == "r":
306+
gimbal_pitch = 1 * st.session_state.gimbal_speed
307+
elif st.session_state.key_pressed == "f":
308+
gimbal_pitch = -1 * st.session_state.gimbal_speed
309+
st.caption(f"PCMD(pitch = {pitch}, roll = {roll}, yaw = {yaw}, thrust = {thrust})")
310+
req.cmd.pcmd.yaw = yaw
311+
req.cmd.pcmd.pitch = pitch
312+
req.cmd.pcmd.roll = roll
313+
req.cmd.pcmd.gaz = thrust
314+
req.cmd.pcmd.gimbal_pitch = gimbal_pitch
315+
st.session_state.key_pressed = None
316+
st.session_state.zmq.send(req.SerializeToString())
317+
rep = st.session_state.zmq.recv()

cnc/streamlit/pages/control.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,6 @@ def draw_map():
287287
disabled=st.session_state.rth_sent,
288288
on_click=rth,
289289
)
290-
if "armed2" not in st.session_state:
291-
st.session_state.armed2 = False
292290
if st.session_state.manual_control:
293291
#st.subheader(f":blue[Manual Control Enabled]")
294292
mode = ":green[Manual (armed)]" if st.session_state.armed else ":red[Manual (disarmed)]"

0 commit comments

Comments
 (0)