视窗(Sight)
机器人技术的应用可能会变得非常复杂,因此有必要检查算法和组件的内部工作原理。Isaac SDK的两个最重要的可视化工具是“ sight”和“ websight”。“sight”是一类用于创建可变图或可视化2D或3D渲染中的数据的API。“ websight”是基于Web的前端,可用于查看通过Sight API提供的数据。应用程序通过运行WebsightServer实例与Websight通信。WebsightServer实例允许应用程序显示图表,2D和3D绘图,当前应用程序状态(活动节点和连接)以及更新配置。
首先,运行具有可视化设置的示例应用程序之一,例如apps/tutorials/opencv_edge_detection或apps/samples/stereo_dummy。然后只需打开Web浏览器并导航到http://localhost:3000。您将看到几个窗口,这些窗口向您显示正在运行程序的可视化数据。
视窗-前端(Sight-Front End)
浏览器打开,Sight的默认链接http://127.0.0.1:3000/,您会发现与下面相似的页面。这是“Sight”的主窗口。

UI组织
UI分为通道(Channel)菜单,窗口(Windows)菜单,配置(Configuration)菜单和窗口容器(Window Container)。
通道(Channel)菜单(左下)
通道(Channel)菜单列出了应用程序可发布到的所有通道。通道首先按应用程序(Application)分类,其次按节点(Node)分类,再次按组件(Component)分类,最后使用"."分隔通道名称。只有一个子节点的内部节点将与其子节点合并以减小树的大小。
可以通过显示当前状态的相邻箭头轻松识别内部节点,而不管其子节点是否可见。
从通道菜单禁用通道后,服务器不会发送此通道数据。这样可以节省应用程序的带宽和计算负载,但这样信息记录不被保留以备后用。
您可以一次启用或禁用树的所有通道。

Windows菜单(左上方)
Windows菜单包含所有当前可用窗口的列表,分为四个类别:
- 2D绘图:一个窗口,显示2D操作的渲染,例如绘制的图像,绘制的线,圆等。它们是可自定义的,可以使用复选框隐藏或使用红叉删除。您可以随时使用菜单底部的按钮来创建新的2D工程图。有关详细信息,请参见2D渲染。
- 图表:显示图表的窗口列表。计划将来版本支持自定义绘图。
- 其他:所有其他窗口的列表,例如当前正在运行的应用程序,记录器等的图形。
- 3D渲染:在此版本中,仅WebGL可用,但计划在将来的版本中使用其他3D渲染窗口。
使用复选框可以隐藏每个窗口。单击窗口名称可将焦点集中到该窗口。

配置(Configuration)菜单(右侧面板)

配置菜单包含当前正在运行的节点。展开每个节点可以显示组件以及每个组件的参数列表。
可以更改这些参数并更新机器人。请注意,如果机器人未主动监视更改的区域,则某些参数更改不会立即显现。例如,仅在程序启动时读取频率,而不在继续执行期间读取频率。
窗户容器(Window Container)
窗口容器包含当前可见并在窗口菜单中列出的所有窗口。可以拖动Windows以自定义视图,然后单击左上方的图标将其隐藏。使用窗口菜单显示以前隐藏的窗口。

窗口类型列表
Sight具有以下窗口类型,对应描述如下:
- 2D工程图: 2D工程图窗口显示机器人的可自定义2D视图。它们可用于显示摄像机图像和带有扫描光束,机器人位置,检测到的障碍物等信息的叠加图。
- 3D绘图: 3D绘图窗口与2D绘图窗口类似,不同之处在于它们以3D方式渲染。
- 图表:图窗口显示一些信息的图表,对系统监视很有用。
- 图形:图形窗口显示当前应用程序的图形和各个节点的执行状态。
- 录制:可以启用和禁用录制。
- 重播:可以控制重播。
快捷键
可以使用以下键盘快捷键:
- 回车:按Enter键可重新组织窗口,使它们不重叠。
- 箭头:使用箭头键可在3D视图中移动相机。
- 右键单击:渲染视图右击以显示可用菜单。
- 鼠标中键:指向左侧菜单上的通道名称时,单击鼠标的中键可将全名复制到剪贴板。
渲染(Rendering)
提供2D和3D渲染。两种视图都可自定义:您可以使用Windows菜单上的两个按钮来创建新视图。创建视图后,选择要渲染的通道和顺序。两种视图均可用于渲染2D或3D数据。
右键单击视图以访问菜单:
- 一次启用/禁用所有通道
- 拍摄视图的屏幕截图
- 开始和停止录制
- 访问设置以添加/删除通道并更改渲染的大小
- 显示或隐藏鼠标指针处对象的颜色和像素信息(仅2D视图)
视图下方有一个通道列表。单击给定通道左侧的图标可访问特定于通道的菜单。使用复选框可以从视图中启用或禁用通道。
显示为红色的通道未启用,也未更新。
2D和3D视图在渲染中均使用固定的0.2s延迟,以便同步要渲染的数据。如果消息的延迟时间大于此延迟,或者某些消息被丢弃(来自小码的节流(例如ColorCameraViewer)或来自网络本身),这也可能导致渲染通道不同步。
2D和3D视图都可以包含交互式姿态标记,用于表示姿态树的可编辑姿态。有关标记配置的信息,请参见“ 交互式标记配置 ”。

交互式姿势标记允许您使用2D或3D渲染挂件编辑姿态。

下面显示了三个2D交互式姿势标记。选择突出显示的一个进行旋转。

三个3D交互式姿势标记。高亮显示的一个被选中。各个段可以通过颜色区分。
设定选单(Settings Menu)
设置菜单包含:
- 窗口名称。
- 渲染的当前尺寸。(这些可以更改,但可能会被通道覆盖)。
- 包含所有可用频道列表的下拉菜单。
- 当前正在渲染的所有通道的列表。左侧的箭头可让您重新排列频道,使用右侧的图标删除频道。另外,您也可以通过右键单击通道名称直接从频道菜单添加新通道。您也可以使用通道菜单直接从一个或一组通道创建新的渲染器。
2D渲染
2D对象按层和列出顺序渲染。每个通道都包含一个图层,并且可以使用图层菜单选择透明度(alpha通道),大小(用于点和线)和默认颜色(如果未指定)。
3D对象沿Z轴的正交投影渲染,并且将第一个通道用作参考帧。
如果在第一个通道中渲染图像,则窗口将自动调整大小以匹配图像的大小。
鼠标可用于放大和缩小生成的图像。
3D渲染
对于3D渲染的每一层,可以像2D渲染一样自定义颜色和大小,并可以设置默认Z以便在3D世界中渲染2D对象。
渲染是在世界坐标系中完成的,并且图像被解释为占用栅格,如果像素的值大于127,则该单元格被认为是空的。否则会显示墙。
可以使用鼠标或键盘控制视图:
- 变换:键盘箭头或鼠标右键
- 旋转:鼠标左键单击
- 缩放:鼠标滚轮
图表
将自动为绘制标量值的通道创建图表。通道会按完整的通道名称自动分组:来自同一节点的通道和最后一个“.”之前前缀相同的小码将在同一窗口中输出。例如:
- nodeA/codelet/var1和nodeA/codelet/var2 分组在一起
- nodeB/codelet/win1.var1和nodeB/codelet/win1.var2分组在一起
- nodeB/codelet/win2.var1和nodeB/codelet/win2.var1分组在一起,但是在前两个通道的不同窗口中。
该图将自动调整为显示的数据范围。可以通过在下面取消选择单个通道来隐藏单个通道,并且可以使用鼠标来增大或减小所显示数据的范围。最多保留5分钟的历史记录。
图形(Graph)

显示当前应用程序的图形。处于不同状态的节点用不同的颜色表示:
- 灰色表示节点尚未启动
- 金节表示节点正在开始
- 橙色表示节点的运行频率低于0.1Hz
- 绿色表示节点的运行频率超过0.1hz。速度越快,颜色越浅。
- 红色表示节点已停止。
记录挂件(Widget)

“ 记录挂件(Record Widget)”部分将详细讨论此挂件(Widget)。
重播挂件(Replay Widget)

在 “重播挂件”部分将详细讨论此挂件(Widget)。
虚拟手柄挂件(Virtual Gamepad Widget)

该挂件在 "使用视窗(Sight)的远程操纵杆(Remote Joystick)"]部分进行了详细讨论。
Websight(后端)
在小码(Codelet)内部渲染
使用Sight :: Show函数在小码内部渲染:
sight::show("plot_1", timestamp, val1);
sight::show("plot_2", val2);
sight::show("some_image", time, image);
sight::show("some_image", image);
sight::show("some_drawing", time, [&](sight::Sop& sop) {
...
});
sight::show("some_drawing", [&](sight::Sop& sop) {
...
});
第一个参数始终是通道的名称。Sight中的完整频道名称为appname / node_name / codelet_name / channel。时间戳记和时间参数是可选的。如果省略了时间戳和值,则使用当前时间。时间戳应以纳秒为单位,而时间应以秒为单位。
Sight :: show函数可以直接渲染图像(Image1ub,Image3ub和Image4ub)。使用Sight :: Sop对象呈现更复杂的操作,如以下各节所述。
视线:: SopStyle
每个渲染的元素都可以具有特定的样式,该样式由颜色,大小以及是否应填充对象或线框组成。使用Sight :: SopStyle构造函数之一创建新样式:
sight::SopStyle{color};
sight::SopStyle{color, filled};
sight::SopStyle{color, filled, size};
- 颜色必须是Pixel3ub或代表有效JavaScript颜色的字符串(或char *):
- 颜色名称直接:“红色”,“白色”,“蓝色”等
- 十六进制代码:“#ff0000”,“#fff”等
- Javascript函数:“ rgb(255,0,0)”,“ rgba(255,255,255,1.0)”等。注意:alpha通道在[0.0,1.0]范围内,而颜色在[0,255]范围内。
- fill是一个布尔值(默认为false),用于确定对象是填充还是线框。
- size是一个标量,默认值为1.0
看:: SopTransform
转换可以两种方式传递:帧名称或直接姿态。
首选方式是通过框架名称:
sight::SopTransform{"robot"};
如果传递框架名称,则SOP数据将以给定名称放置在坐标框架内。例如,如果您指定“机器人”,则通过视线显示的事物将放置在名称为“机器人”的坐标框中。具体的姿态值将从应用程序姿态树中完全自动检索。大多数时候,您的应用程序已经在使用许多坐标框架来存储各种角色的姿态。您可以直接使用这些坐标系来发布可视化数据。此方法提供了最大的灵活性,您应尽可能使用它。
或者,您也可以直接以Pose2或Pose3对象的形式给出姿态。这时,姿态值相对于一般世界坐标系生成。
sight::SopTransform{pose};
请注意,此坐标系框架没有名称,并且姿势树无法解析。姿态参数必须是Pose2或Pose3。
此外,您还可以传递另外两个参数:scale和pinhole。
sight::SopTransform{pose, size};
sight::SopTransform{pose, pinhole};
sight::SopTransform{pose, size, pinhole};
size参数是用于缩放变换的标量。对于图像,它对应于像素大小。针孔参数使瞄准具可以将图像用作增强相机图像的背景图像。例如,在已记录图像的顶部渲染线条和矩形。
视线:: SopImage
vision :: SopImage函数对图像进行编码以使其显示在视觉上。支持PNG和JPEG格式。
sight::SopImage::Jpg(image); // Fast but loss in quality)
sight::SopImage::Png(image); // No quality loss, but rather slow.
该图像必须是Image3ub或Image1ub类型。图像类型Image4ub仅受PNG格式支持。
视线:: Sop(显示操作)
视窗操作由要一系列可执行的操作组成。可以将其视为操作树,每个节点包含一个应用于每个子级的SopTransform,以及包含所有子级的默认样式(如果未指定样式)的SopStyle,其中。它们还包含要使用默认样式呈现的图元或其他Sop列表,因此也包含树结构。
支持的原语列表(对于所有原语,N = 2/3,K = double / float / int)是:
- geometry :: LineSegement <K,N>(Vector <K,N> a,Vector <K,N> b); (从a到b的线)
- geometry :: NSphere <K,N> {Vector <K,N> center,K radius}; (圆/球)
- geometry :: NCuboid <K,N> {Vector <K,N> corner1,Vector <K,N> corner2}; (一个矩形或盒子)
- geometry :: Polygon <K,N> {std :: vector <Vector <K,N >> {polygon}}; (多边形)
- Vector <K,N>()(单点)
- std :: vector <Vector <K,N >>(如果样式设置为填充,则为点或折线的列表)
- Image <K,N>图像(自动转换为JPEG格式的SopImage)
- SopImage(已序列化的sop图像)
- SopText {“文本”,Vector <K,N> pos}(给定位置的文本)
- SopAsset {asset_name}(配置中指定的相同对象)
要更改变换或样式,请覆盖“ transform”或“ style”对象:
show("channel", [&](sight::Sop& sop) {
sop.transform = sight::SopTransform{wolrd_T_robot}; // Set the transform where the robot is
sop.style = sight::SopStyle{"red"}; // Set the color to red
sop.add(geometry::Circled({0.0, 0.0), 1.0); // Draw a red circle at the position of the robot
sop.add([&](sight::Sop& sop) { // Recursive call
sop.style = sight::SopStyle("#0000ff");
for (const auto& pt : path) {
sop.add(Circled(pt, 0.2)); // Draw a small circle on the path of the robot
}
});
})
图表(Plot)
使用以下显示功能渲染图表:
show("channel", value);
show("channel", timestamp, value);
如果未指定时间戳,则使用当前时间。
要在同一图中将变量分组,请使用相同的前缀:win1.var1和win1.var2显示在同一窗口中,而win2.var3在其自己的窗口中。
Websight服务器
配置
可以从类似于以下内容的配置文件中配置服务器:
{
"websight": {
"WebsightServer": {
"webroot": "packages/sight/webroot",
"assetroot": "external/isaac_assets",
"port": 3000,
"bandwidth": 10000000,
"ui_config": {
"windows": {
"Renderer 2D": {
"renderer": "2d",
"dims": { "width": 256, "height": 256 },
"channels": [
{ "name": "appname/node/codelet/channel1", "active": true },
{ "name": "appname/node/codelet/channel2", "active": true },
{ "name": "appname/node/codelet/channel3", "active": true }
]
},
"Renderer 3D": {
"renderer": "3d",
"dims": { "width": 256, "height": 256 },
"channels": [
{ "name": "appname/node/codelet/channel1", "active": true },
]
}
},
"assets": {
"Asse name": {
"obj": "apps/assets/carter.obj",
"txt": "apps/assets/carter_albido.png",
"norm": "apps/assets/carter_normal.png"
}
}
}
}
}
}
- webroot:包含前端代码的文件夹的路径
- assetroot:资源文件夹的路径
- 端口:Web服务器正在侦听的端口
- 带宽:每个通道可以消耗的最大带宽。如果此值太高且网络已饱和,则消息将在服务器端累积,直到最终其中一些消息被丢弃为止;这也会在前端显示的内容和机器人实际执行的操作之间产生视觉滞后。我们建议设置此值以限制网络饱。
- ui_config.windows:将自动显示的渲染器小部件列表
- 渲染器:“ 2d”或“ 3d”
- 暗淡:渲染器的大小
- 频道:渲染器频道列表
- 名称:频道名称
- active:默认情况下通道是否处于活动状态(默认值为true)
- ui_config.assets:资源列表:
- obj:包含网格物体的obj文件
- txt:纹理文件
- 规范:包含3d网格的常规信息的文件
执行优化
服务器经过优化,仅计算要发送到前端的内容。当使用lambda函数调用提供了Sight :: Sop对象时,仅当至少一个客户端当前正在侦听该通道时,才执行该函数。因此,无论何时执行复杂的显示操作(例如对图像进行标准化,裁剪或调整大小),都不要犹豫会滥用lambda函数。
互动式标记
本章的前半部分介绍了如何在Websightserver中使用标记。下半部分说明如何配置应用程序以将标记公开给Websight用户。
交互式3D标记
该交互式排可以在多种方式进行编辑:
- 左键按住:小部件将随相机一起移动。
- 按住left-Alt键并单击鼠标左键:按下鼠标左键或鼠标右键时,小部件将旋转到位。旋转取决于小部件的哪个部分获得点击。在此模式下,也可以使用WASD和QE键移动小部件。
- 按住left-Alt键并单击鼠标中键:向上或向下移动鼠标,而按下鼠标中键时,该窗口小部件将沿轴平移。该轴将成为单击的线段的轴。
带有选定段的交互式3D标记。
交互式2D标记
该互动标记与投影坐标内绘制这些帧被表示为圆圈。(您必须在Sight中添加一个窗口以查看标记。有关更多信息,请参见Windows菜单(左上)。)可以通过在轴上单击鼠标左键并将其拖动到所需位置来进行翻译。也可以通过单击圆周并拖动来更改它们绕z轴的旋转。
旋转的交互式2D标记。在旋转过程中,黄色指导线从小部件中心到鼠标。
交互式标记配置
需要在Websight中使用交互式标记的应用程序还需要使用任何(或两个)渲染器。唯一需要的额外配置是添加 IntreactiveMarkersBridge组件。
一旦桥存在并配置。交互式标记将始终显示在应用程序的任何渲染器小部件中。
交互式标记桥
交互式标记桥组件需要很少的配置。这是一个三步配置过程。首先,创建一个具有网桥和消息分类帐的节点。将PoseInitializer组件用于应用程序所需的任何标记。最后,因为它是一座桥梁;它需要连接到Websight服务器。
以下是一个代码片段,其中包含使用两个标记的交互式标记桥的典型节点:
<pre style="box-sizing: border-box; font-family: Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace; font-size: 12px; white-space: pre; margin: 0px; padding: 12px; line-height: normal; display: block; overflow: auto; color: rgb(64, 64, 64);">“ name” : “ interactive_markers_bridge” ,
"name": "interactive_markers_bridge",
"components": [
{
"name": "message_ledger",
"type": "isaac::alice::MessageLedger"
},
{
"name": "InteractiveMarkersBridge",
"type": "isaac::alice::InteractiveMarkersBridge"
},
{
"name": "left_shoulder_initializer",
"type": "isaac::alice::PoseInitializer"
},
{
"name": "left_elbow_initializer",
"type": "isaac::alice::PoseInitializer"
}
]
}
请注意,在此示例中,姿势初始化器包含在同一节点中。这不是强制性的:将属性设置attach_interactive_marker为true 跨越标记的任何姿势初始化器(在任何节点中)。姿势也可以由应用程序的任何其他组件以标准方式查询和使用,例如PoseTree与此处定义的lhs和rhs名称一起使用。这是这种节点的配置。
"interactive_markers_bridge": {
"InteractiveMarkersBridge": {
"tick_period": "0.4"
},
"left_shoulder_initializer": {
"lhs_frame": "root",
"rhs_frame": "leftShoulder",
"pose": [1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0],
"attach_interactive_marker": true
},
"left_elbow_initializer": {
"lhs_frame": "leftShoulder",
"rhs_frame": "leftElbow",
"pose": [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"attach_interactive_marker": true
}
}
最后是连接节点和Websight服务器的两个方面。
{
"source": "websight/WebsightServer/interactive_markers",
"target": "interactive_markers_bridge/InteractiveMarkersBridge/request"
},
{
"source": "interactive_markers_bridge/InteractiveMarkersBridge/reply",
"target": "websight/WebsightServer/interactive_markers_reply"
}
补充说明
在初始化时,桥将创建所有可编辑姿势并将其插入中PoseTree。以后可以检索这些姿势并将其用作应用程序中的任何其他姿势:通过查询PoseTree。
应用程序负责确保在应用程序本身正在编辑姿势的同时,不会由视线用户编辑姿势。如果不是,则以最近的时间戳为准。
可编辑的姿势始终是可编辑的,因此在应用程序执行期间始终会在网络视觉中显示标记。
对于任何其他通道,可以调整标记的大小或修改其颜色。为此,您可以单击标记名称旁边的图标,然后会发现一个用于调整大小的滑块,还可以更新颜色或Alpha通道组件。
对于其中的交互式标记, 有一个最小的工作示例apps/samples/interactive_markers
交互式标记的另一个示例是,当机器人难以在地图上的正确位置进行定位时,通过重新播种粒子进行定位来手动定位机器人。
请按照以下步骤手动定位机器人:
- 请务必将根据您的应用程序配置。
"attach_interactive_marker": true``PoseInitializer - 在Isaac Sight上,右键单击“地图视图”,然后选择“设置”。
- 在“选择标记”下拉列表下,选择“ robot_init”,然后单击“添加标记”。单击更新。
- 单击并按住交互式标记,将标记拖动到地图上的所需位置。
- 要调整角度,请单击并按住交互式标记的圆周,然后将标记旋转到所需的角度。
- 对正确的位置和角度满意后,在“应用程序配置”>“ navigation.localization.scan_localization”>“ Isaac.navigation.PaticleFilterLocalization”下选择“ reseed_particles”,然后单击“提交”
- 机器人定位到新位置后,取消选中“ reseed_particles”,然后单击“提交”





