Creating a new application outside Choregraphe using the qi Framework¶
Step one: choose your langage¶
You can do this using either C++ or Python.
C++¶
If you choose to do this in C++, please follow the C++ SDK - Installation Guide first.
Python¶
If you choose to do this in Python, please follow the Python SDK - Installation Guide.
Step two: write the service¶
C++¶
Create a new service
Your layout will look like this
worktree
|__ myapp
|__ qiproject.xml
|__ CMakeLists.txt
|__ main.cpp
|__ myservice.cpp
|__ myservice.hpp
For an example of service in C++, refer to C++ - How to write a qimessaging service. If you want to write just a client which does not expose an API, refer to C++ - How to write a qimessaging client.
<!-- in qiproject.xml -->
<project version="3">
<qibuild name="myapp">
<depends runtime="true" buildtime="true" names="libnaoqi" />
</qibuild>
</project>
Warning
If you do not specify a runtime dependency on libnaoqi, your application may not work when the system is upgraded to a later version of NAOqi OS.
# In CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(myapp)
find_package(qibuild)
include_directories(".")
qi_create_bin(myservice
main.cpp myservice.hpp myservice.cpp
DEPENDS QI)
Python¶
Create a new service
Your layout will look like this:
worktree
|__ myapp
|__ qiproject.xml
|__ myservice.py
|__ helper.py
|__ mylib
|__ __init__.py
|__ stuff.py
For an example of service in Python, refer to Python - How to write a qimessaging service.
<!-- in qiproject.xml -->
<project version="3">
<qipython name="myapp">
<!-- this is your executable that will go in bin/ -->
<script src="myservice.py" />
<!-- this is an helper that will go in lib/python2.7/site-packages/ -->
<module name="helper" />
<!-- this is a package that will go in lib/python2.7/site-packages/ too -->
<package name="mylib" />
</qipython>
</project>
# in myservice.py
import qi
import helper
import mylib
class MyService:
def echo(self, message):
return message
def do_something(self):
pass
def main():
app = qi.Application()
app.start()
session = app.session
myService = MyService()
session.registerService("MyService", myService)
app.run()
if __name__ == "__main__":
main()
Step three: C++ only - configure and build the project¶
At this stage you should have installed the cross-toolchain and configure qibuild to use it. If not, please go back to the C++ SDK - Installation Guide section.
Basically it boils down to:
qitoolchain create atom /path/to/ctc/toolchain.xml
Then configure and build the project with:
cd myapp
qibuild configure -c atom
qibuild make -c atom
Step four: generate a package for the Aldebaran store¶
Create the following files in order to generate a package:
<!-- in manifest.xml -->
<package uuid="myapp" version="0.1.0">
<services>
<!-- if written in Python -->
<service name="myservice" autorun="true" execStart="./python bin/myservice.py" />
<executableFiles>
<file path="python" />
</executableFiles>
<!-- if written in C++ -->
<service name="myservice" autorun="true" execStart="bin/myservice" />
<executableFiles>
<file path="bin/myservice" />
</executableFiles>
</services>
</package>
Set the autorun attribute to true if you want your service to be started when the robot starts.
<!-- in myapp.pml -->
<Package name="myapp" format_version="4">
<Manifest src="manifest.xml" />
<!-- optional resources : -->
<!--
<Resources>
<File src="path/to/some/data" />
</Resources>
-->
<!-- if written in Python -->
<qipython name="myservice" />
<!-- if written in C++ -->
<qibuild name="myservice" />
</Package>
At this point, you should add the project to your worktree with:
qisrc add .
Then you can generate the package using:
Python:
qipkg make-package myapp.pml
C++:
qipkg make-package myapp.pml -c atom
This will generate a file named myapp-0.1.0.pkg
in the current working directory.
Step five: deploy the package to the robot¶
Make sure you have installed the Python SDK, and run:
qipkg deploy-package myapp-0.1.0.pkg --url nao@nao.local
If everything works fine, you can then submit your package to the Aldebaran store.
Step six: start and stop your service¶
You can execute operations on the services registered with a manifest by using ServiceManager API.
To start a service:
qicli call ALServiceManager.startService myapp.myservice
To stop a running service:
qicli call ALServiceManager.stopService myapp.myservice
You can also call these methods from a behavior or another service.
Troubleshooting¶
If you get this warning when your service is supposed to start:
[W] 16967 core.processmanager.qt: myservice: service failed to start (Permission denied)
You may have not set your file as an executable file. So it does not have the rights to be launched. Make sure to use the executableFiles tag.
You can see the standard output and error streams of the process in
/var/log/naoqi/servicemanager