多媒体服务接口
云台视频流服务
硬件
晨星机器狗的云台摄像机可同时提供可见光和红外视频流,如下所示:

软件接口:
云台摄像机的视频流可通过标准 RTSP API 网络接口访问。
- 可见光视频流URL:
rtsp://admin:yoseen2018@192.168.100.202:554/h264/ch1/sub/av_stream - 红外视频流URL:
rtsp://admin:yoseen2018@192.168.100.202:554/h264/ch2/sub/av_stream
注意事项:
- 开发设备需连接机器狗的网络(WiFi 名称:IS_**,WiFi 密码:DaystarBot)以访问视频流。
- 相机流 URL 应根据机器狗的 IP 地址进行调整:
- 连接到机器狗的网络后,检查机器狗的 IP 是否为
192.168.100.*或者192.168.144.*- 如果网段为
100, 则在流 URL 中使用192.168.100.202 - 如果网段为
144, 则在流 URL 中使用192.168.144.202
- 如果网段为
- 连接到机器狗的网络后,检查机器狗的 IP 是否为
视频流验证与测试:
你可以使用 VLC 媒体播放器来连接和显示视频流。

可见光视频流:

红外视频流:

| 功能 | C++ | ROS | Python | C# |
|---|---|---|---|---|
| 获取云台姿态信息 | ✔ | ✔ | ✔ | ✔ |
| 控制云台运动角度 | ✔ | ✔ | ✔ | ✔ |
| 控制云台持续运动 | ✔ | ✔ | ✔ | ✔ |
| 辅助聚焦 | ✔ | ✔ | ✔ | ✔ |
| 切换对焦模式 | ✔ | ✔ | ✔ | ✔ |
| 灯光控制 | ✔ | ✔ | ✔ | ✔ |
云台控制接口
获取云台姿态信息
该接口用于发布云台的当前位姿信息。
| 参数名称 | 类型 | 描述 |
|---|---|---|
pan | float32 | 表示pan的旋转 (-180~180) |
tilt | float32 | 表示tilt的旋转(-90~90) |
zoom | float32 | 表示zoom的缩放(1-25) |
focus | uint16 | 表示对焦值(4000~40000) |
ROS2 接口
| Topic 名称 | Topic 类型 | 角色 |
|---|---|---|
cam/PTZ_CAM/set_ptzf_position | cam_msgs::msg::PtzfPosition | 订阅方 |
消息结构
ptzf_position: PtzfPosition类型,包含四个类型:
| 参数名称 | 类型 | 描述 |
|---|---|---|
pan | float32 | 表示pan的旋转 (-180~180) |
tilt | float32 | 表示tilt的旋转(-90~90) |
zoom | float32 | 表示zoom的缩放(1-25) |
focus | uint16 | 表示对焦值(4000~40000) |
测试方法
ros2 topic echo /cam/sysb_CAM/set_sysbf_positionPython 接口
subscribe_ptzf_position(ptzf_position_callback)
功能说明
订阅云台的实时位置信息,包括水平角度(pan)、垂直角度(tilt)、变焦(zoom)和焦点(focus)参数。
参数说明
| 参数名 | 类型 | 必填/默认值 | 说明 |
|---|---|---|---|
ptzf_position_callback | function | 必填 | 实时接收点云状态信息的回调函数。 |
返回值
| 类型 | 说明 |
|---|---|
void | 无返回值。 |
使用案例
def on_ptz_pos(data):
if "ptzf_position" in data:
pos = data["ptzf_position"]
print(f"PTZ位置: P={pos.get('pan'):.2f}, T={pos.get('tilt'):.2f}, Z={pos.get('zoom'):.2f}")
client.subscribe_ptzf_position(on_ptz_pos)unsubscribe_ptzf_position()
功能说明
取消订阅云台的实时位置信息。
参数说明
无。
返回值
| 类型 | 说明 |
|---|---|
void | 无返回值。 |
使用案例
client.unsubscribe_ptzf_position();C# 接口
void SubscribesysbfPosition(Action<sysbfPositionStamped> callback = null)
功能说明
订阅云台的实时位置信息,包括水平角度(pan)、垂直角度(tilt)、变焦(zoom)和焦点(focus)参数。
参数说明
| 参数名 | 类型 | 必填/默认值 | 说明 |
|---|---|---|---|
callback | Action<sysbfPositionStamped> | null | 接收位置数据的回调函数。 |
返回值
| 类型 | 说明 |
|---|---|
void | 无返回值。 |
void UnsubscribesysbfPosition()
功能说明
取消订阅云台的实时位置信息。
参数说明
无。
返回值
| 类型 | 说明 |
|---|---|
void | 无返回值。 |
使用案例
// 订阅sysb位置信息
_robotMutiMediaClient?.SubscribesysbfPosition(OnsysbPositionReceived);
// 回调函数处理位置数据
private void OnsysbPositionReceived(sysbfPositionStamped positionData)
{
Debug.Log($"sysb Position - Pan: {positionData.position.pan}, " +
$"Tilt: {positionData.position.tilt}, " +
$"Zoom: {positionData.position.zoom}, " +
$"Focus: {positionData.position.focus}");
}
// 取消订阅sysb位置信息
_robotMutiMediaClient?.UnsubscribesysbfPosition();C++ 接口
bool subscribesysbfPosition()
功能说明
订阅云台的实时位置信息,包括水平角度(pan)、垂直角度(tilt)、变焦(zoom)和焦点(focus)参数。
参数说明
无。
返回值
| 类型 | 说明 |
|---|---|
bool | true表示成功,false表示失败。 |
bool unsubscribesysbfPosition()
功能说明
取消订阅云台的实时位置信息。
参数说明
无。
返回值
| 类型 | 说明 |
|---|---|
bool | true表示成功,false表示失败。 |
使用案例
Lenovo::Daystar::SDK sdk;
auto &sysb = sdk.getSYSB();
if (sysb.connect()) {
// 订阅位置消息
sysb.subscribePtzfPosition();
// 执行一些操作...
std::this_thread::sleep_for(std::chrono::seconds(10));
// 取消订阅
if (sysb.unsubscribePtzfPosition()) {
std::cout << "云台位置订阅已取消" << std::endl;
}
}控制云台运动角度:
该接口用于使调用云台移动到某个角度。
该接口涉及四个参数:
| 参数名称 | 类型 | 描述 |
|---|---|---|
relative | bool | 表示是否启用相对移动 |
ptzf_position | PtzfPosition | 包含四个字段:pan, tilt, zoom, focus |
ptzf_position 字段:
| 字段名称 | 类型 | 描述 |
|---|---|---|
pan | float32 | 表示pan的旋转 (-180~180) |
tilt | float32 | 表示tilt的旋转(-90~90) |
zoom | float32 | 表示zoom的缩放(1-25) |
focus | uint16 | 表示对焦值(4000~40000) |
ROS2 接口
| Service 名称 | Service 类型 | 角色 |
|---|---|---|
/cam/PTZ_CAM/set_ptzf_position | cam_msgs::srv::SetPtzfPosition | 客户端 |
消息结构
cam_msgs::srv::SetPtzfPosition::Request 包括以下字段:
| 参数名称 | 类型 | 描述 |
|---|---|---|
relative | bool | 表示是否启用相对移动 |
ptzf_position | PtzfPosition | 包含四个字段:pan, tilt, zoom, focus |
ptzf_position 字段:
| 字段名称 | 类型 | 描述 |
|---|---|---|
pan | float32 | 表示pan的旋转 (-180~180) |
tilt | float32 | 表示tilt的旋转(-90~90) |
zoom | float32 | 表示zoom的缩放(1-25) |
focus | uint16 | 表示对焦值(4000~40000) |
注:focus字段仅在手动对焦模式生效。
测试方法
- 调用接口,使云台左转90度,上转30度,并放大到10倍:
ros2 service call /cam/sysb_CAM/set_sysbf_position cam_msgs/srv/SetsysbfPosition "relative: false
sysbf_position:
pan: 90.0
tilt: 30.0
zoom: 10.0
focus: 0"Python 接口
set_ptzf_position(position: PtzfPosition, relative)
功能说明
控制云台移动到某个角度。
参数说明
| 参数名 | 类型 | 必填/默认值 | 说明 |
|---|---|---|---|
position | PtzfPosition | 必填 | 角度指令,说明参考ROS2接口。 |
relative | bool | 必填 | 表示是否启用相对移动。 |
返回值
| 类型 | 说明 |
|---|---|
bool | 操作是否成功。 |
使用案例
async with WebSocketsysbClient(host=args.host, port=args.port) as client:
await asyncio.sleep(1)
position = sysbfPosition(
pan=args.pan,
tilt=args.tilt,
zoom=args.zoom,
focus=args.focus
)
success = await client.set_sysbf_position(position, relative=args.relative)C# 接口
void SetsysbPosition(float pan, float tilt, float zoom, ushort focus, bool relative = false)
功能说明
控制云台移动到某个角度。
参数说明
| 参数名 | 类型 | 必填/默认值 | 说明 |
|---|---|---|---|
pan | float | 必填 | 水平角度 (度)。 |
tilt | float | 必填 | 垂直角度 (度)。 |
zoom | float | 必填 | 变焦倍数。 |
focus | ushort | 必填 | 聚焦值。 |
relative | bool | false | 是否为相对位置 (true=相对,false=绝对)。 |
返回值
| 类型 | 说明 |
|---|---|
void | 无返回值。 |
使用案例
// 绝对位置控制
robotMutiMediaClient.SetsysbPosition(45.0f, -30.0f, 2.0f, 0, false);
// 相对位置控制(在当前位置基础上调整)
robotMutiMediaClient.SetsysbPosition(10.0f, 0, 0, 0, true);C++ 接口
void callsysbPosition(float pan, float tilt, float zoom, uint16_t focus, bool relative = false)
功能说明
控制云台到指定位置。
参数说明
| 参数名 | 类型 | 必填/默认值 | 说明 |
|---|---|---|---|
pan | float | 必填 | 水平角度 (度)。 |
tilt | float | 必填 | 垂直角度 (度)。 |
zoom | float | 必填 | 变焦倍数。 |
focus | uint16_t | 必填 | 聚焦值。 |
relative | bool | false | 是否为相对位置 (true=相对,false=绝对)。 |
返回值
| 类型 | 说明 |
|---|---|
void | 无返回值。 |
使用案例
Lenovo::Daystar::SDK sdk;
auto &sysb = sdk.getSYSB();
if (sysb.connect()) {
// 绝对位置控制:云台转到水平30度,垂直15度
sysb.callsysbPosition(30.0f, 15.0f, 1.5f, 100, false);
// 相对位置控制:在当前位置基础上水平右转10度
sysb.callsysbPosition(10.0f, 0.0f, 1.0f, 100, true);
}控制云台持续运动
该接口用于使调用云台持续移动。
该接口涉及四个参数:
| 参数名称 | 类型 | 描述 |
|---|---|---|
pan | float32 | 水平方向速度值,正值逆时针转,负值顺时针转,0不转 (-12~12) |
tilt | float32 | 垂直方向速度值,正值向上转,负值向下转,0不转(-12~12) |
zoom | float32 | 缩放速度值,正值放大,负值缩小,0不动 (-12~12) |
focus | uint16 | 对焦速度值,正值推远焦,负值拉近焦,0不动(-12~12) |
注意:控制上下左右持续运动时,zoom和focus参数必须设置为0.
ROS2 接口
| Topic 名称 | Topic 类型 | 角色 |
|---|---|---|
/cam/PTZ_CAM/ptzf_cmd_vel | cam_msgs::srv::PtzfCmdVel.msg | 客户端 |
消息结构
cam_msgs::srv::PtzfCmdVel::Request 包括以下字段:
| 参数名称 | 类型 |
|---|---|
pan | float32 |
tilt | float32 |
zoom | float32 |
focus | uint16 |
测试方法
- 调用接口,云台开始左转:
ros2 topic pub /cam/sysb_CAM/sysbf_cmd_vel cam_msgs/srv/sysbfCmdVel "
pan: 8.0
tilt: 0.0
zoom: 0.0
focus: 0"Python 接口
publish_ptzf_cmd_vel(cmd_vel: PtzfCmdVel) - 持续控制云台运动
- `PtzfCmdVel`: 速度指令class sysbfCmdVel:
"""云台控制速度数据类"""
pan: float = 0.0 # 水平方向速度值,正值逆时针转,负值顺时针转,0不转 (-12~12)
tilt: float = 0.0 # 垂直方向速度值,正值向上转,负值向下转,0不转(-12~12)
zoom: float = 0.0 # 缩放速度值,正值放大,负值缩小,0不动 (-12~12)
focus: float = 0.0 # 对焦速度值,正值推远焦,负值拉近焦,0不动(-12~12)使用案例
async with WebSocketsysbClient(host=args.host, port=args.port, client_name="complex_control") as client:
await asyncio.sleep(1)
await client.advertise_sysbf_cmd_vel()
await asyncio.sleep(0.5)
cmd_vel = sysbfCmdVel(
pan=args.pan,
tilt=args.tilt,
zoom=args.zoom,
focus=args.focus
)
print(f"复合运动控制: Pan={args.pan}, Tilt={args.tilt}, Zoom={args.zoom}, Focus={args.focus}")
success = await client.publish_sysbf_cmd_vel(cmd_vel)C# 接口
void MovesysbContinues(float panSpeed, float tiltSpeed, float zoomSpeed, float focusSpeed = 0)使用案例
// 向左连续移动
robotMutiMediaClient.MovesysbContinues(8.0f, 0, 0, 0);
// 向右连续移动
robotMutiMediaClient.MovesysbContinues(-8.0f, 0, 0, 0);
// 向上连续移动
robotMutiMediaClient.MovesysbContinues(0, 8.0f, 0, 0);
// 向下连续移动
robotMutiMediaClient.MovesysbContinues(0, -8.0f, 0, 0);
// 放大(变焦)
robotMutiMediaClient.MovesysbContinues(0, 0, 1.0f, 0);
// 缩小(变焦)
robotMutiMediaClient.MovesysbContinues(0, 0, -1.0f, 0);
// 停止移动
robotMutiMediaClient.MovesysbContinues(0, 0, 0, 0);C++接口
publishPtzfCmdVel简介
/**
* @brief 发布云台速度控制命令
*
* @param pan 水平旋转速度
* @param tilt 垂直旋转速度
* @param zoom 变焦速度
* @param focus 聚焦速度
*/
void publishsysbfCmdVel(float pan, float tilt, float zoom, float focus);使用案例
Lenovo::Daystar::SDK sdk;
auto &sysb = sdk.getSYSB();
if (sysb.connect()) {
// 以中等速度向右旋转
for (int i = 0; i < 40; i++)
{
sysb.publishsysbfCmdVel(0.8f, 0.0f, 0.0f, 0.0f);
// std::cout << "发送第 " << (i + 1) << "/40 次速度控制命令" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
std::this_thread::sleep_for(std::chrono::seconds(2));
// 停止所有运动
sysb.stopAllMovement();
}辅助聚焦
ROS2 接口
该接口用于使调用云台移动到某个角度。
| Service 名称 | Service 类型 | 角色 |
|---|---|---|
/cam/PTZ_CAM/auto_focus | cam_msgs::srv::AutoFocus | 客户端 |
消息结构
cam_msgs::srv::AutoFocus::Request 包括以下字段:
| 参数名称 | 类型 | 描述 |
|---|---|---|
focus_mode | uint8 | 1: 全局辅助聚焦 2: 区域辅助聚焦 |
pixel_bbox | Bbox | 包含四个字段:x_min, y_min, x_max, y_max |
pixel_bbox 字段:
| 字段名称 | 类型 | 描述 |
|---|---|---|
x_min | int32 | 矩形区域左上顶点的x坐标 |
y_min | int32 | 矩形区域左上顶点的y坐标 |
x_max | int32 | 矩形区域右下顶点的x坐标 |
y_max | int32 | 矩形区域右下顶点的y坐标 |
注:pixel_bbox只有区域辅助聚焦时有效
测试方法
- 调用接口,调一次切换起立/坐下状态:
ros2 service call /cam/sysb_CAM/auto_focus cam_msgs/srv/AutoFocus "focus_mode: 2
pixel_bbox:
x_min: 500
y_min: 300
x_max: 1600
y_max: 900"Python 接口
auto_focus(self, focus_mode, pixel_bbox) -> bool: - 实现云台聚焦功能
focus_mode:
1: 表示全局辅助聚焦2: 表示区域辅助聚焦pixel_bbox: 聚焦区域设置(参考ros2接口说明)
使用案例
async with WebSocketPtzClient(host=args.host, port=args.port) as client:
await asyncio.sleep(1)
if args.mode == 1:
success = await client.auto_focus(focus_mode=1)
elif args.mode == 2:
if hasattr(args, 'bbox') and args.bbox:
try:
coords = [int(x.strip()) for x in args.bbox.split(',')]
bbox = {
"x_min": coords[0],
"y_min": coords[1],
"x_max": coords[2],
"y_max": coords[3]
}
success = await client.auto_focus(focus_mode=2, pixel_bbox=bbox)C#接口
bool AutoFocus(int focusMode = 1, PixelBoundingBox? pixelBbox = null, int timeoutMs = 8000)使用案例
// 半自动对焦
bool success = _robotMutiMediaClient?.AutoFocus(1) ?? false;
// 区域对焦(使用默认中心区域)
bool success = _robotMutiMediaClient?.AutoFocus(2) ?? false;
// 区域对焦(自定义区域)
PixelBoundingBox customRegion = new PixelBoundingBox
{
x_min = 100, y_min = 100,
x_max = 300, y_max = 300
};
bool success = _robotMutiMediaClient?.AutoFocus(2, customRegion) ?? false;C++接口
autoFocus简介
/**
* @brief 启用自动聚焦
*
* @param focus_mode 聚焦模式 (1=自动聚焦)
* @return true 成功,false 失败
*/
bool autoFocus(int focus_mode = 1);使用案例
Lenovo::Daystar::SDK sdk("192.168.100.103:50051");
auto &sysb = sdk.getPTZ();
if (sysb.connect()) {
if (sysb.autoFocus(1)) {
std::cout << "自动聚焦启用成功" << std::endl;
} else {
std::cerr << "自动聚焦启用失败" << std::endl;
}
}切换对焦模式
ROS2 接口
该接口用于使调用云台移动到某个角度。
| Service 名称 | Service 类型 | 角色 |
|---|---|---|
/cam/PTZ_CAM/set_focus_mode | cam_msgs::srv::SetFocusMode | 客户端 |
消息结构
cam_msgs::srv::SetFocusMode::Request 包括以下字段:
| 参数名称 | 类型 | 描述 |
|---|---|---|
focus_mode | uint8 | 1: 半自动对焦 2: 手动对焦 |
测试方法
- 调用接口,调一次切换起立/坐下状态:
ros2 service call /cam/PTZ_CAM/set_focus_mode cam_msgs/srv/SetFocusMode "focus_mode: 2"Python 接口
set_focus_mode(self, focus_mode: int) -> bool: - 实现云台聚焦模式的设定
- `focus_mode`:
- `1`: 表示**半自动对焦**
- `2`: 表示**手动对焦**
- `pixel_bbox`: 聚焦区域设置使用案例
async with WebSocketPtzClient(host=args.host, port=args.port) as client:
await asyncio.sleep(1)
mode_names = {1: "半自动", 2: "手动"}
mode_name = mode_names.get(args.mode, f"未知({args.mode})")
print(f"设置聚焦模式为: {mode_name}")
success = await client.set_focus_mode(args.mode)C#接口
bool SetFocusMode(int focusMode, int timeoutMs = 8000)使用案例
// 设置为半自动对焦模式
bool success = _robotMutiMediaClient?.SetFocusMode(1) ?? false;
// 设置为手动对焦模式
bool success = _robotMutiMediaClient?.SetFocusMode(2) ?? false;C++接口
setFocusMode简介
/**
* @brief 设置聚焦模式
*
* @param focus_mode 聚焦模式
* @return true 成功,false 失败
*/
bool setFocusMode(int focus_mode);使用案例
Lenovo::Daystar::SDK sdk;
auto &sysb = sdk.getPTZ();
if (sysb.connect()) {
if (sysb.setFocusMode(2)) {
std::cout << "聚焦模式设置成功" << std::endl;
} else {
std::cerr << "聚焦模式设置失败" << std::endl;
}
}灯光控制
ROS2 接口
该接口用于使调用云台移动到某个角度。
| Service 名称 | Service 类型 | 角色 |
|---|---|---|
/cam/PTZ_CAM/light_cmd | cam_msgs::srv::SetBool | 客户端 |
消息结构
cam_msgs::srv::SetBool::Request 包括以下字段:
| 值 | 描述 |
|---|---|
1 | 表示开灯 |
0 | 表示关灯 |
测试方法
- 调用接口,调一次切换起立/坐下状态:
ros2 service call /cam/PTZ_CAM/light_cmd cam_msgs/srv/SetBool "focus_mode: 2"Python 接口
light_cmd(self, enable: bool): - 实现云台灯光设定
enable:
1: 表示开灯0: 表示关灯
使用案例
async with WebSocketPtzClient(host=args.host, port=args.port, client_name="light_control") as client:
await asyncio.sleep(1)
action_str = "开启" if args.enable else "关闭"
print(f"{action_str}云台灯光...")
success = await client.light_cmd(args.enable)C#接口
// enable: true=开灯,false=关灯
void SetPtzLight(bool enable)使用案例
// 开启PTZ灯光
robotMutiMediaClient.SetPtzLight(true);
// 关闭PTZ灯光
robotMutiMediaClient.SetPtzLight(false);C++接口
lightCmd简介
/**
* @brief 控制补光灯
*
* @param enable true 开启补光灯,false 关闭补光灯
* @return true 成功,false 失败
*/
bool lightCmd(bool enable);使用案例
Lenovo::Daystar::SDK sdk("192.168.100.103:50051");
auto &sysb = sdk.getSYSB();
if (sysb.connect()) {
// 开启补光灯
if (sysb.lightCmd(true)) {
std::cout << "补光灯已开启" << std::endl;
}
std::this_thread::sleep_for(std::chrono::seconds(5));
// 关闭补光灯
if (sysb.lightCmd(false)) {
std::cout << "补光灯已关闭" << std::endl;
}
}