2.Pre-requisite
The followings are required before developing software using Uli SDK.
2.1 Development Host
An x86_64 computer running Ubuntu 18.04 is needed as the development host of Uli SDK applications.
Here are the recommended hardware specifications of the development host:
CPU: Intel Core i7-1165G7 or newer
Memory: 16G
Disk: 512G
2.2 Ubuntu 18.04
The code development is hosted on Ubuntu 18.04 x86_64 computer. The development host computer produces libraries and executables for both x86_64 and NVIDIA Jetson ARM computers.
It is preferable to prepare the Ubuntu 18.04 x86_64 development host computer with no python and other build tools installed. All required packages for development will be installed from the ISAAC SDK setup steps.
The development host computer should have VS Code installed. It can also set up as VS Code service if cloud PC is used, for example AWS EC2 instance.
2.3 Isaac SDK
The Isaac SDK is required as Uli SDK’s build tools extends Isaac SDK build framework. Obtain compatible Isaac SDK from Nvidia Developer Site. The table below shows the compatible Isaac SDK version:
Uli SDK | Isaac SDK |
---|---|
2022.01 | 2021.1 |
Once obtained Isaac SDK, install it by untar to your home directory ~/nvidia/isaac_sdk. After untar, you should see these two sub-directories: ~/nvidia/isaac_sdk/engine and ~/nvidia/isaac_sdk/sdk.
You need to install dependencies of the Isaac SDK for the development host. Run the install_dependencies.sh script in ~/nvidia/isaac_sdk/engine/engine/build/scripts:
% cd ~/nvidia/isaac_sdk/engine/engine/build/scripts
% ./install_dependencies.sh
The Isaac SDK install_dependencies.sh should install the correct versions of the dependent packages, include Google bazel build tool.
If you are planning to build and run applications on Nvidia Jetson devices, you also need to prepare the Nvidia Jetson devices. First, obtain the IP addresses of your Jetson devices. Connect a monitor to your Jetson device, open a terminal window, and type to get the IP address of the Jetson device:
% ip addr show
You also need to have valid user name on the Nvidia device.
Run the following from the development host. It will install required packages to the Jetson device:
% cd ~/nvidia/isaac_sdk/engine/engine/build/scripts
% ./install_dependencies_jetson.sh -h ip-addr-jetson-device -u user-name-jetson-device
2.4 Uli SDK
Obtain Uli SDK from www.ulisdk.com. Untar Uli SDK to ovt directory in your home directory: ~/ovt/. After untar, you should see the two sub-directories: third_party_archive and uli_sdk.
First, you need to expand third_party_archive to install the boost libraries to the correct location:
% cd ~/ovt/third_party_archive
% ./install-boost.sh
Second, you need configure the bazel WORKSPACE file of the Isaac SDK for accessing Uli SDK while building codelets that integrate the Uli SDK.
Edit ~/nvidia/isaac_sdk/sdk/WORKSPACE file as described below to configure Isaac SDK to access Uli SDK:
1.Modify this line to also load bazel function, isaac_new_local_repository:
load(“@com_nvidia_isaac_engine//bzl:deps.bzl”, “isaac_http_archive”, “isaac_new_local_repository”)
2.add the lines below after sensor_certification_workspace(), as following:
sensor_certification_workspace()
####################################################################################################
# Load uli_sdk
local_repository(
name = “com_ovt_uli_sdk”,
path = “../../../ovt/uli_sdk”,
)
isaac_new_local_repository(
name = “com_ovt_boost_x86_64”,
build_file = “@com_ovt_uli_sdk//third_party:boost.BUILD”,
path = “../../../ovt/third_party_archive/dist/boost_x86_64”,
licenses = [“@com_ovt_boost_x86_64//:LICENSE”],
)
isaac_new_local_repository(
name = “com_ovt_boost_jetpack45”,
build_file = “@com_ovt_uli_sdk//third_party:boost.BUILD”,
path = “../../../ovt/third_party_archive/dist/boost_jetpack45”,
licenses = [“@com_ovt_boost_jetpack45//:LICENSE”],
)
####################################################################################################
1.1 ISAAC Addons
Also obtain Isaac Addon from www.ulisdk.com. Isaac Addon is the Isaac codelets that integrate Uli SDK. The Isaac Addon needs to be copied to ~/nvidia/isaac_sdk/sdk and untar after copy:
% cd ~/nvidia/isaac_sdk/sdk
% cp isaac_addon.2022.01.tar.gz .
% tar xzf isaac_addon.2022.01.tar.gz
1.2 Validate build
Here are the commands to build the core services of the Uli SDK:
% cd ~/ovt/uli_sdk
% bazel build services/core
Use the following commands to build Isaac SDK apps/uli_kaya:
% cd ~/nvidia/isaac_sdk/sdk
% bazel build apps/uli_kaya:mobility
1.3 Additional Packages
Additional packages need to be installed to the development host:
1.VS Code
We recommend that VS Code is used as code editor. Here are the instructions to install:
% sudo apt update
% wget -q https://packages.microsoft.com/keys/microsoft.asc -O- | sudo apt-key add –
% sudo add-apt-repository “deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main”
% sudo apt update
% sudo apt install code
To configure VS Code, edit ~/.config/Code/user/settings.json as following:
{
“window.zoomLevel”: 1,
“editor.fontSize”: 16,
“editor.tabSize”: 2,
“workbench.colorTheme”: “Visual Studio Dark”
}
Run /usr/bin/code and add C++ and Python Extensions.
2.OpenJDK
Java is needed for code generator. Download OpenJDK:
% sudo apt update
% sudo apt install default-jdk
To check version:
% java –version
3.PyQt5
PyQt5 is for creating GUI applications. To install, follow the instructions below:
% pip3 install –user pyqt5
% sudo apt-get install python3-pyqt5
% sudo apt-get install pyqt5-dev-tools
% sudo apt-get install qttools5-dev-tools — this installs pyrcc5 to ~/.local/bin
Refer to https://gist.github.com/ujjwal96/1dcd57542bdaf3c9d1b0dd526ccd44ff
for details.
The pyrcc5 is to compile qt resource files, *.qrc. You need to set it up so that the bazel function, uli_py_binary, knows how to launch pyrcc5 when building PyQt5 application.
Do the followings:
Find the location where pyrcc5 is installed, usually it is installed in your home directory .local/bin.
Edit uli_sdk/build/repositories.bzl, modify the path of the following so that it points to the directory where pyrcc5 was installed:
native.new_local_repository(
name = “com_ovt_pyqt_tools”,
build_file = clean_dep(“//third_party:pyqt_tools.BUILD”),
path = “/home/ovt/.local/bin”, or path=”usr/bin”,
)
You also need to install PyQtWebEngine. It is in a separate package. Use pip3 to install it:
% pip3 install –user PyQtWebEngine
In main python module, you also need to do two things:
1)set the environment variable QTWEB_ENGINE_CHROMIUM_FLAGS to “–ignore-gpu-blacklist” to prevent WebGL throwing errors.
2)Set the core application attribute to ShareOpenGLContexts.
4.Approximate Engineering – Input (Gamepad)
This package is needed for using gamepad in your PyQt5 applications. To install, follow the instructions below:
% pip3 install approxeng.input
For details, refer to https://approxeng.github.io/approxeng.input/
5.Nintendo Switch Joycon Controller
Before going further, make sure you already have git, build-essential and the latest cmake installed. If not, do the following:
% sudo apt-get install -y –no-install-recommends git git-lfs git-review build-essential g++
To install the latest cmake, do the following:
% wget -O – https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add –
% sudo apt-add-repository ‘deb https://apt.kitware.com/ubuntu/ bionic main’
% sudo apt-get update
% sudo apt install cmake-curses-gui
You also need to install dkms and libevdev as Ubuntu 18.04 distribution does not include them. Follow the steps below to install:
% sudo apt-get install -y –no-install-recommends dkms libevdev-dev
To use Joycon controller in Ubuntu 18.04, two things are needed:
1)Install Nintendo joycon hid driver, do the following:
% sudo su
# cd /usr/src
# git clone https://github.com/nicman23/dkms-hid-nintendo
# mv dkms-hid-nintendo nintendo-3.2
# cd Nintendo-3.2
# dkms add .
# dkms build nintendo -v 3.2
# dkms install nintendo -v 3.2
The dmks build step above may ask you to set up EFI password, if your computer does EFI boot.
To check installed dkms module, do
% sudo dkms status
2)Install joycond – a system service that create a virtual device for combined left and right joycon. Do the following:
% git clone https://github.com/DanielOgorchock/joycond
% cd joycond
% cmake .
% sudo make install
% sudo systemctl enable –now joycond
The following files are installed:
/usr/bin/joycond
/lib/udev/rules.d/89-joycond.rules
/lib/udev/rules.d/72-joycond.rules
/etc/systemd/system/joycond.service
/etc/modules-load.d/joycond.conf
You can use the combined joycon with Approxeng.input. Patch the following files in the Approxeng.input site package:
1)Add the following to switch.py
__all__ = [‘SwitchJoyConCombined’, ‘SwitchJoyConLeft’, ‘SwitchJoyConRight’]
class SwitchJoyConCombined(Controller):
“””
Nintendo Switch Joycon paired.
“””
def __init__(self, dead_zone=0.05, hot_zone=0.05, **kwargs):
“””
Create a new Nintendo Switch Joycon controller instance
Combined controller only
:param float dead_zone:
Used to set the dead zone for each :class:`approxeng.input.CentredAxis` and
:class:`approxeng.input.TriggerAxis` in the controller.
:param float hot_zone:
Used to set the hot zone for each :class:`approxeng.input.CentredAxis` and
:class:`approxeng.input.TriggerAxis` in the controller.
“””
super(SwitchJoyConCombined, self).__init__(
controls=[
Button(“A”, 305, sname=”a”),
Button(“B”, 304, sname=”b”),
Button(“X”, 307, sname=”x”),
Button(“Y”, 308, sname=”y”),
Button(“Right”, 547, sname=”circle”),
Button(“Up”, 544, sname=”triangle”),
Button(“Left”, 546, sname=”square”),
Button(“Down”, 545, sname=”cross”),
Button(“Trigger Left”, 310, sname=”tl”),
Button(“Trigger Right”, 311, sname=”tr”),
Button(“Trigger Left2″, 312, sname=”zl”),
Button(“Trigger Right2″, 313, sname=”zr”),
Button(“Left Stick”, 317, sname=”ls”),
Button(“Right Stick”, 318, sname=”rs”),
Button(“Home”, 316, sname=”home”),
Button(“Option”, 309, sname=”select”),
Button(“Minus”, 314, sname=”l1″),
Button(“Plus”, 315, sname=”r1″),
CentredAxis(“Left Horizontal”, -32767, 32767, 0, sname=”lx”),
CentredAxis(“Left Vertical”, -32767, 32767, 1, sname=”ly”),
CentredAxis(“Right Horizontal”, -32767, 32767, 3, sname=’rx’),
CentredAxis(“Right Vertical”, -32767, 32767, 4, sname=’ry’)
],
dead_zone=dead_zone,
hot_zone=hot_zone,
**kwargs)
@staticmethod
def registration_ids():
“””
:return: list of (vendor_id, product_id) for this controller
“””
return [(0x57e, 0x2008)]
def __repr__(self):
return ‘Nintendo Switch Combined Joy-Cons’
2)Add SiwtchJoyConCombined to the CUSTOM_CLASSES in the controller.py
# This is used to specify classes to load, as we no longer (as of 2.6.0) do a subclass scan
# Some of these will be replaced in due course with the new profiles, others require more
# controls or are special cases in some way and will remain as custom classes
CUSTOM_CLASSES = [DualShock3, DualShock4, PiHut, SF30Pro, SwitchJoyConCombined, SwitchJoyConLeft, SwitchJoyConRight, WiiMote, SpaceMousePro,
SteamController]