生物量、盐度、温度采样
本示例演示如何对生物量、盐度和温度的复杂分布进行建模。通过"集群"(cluster),可以在地图上的任意位置放置生物量、盐度或温度的浓度中心,使其不再遵循常规趋势。本场景在基础的生物量和盐度函数模型之上,添加了若干可能代表浮游植物水华的生物量集群,并使用自定义温度函数模拟冰川附近温度随位置的变化。
如需上传自定义函数而不只是调整现有参数,请在脚本中调用 env.set_biomass_function("auv0", new_biomass_function)、env.set_salinity_function("auv0", new_salinity_function) 或 env.set_temperature_function("auv0", new_temperature_function),分别用于设置生物量、盐度或温度。其中 "auv0" 是您要修改的载具名称,new_temp_function 是您的自定义函数,它至少接受一个 3 元素的一维数组(位置)并返回对应数值。
注意
实时更新热图会带来明显的性能开销。本示例使用 Python 多进程在独立进程中更新热图,在保持实时显示的同时显著提升模拟性能。如果您希望使用 BST 传感器的绘图功能,强烈建议采用多进程方式。
运行后使用键盘控制载具移动,按 - 键退出。

import holoocean
import numpy as np
from pynput import keyboard
from multiprocessing import Process, Queue
import time
from holoocean.environments import HoloOceanEnvironment
from queue import Empty
def temp_fx(location):
# NOTE: It's required that we name this parameter "location"
x, y, z = location
base_temp = 4
alpha = -.2
beta = .05
return base_temp + alpha * z + beta * y
scenario = {
"name": "test_currents",
"world": "PierHarbor",
"package_name": "Ocean",
"main_agent": "auv0",
"ticks_per_sec": 60,
"frames_per_sec": 60,
"agents": [
{
"agent_name": "auv0",
"agent_type": "HoveringAUV",
"sensors": [
{
"sensor_type": "BSTSensor",
"socket": "COM",
"configuration": {
"biomass_clusters": [{"position":[10, 10, -10], "strength": 2, "falloff": 10}]
}
},
{
"sensor_type": "LocationSensor",
"socket": "COM"
}
],
"control_scheme": 0,
"location": [-20, 10, -10]
}
],
}
pressed_keys = list()
force = 200
def on_press(key):
global pressed_keys
if hasattr(key, 'char'):
pressed_keys.append(key.char)
pressed_keys = list(set(pressed_keys))
def on_release(key):
global pressed_keys
if hasattr(key, 'char'):
pressed_keys.remove(key.char)
listener = keyboard.Listener(
on_press=on_press,
on_release=on_release)
listener.start()
def parse_keys(keys, val, visualizer=None, location=None):
command = np.zeros(8)
if 'i' in keys:
command[0:4] += val
if 'k' in keys:
command[0:4] -= val
if 'j' in keys:
command[[4,7]] += .1 * val
command[[5,6]] -= .1 * val
if 'l' in keys:
command[[4,7]] -= .1 * val
command[[5,6]] += .1 * val
if 'w' in keys:
command[4:8] += val
if 's' in keys:
command[4:8] -= val
if 'a' in keys:
command[[4,6]] += val
command[[5,7]] -= val
if 'd' in keys:
command[[4,6]] -= val
command[[5,7]] += val
if 'm' in keys:
if visualizer is not None and location is not None:
visualizer.update_position(location)
return command
def plot_process(location_queue, scenario, custom_temp):
print("Process started")
visualizer = HoloOceanEnvironment.initialize_bst_graphs(config=scenario, temperature_func=custom_temp)
while True:
latest_location = None
while True:
try:
latest_location = location_queue.get_nowait()
except Empty:
break
if latest_location is not None:
visualizer.update_position(latest_location)
time.sleep(.01)
if __name__ == "__main__":
time = 0
with holoocean.make(scenario_cfg=scenario, start_world=False) as env:
# Here we pass in the custom function into the live graph instance to get accurate figures
queue = Queue()
queue.put(scenario["agents"][0]["location"])
p = Process(target=plot_process, args=(queue, scenario, temp_fx))
p.start()
env.set_temperature_function("auv0", temp_fx)
while True:
# We need to pass the same custom function into the BST sensor to get accurate readings in the terminal
sensor_data = env.tick()
location = sensor_data["LocationSensor"]
queue.put(location)
bst_data = sensor_data["BSTSensor"]
# print(bst_data)
time += 1
if '-' in pressed_keys:
break
# Your control logic
command = parse_keys(pressed_keys, force)
env.act("auv0", command)
# Clean up
p.join()