Wolfmans Howlings

A programmers Blog about Programming solutions and a few other issues

Porting xgps to Qtopia for the Freerunner

Posted by Jim Morris on Wed Aug 27 14:46:34 -0700 2008

Background

I was getting bored waiting for Trolltech to release the next version of Qtopia for the Freerunner, so I ported the xgps client from gpsd's distribution to Qtopia.

As you may know by now, Qtopia does not have X11 so none of the existing X11 based or GTK based GPS clients work. I was exploring GPSD because I wanted to to be able to get a one time position for my sunset calculator which requires your current latitude and longitude. Although GPSD is not well suited for that (thats a whole other blog entry), I did notice you can connect to it over the ethernet, so I was playing with cgps and xgps that you find in the GPSD tar file, running on my desktop, talking to gpsd running on my Freerunner.

So wanting to dust of my Qt skills (which were so ancient I barely even recognize Qt4) I decided to port xgps to Qt.

I first did a pretty straight forward port to my Desktop Qt4/X11.

I designed the form using designer, then plugged in the code taken as closely as I could from xgps. This was not 1:1 by any means as XLib and Qt are not similar ;) I ended up just taking the ideas and algorithms from the xgps program and recoding.

So that took a day or so, as I was relearning Qt as I went, I have to say the documentation for Qt is excellent, unlike another graphics library I could mention (I'm looking at you GTK).

I got the basics working, and as my GPS fix inside was not very good (works about 50/50), I found you could also point any gpsd based client at gpsd.rellim.com and always get good data from there, this is great for testing.

So I had qtgps (for want of a better name) running on my desktop, looking pretty much the same as xgps, with the satellite list the sky view and of course the basic Fix data.

qtgps on workstation

Now the trick to port it to FR, so I could run this on my FR.

The UI wasn't going to fit on the FR screen so I revamped the UI in Designer, by basically dragging all the views into a tabbed frame. So the satellite list, the sky view, the position information and the movement information all had their own tab, this fits pretty well on a tiny screen.

qtgps on workstation qtgps on workstation qtgps on workstation qtgps on workstation

Other than that I didn't have to do much. I had to create a new qtgps.pro file for Qtopia, as the qmake qt one is somewhat different. I had to use the skeleton main.cpp that all Qtopia apps seem to use, but the bulk of the code remains the same.

Sending signals from callbacks

I did have an interesting time trying to figure out how to emit a signal from the gps callback thread to the main window, not sure if I chose the right way to do it but it worked... I created a singleton QObject based class, and allowed it to be called statically, then that does the emit. This is used to signal the main display thread that new gps data has arrived. (Note this won't work if the singleton can be called concurrently from multiple threads, Google c++ singleton pattern to see how to do that).

// Singleton for sending signal from a callback
class ExtSig : public QObject
{
    Q_OBJECT
    public:
        static ExtSig *self();
        void send(struct gps_data_t* p, char* buf);

    signals:
        void sendit(struct gps_data_t* p, char* buf);

    private:
        ExtSig();
};

// Singleton defns for emiting a signal from a callback
ExtSig::ExtSig(){}
ExtSig *ExtSig::self()
{
    static ExtSig inst;
    return &inst;
}

void ExtSig::send(struct gps_data_t* p, char* buf)
{
    emit sendit(p, buf);
}

// in callbeck call...
// signal the GUI thread we have new gps data
    ExtSig::self()->send(p, buf);

Howto build your own applications

Ok so how can you write your own Qtopia applications? There are at least two ways, 1) use the VMPlayer based Toolchain that Trolltech provide, or 2) setup your Linux workstation to use the toolkit. 1) is easier, and just works on pretty much anything that runs VMPlayer and has a lot of memory. 2) is faster and used less memory. I chose 2) but I did play with 1).

I won't go into how to do 1) as it is pretty much straight forward, just download the iso, and install it (either from a loopback device or from a burned CD).

The second method is not so well documented (if at all) so here is what I did to make it work on a Ubuntu Hardy i686 32-bit workstation with KDE installed..

Download the toolchain and install it into /opt/toolchains, it seems it must be there otherwise it doesn't quite work.

Then download the latest qtopia snapshot and put that in a working directory and set QTOPIA_DEPOT_PATH to that directory.

Then create a build directory for the qtopia build and set the QPEDIR environment variable to that path.

In my case I have QTOPIA_DEPOT_PATH=/opt/QtopiaSDK/qtopia-opensource-src-4.3.2-snapshot-20080815 and QPEDIR=/opt/QtopiaSDK/build/qtopia-4.3.2

Now we need to build the qtopia snapshot, you can use the result to copy to /opt/Nokia/Qtopia on your FR, or not, but you need to do this to get the tools to build your own apps.

Now follow these steps to build Qtopia:-

> cd $QPEDIR
> $QTOPIA_DEPOT_PATH/configure -device ficgta01
> make
> make install

Go get some coffee or dinner :) this will take a while.....

NOTE You may need to set -prefix /opt/Nokia/Qtopia in the ./configure stage for newer versions, as Trolltech changed where Qtopia runs from.

Now you will have a full Qtopia build in $QPEDIR/image

You can use the following script to copy this to your FR, it is modified from Trolltechs update script. It will keep your settings. However you will have needed to have flashed to the 0808 version of Qtopia and kernel for this to work.

#!/bin/sh
QTOPIA_DIR=$QPEDIR/image
QTOPIA_IMAGE=qtopia.tar.gz
PHONEIP=your_fr_ip_address
# sudo ifconfig usb0 your_fr_ip_address up

tar -C $QTOPIA_DIR czvf $QTOPIA_IMAGE
cat $QTOPIA_IMAGE | ssh "root@$PHONEIP" '(set -x;rm -f /tmp/restart-qtopia;killall qpe; mkdir -p /opt/Nokia/Qtopia;rm -rf /opt/Nokia/Qtopia/*; cd /opt/Nokia/Qtopia;gunzip |tar xvf -;/etc/init.d/qpe start &)'

Whether you do that or just keep the Trolltech released image you are now ready to write your own apps. I recommend you study the Qt docs Qtopia is pretty much Qt4.3 at the moment.

As an example you can use the qtgps.tar.gz as an example app or use $QTOPIA_DEPOT_PATH/examples/application

I created a build/myapps directory, and then tar xvfz qtgps.tar.gz into that directory. Then...

> cd build/myapps/qtgps
> $QPEDIR/bin/qtopiamake
> make

This will create a qtgps excutable that you can copy to your FR and run.

A nice trick I found is to run a GUI app from the ssh into FR you can do this...

> ssh your_fr_ip
fr# . /opt/Nokia/Qtopia/qpe.env
fr# ./qtgps

The app will popup on the FR screen, you could also run it from the terminal on the FR or from the file manager on the FR.

To create a new application you can do this..

> cd build/myapps/mynewapplication
> ... edit some .cpp and .h files
> $QPEDIR/bin/qtopiamake -project
> ... edit mynewapplication.pro appropriately
> $QPEDIR/bin/qtopiamake
> make

The skeleton main.cpp should look like this...

#include "mynewapp.h"
#include <qtopiaapplication.h>

QTOPIA_ADD_APPLICATION(QTOPIA_TARGET,MyNewApp)
QTOPIA_MAIN

The rest of the files are up to you. I like to create the UI using designer...

> $QPEDIR/bin/designer mynewapp.ui

look in either example.cpp or qtgps.cpp and qtgps.h on how to initialize a designer based UI.

There are lots of example apps on the Trolltech docs site.

Running app on the workstation

If you want to run the app locally rather than on your FR, you can use $QPEDIR/bin/qvfb

You will need to build a native version of qtopia to do that, which can be done by repeating the above steps but in a new build directory do:-

> export QPEDIR=build/qtopia-native
> mkdir $QPEDIR
> cd $QPEDIR
> $QTOPIA_DEPOT_PATH/configure -device i686fb
> make
> make install

and then rebuild your app for the native machine...

> cd build/myapps/qtgps
> make clean
> $QPEDIR/bin/qtopiamake
> make

Then run the native version of your app, but you will need to do the following to make the size correct...

> export QWS_DISPLAY=QVFb:mmWidth43:mmHeight58:0
> $QPEDIR/bin/qvfb -width 480 -height 640 &
> sleep 2
> ./qtgps -qws gpsd.rellim.com

This will run qtgps on the local workstation in a simulation of the FR screen (without qtopia), using gps data from gpsd.rellim.com.

Packaging

UPDATED I figured out how to install.

This document explains how to install a package so it shows up in the applications list, here is how I actually did it.

I created a directory called feed in my work directory, and set the path to $HTTPDIR. Then I ran a simple web server (I used boa but any will do), that points to $HTTPDIR to serve files.

Then I built the qpk package...

> cd $WORKDIR/qtgps
> make packages
> $QPEDIR/bin/mkPackages $HTTPDIR

Then make sure the web server is running, on the FR goto the Software Packages App, add the following server to the server lists http://192.168.0.200:8000, this presumes you are connected via USB and you ran the webserver at port 8000. Then click download, and you should see qtgps in the list, select it for install, and it will get installed. From then on you can replace the qtgps binary it installs with any new builds. It will be under /home/root/packages/somelongrandomstring/bin/qtgps

If you are using the vmplayer version of the SDK, then you can simply do this...

> sdk -b
> sdk -p
> sdk -i

The package for this is available here, (Right click to download). (Remember to generate the packages.list file using mkPackages). Setup a local web server and install as explained above.

A simple ruby script like this could also be used as a web server:-

--------- webserver.rb ---------
#!/usr/local/bin/ruby
require 'webrick'
include WEBrick

s = HTTPServer.new(
  :Port            => 8000,
  :DocumentRoot    => Dir::pwd
)

trap("INT"){ s.shutdown }
s.start
--------------------------------

> ruby webserver.rb

Then point your feed to http://192.168.0.200:8000/feed if using USB networking and the .qpk file is in the feed directory.

Where to get the source

The source code to this project is now on github http://github.com/wolfmanjm/qtopiagps/tree/master

Installing required libraries for the toolchain

UPDATE I forgot to mention how I got the libgps stuff into the toolchain. I found a hack, first I built gpsd-dev using mokomakefile then I did this...

dpkg-deb -X build/tmp/deploy/glibc/ipk/armv4t/gpsd-dev_2.34-r9_armv4t.ipk  /opt/QtopiaSDK/opt/toolchains/arm920t-eabi/arm-angstrom-linux-gnueabi

This worked for this case and setup the .so links correctly. You could also copy the libgps.so from your FR.

Another user (Radek Barton) did it this way, but I haven't tested this...

1. Download lastest gpsd source code at http://download.berlios.de/gpsd/gpsd-2.37.tar.gz and unpack it somewhere.
2. Add line #include <linux/limits.h> to gpsd.h-head file.
3. Modify line 15 of gps.h file from <limits.h> to <linux/limits.h>
4. configure with command: PATH=/opt/toolchains/arm920t-eabi/bin:$PATH ./configure --host=arm-angstrom-linux-gnueabi
5. Then make, make install, etc.

For those that cannot do that, then download this tar file to /pathtodownload/...

and...

> cd /
> tar xzvf /pathtodownload/libgps.tar.gz

This presumes that your Qtopia toolchain is in /opt/toolchains

Also note that the following packages need to be installed on the FR libgps16, gps-utils and gpsd.

Posted in Openmoko  |  Tags openmoko,freerunner,gps  |  32 comments

Comments

  1. Abdel said on Thu Aug 28 00:48:14 -0700 2008
    This is very nice Jim. I look forward to test this when I finally receive my freerunner tomorrow or so.

    Believe me if you want but I had the very same idea about the dialog dispatching in tabs when I first saw the xgps screenshot ;-)
  2. Abdel said on Thu Aug 28 00:54:48 -0700 2008
    By the way, as I told you by mail, if you port you network code to Qt, you could use QSocketNotifier for notifying the GUI about a new gpsd message: http://doc.trolltech.com/4.3/qsocketnotifier.html
  3. Avinash said on Mon Sep 01 05:22:12 -0700 2008
    I tried to build the application on Vmware GTA01 but on running make I am getting /usr/local/bin/ld: cannot find -lgps. What can be the reason.
  4. wolfmanjm said on Mon Sep 01 09:40:00 -0700 2008
    See the update at the end of the article. You need to install the libgps libraries in the appropriate places. There are a couple of ways to do that.
  5. Avinash said on Tue Sep 02 05:15:38 -0700 2008
    Thanks Jim, Installed gpsd and built the app, Its working on the emulator. we can make the package for qtopia using sdk -p
  6. Daniel Hedblom said on Fri Sep 05 04:20:15 -0700 2008
    Hey, this looks really nice.

    Any chance someone could put up a package of this? QT really rocks but its gots no GPS yet. This app is exactly what i like to have.
  7. wolfmanjm said on Fri Sep 05 12:58:21 -0700 2008
    I'll checkin the qpk, and you can follow th instructions for installing locally. I do not want to run a Qtopia feed at this time and I don't know of any others other than Trolltechs.
  8. Dylan said on Wed Sep 10 16:22:43 -0700 2008
    Does this software have a metric option?
  9. wolfmanjm said on Wed Sep 10 16:49:10 -0700 2008
    Yes it does, but there is no UI yet for setting it. The code is the same as xgps, which has a way to set the units. It would be relatively easy to add an option for that.
  10. Dareus said on Thu Sep 11 02:22:22 -0700 2008
    Your script to copy the qtopia image to the FR would work with the 09-03-2008 snapshot of 4.3.3 (image flashed)? Qtopia is installed under /opt/Nokia/Qtopia...
  11. wolfmanjm said on Thu Sep 11 02:57:36 -0700 2008
    Thanks, I updated all references to /opt/Qtopia with /opt/Nokia/Qtopia
  12. Dareus said on Thu Sep 11 06:40:37 -0700 2008
    I followed your steps, I'm now facing a problem in make-ing qtgps.
    it says:
    /opt/toolchains/arm920t-eabi/lib/gcc/arm-angstrom-linux-gnueabi/4.1.2/../../../../arm-angstrom-linux-gnueabi/bin/ld: cannot find -lgps
    collect2: ld returned 1 exit status

    how could i solve the issue?

    another question: how can i run qtgps in the FR without being connected to a pc?
  13. Dareus said on Thu Sep 11 09:08:53 -0700 2008
    previous issue is solved (i just had to read carefully ...), the question is still there, because i get another issue. I copied the executable file in /home/root on the FR but running it through qterminal says:
    ./qtgps: error while loading shared libraries: libgps.so.16: cannot open shared object file: No such file or directory

    another thing are your commands to run a GUI app from the ssh into FR correct?

    because (e.g.) 192.168.0.200 is the pc IP
  14. wolfmanjm said on Thu Sep 11 11:10:19 -0700 2008
    You also need to install gpsd on the FR, I think the libgps.so is in that package if not look for other gpsd packages, and install them. Let me know which one works ;) You can also manually install it from the downloads linked in this blog.
    Good catch on the ssh ip I'll fix that.
  15. wolfmanjm said on Thu Sep 11 11:13:24 -0700 2008
    To run qtgps without ssh, you can install the package, or run it from the terminal or from the filemanager.
  16. michaelbotham@yahoo.co.uk said on Sun Sep 14 07:21:20 -0700 2008
    Hi,
    Can you tell me which repository gpsd is in?
    Thanks
  17. michael said on Sun Sep 14 08:34:25 -0700 2008
    I found I needed to add the user repositories (see http://wiki.openmoko.org/wiki/Users_Repositories), then I could install gpsd, now I have it all working- thanks
  18. Dareus said on Fri Sep 19 03:05:17 -0700 2008
    hi, i tried your script to move my qtopia image to the FR
    i noticed that the IP is still 192.168.0.200 for the FR (i think it should be 192.168.0.202) and i found a problem: running the script tar says that he won't create an empty archive and then i don't know if it could work (because no archive is created at all)
  19. Dareus said on Fri Sep 19 08:15:52 -0700 2008
    the only way i found to obtain an archive was to:
    cd $QTOPIA_DIR #and then
    tar -czvf $QTOPIA_IMAGE *

    another thing i found building qtopia 20080917, make says that with your options qtopia is intended to be installed under /opt/Qtopia when (using flash images on qtopia.net) it is under /opt/Nokia/Qtopia
    I don't know if the make message is outdated or sth and couldn't test, anyway (after some tests) the script should be edited again...
    Hope to be useful
  20. wolfmanjm said on Sun Sep 21 13:22:05 -0700 2008
    Thanks I fixed the IP, and I'll update the instructions, it depends on the version of qtopia as to where it goes.
  21. Martin said on Sun Dec 28 12:31:58 -0800 2008
    Could you maybe add "packages.list" to
    http://github.com/wolfmanjm/qtopiagps/tree/master/pkg?
    (Is there a way to install the application using
    shell commands and omitting a direct WWW access?)
  22. wolfmanjm said on Tue Dec 30 18:21:20 -0800 2008
    Yes I can add the packages.list file, if that helps.

    For some reason QT does not allow apps to be installed from any source other than http. Not sure why, but that is up to Qt to solve or not.
  23. Aditya said on Wed Dec 31 00:14:55 -0800 2008
    Hi, tried to port qtgps executable to my target processor.its is give error like this,SXE key has not been set. Has "make install" been run on ./qtgps.so then i tried to compile the project again and iam getting the same error please help me to solve this problem
  24. Martin said on Sun Jan 11 02:59:22 -0800 2009
    Looking at http://github.com/wolfmanjm/qtopiagps/tree/master/pkg/packages.list ,
    > "QtopiaVersion: 4.3.0-4.3.2"

    indicates that this executable is not suitable for QtExtended 4.4.
    The package manager shows "0 program(s) found" after connecting to this feed with a Neo Freerunner running
    http://other.lastnetwork.net/OpenMoko/qtextended-4.4.2-gta02-rootfs-release-working-with-SystemRingTones.jffs2 .
    (Comparing with
    http://qtextended.org/packages/feed/4.4.1/neo/packages.list ,
    there are also packages with "Architecture: arm" here, but it's "QtopiaVersion: 4.4.0-4.4.3".)

    Is there also a feed with a Neo Freerunner version for the actual QtExtended 4.4.2 somewhere?
    URL?

    This URL could be added to the [Openmoko Wiki](http://wiki.openmoko.org/wiki/Qtopia_/_Qt_Extended_on_FreeRunner#Software_packages_feeds)...
  25. wolfmanjm said on Tue Jan 13 23:08:32 -0800 2009
    I have not tested this on QTExtended, so I don't know if it will work. When I tried to run it once I got a blank screen, so I'm not sure if it needs to be recompiled with the qtextended toolchain.
  26. Nick said on Fri Feb 06 14:18:45 -0800 2009
    Hi,
    As I see your packages (and some on the net) are build only for 4.3x
    does that mean that the 4.4.2 on neo is a dead platform?!

    thx
  27. wolfman said on Fri Feb 06 14:37:23 -0800 2009
    Not at all. I think this will actually install on the latest version of QTE but I haven't tested it. However in the case of GPS, the new version of QTE has a library for GPS, and I really need to port this app to use that library rather than gpsd. But seeing as I am not using QTE at the moment that will be hard to do. Feel free to work on it though :)
    I am waiting for Trolltech to release a newer version as QTE 4.4.2 was less stable than the previous version IMHO.
  28. Peter said on Tue Aug 04 12:02:05 -0700 2009
    Hi Wolfman, Have you tested this code into the new Qt 4.5.2? Regards
  29. wolfman said on Tue Aug 04 12:27:34 -0700 2009
    No I could not get the original binary to work on the latest releases. However it should build and run if the correct libraries and toolchain are used to build it. But the reason I haven't done it is that this is really made obsolete by the new location libraries builtin to the new version. Someone needs to fork my git and update it using the location library.
  30. Peter said on Wed Aug 12 09:45:47 -0700 2009
    Hi wolfman, I have done some work on it and manage to use the gps libraries but I still a bit away to complete a application like yours. There is one thing, I have notice that to read the raw data you use QSocket which is no there anymore by the way, I have tried to use another library with QTcpSocket but its not working, I spoke with some guys of gpsd channel and they said there is not a way to the raw data from gpsd yet, Could you please tell me (if you remember) what did you do with QSocket? It may help to understand. Thanks
  31. wolfman said on Wed Aug 12 12:41:01 -0700 2009
    @Peter: I don't see any reference to qsocket in my code, all access to the GPS data is via the libgps library, you can get relatively raw data via libgps, but not totally raw. To do that you would need to talk directly to the GPS chip using ublox or other format.
  32. wolfman said on Mon Sep 14 17:18:25 -0700 2009
    I have updated the project at github to build and run on qtmoko, or qtextended 4.4.3

(leave email »)