Tuesday, August 2, 2011

3G USB dongle in Linux

I purchased this USB dongle for internet connection over 3G. I got one from singtel and one from M1. They are meant to work under Windows and MacOSX, but not under Linux (no surprise here ...).

First the dongle is detected as a storage device (this is where they stored the windows drivers). It's called a "flip-flop" USB gear, or mode switching, or multiple device. Once the windows driver is installed, it manage to switch the mode to modem type device. There is a tool under Linux that does it, called usb-modeswitch, available from the Ubuntu repository. Once installed, the dongle appeared as a modem in my network manager.
See http://www.draisberghof.de/usb_modeswitch/ for more info on the mode switching tool.

Second, I am not sure how to configure the network interface. The configuration window has many fields, but under windows none of them is filled in, except for Number (*99#) and APN (internet on the Singtel card, sunsurf on the M1).

As of now, I can't make it work. The M1 card works on a different computer running Ubuntu and Gnome though, apparently it wasn't too difficult. I am using KDE... So their must be a solution somewhere...

EDIT: installing package mobile-broadband-provider-info helps: it automatically fills in the connection info. Tested under Gnome.

One more trick: the Ethernet card does not provide internet access, but the 3G dongle does. So the network settings have to be configured so that eth0 is not use as a gateway when routing. This can be done (in Gnome) as follow:
System > Preferences > Network Connections
Wired tab, edit the settings for the Ethernet connection
IPV4 tab, click on Route
check "Use this connection only for resources on its network"
Disconnect and reconnect eth0

This should allow connecting to the internet via the 3G dongle. In a terminal, type route and check that the gateway's address corresponds to the one provided by the dongle.

Friday, July 29, 2011

disable touchpad while typing

On laptops, the touchpad sometimes gets in the way of typing. It is possible to configure the touchpad so that it is automatically disabled while typing.

I did this in KUbuntu 10.04

This is done using syndaemon (found in package xserver-xorg-input-synaptics). Create a script called syndaemon.sh with the following content:
syndaemon -i 1 -d
Then set the script as executable and place it in your startup scripts (System Settings > Startup)
May need to restart...

Thursday, July 28, 2011

printing on a canon printer from linux with job accounting

At work we have this Canon iRC2550i network printer. Job accounting (username and password) is used to protect against unauthorized used of the printer / photocopier. Unfortunately, it does not work out of the box under Linux. So here is how to do it. (Note: I had to try lots of things before I managed to make this work, so maybe there were so hidden steps...)

- Download and install the UFR II driver from Canon
Choose the UFR_II driver. This is an archive file, unpack it and go to the 32 bit debian folder.

Before installing the debs there is a small trick, as they depend on gs-esp and it has been removed from the repo starting from Maverick.

Make sure ghostscript-x is installed (sudo apt-get install ghostscript-x)
Generate a fake gs-esp package:

Install equivs (sudo apt-get install equivs)
echo "Package: fake-gs-esp" > fake-gs-esp.control
echo "Provides: gs-esp" >> fake-gs-esp.control
equivs-build fake-gs-esp.control
sudo dpkg -i fake-gs-esp_1.0_all.deb
Then install the UFR cups drivers:
sudo dpkg -i cndrvcups-common_2.20-1_i386.deb
sudo dpkg -i cndrvcups-ufr2-uk_2.20-1_i386.deb

- Add the printer on your system (Cups) using the UFR II driver: HP JetDirect

- Configure the job accounting:
sudo cnjatool -e [printer name] (to enable job accounting)
cnjatool -p [printer name] (to set the username and password)

Optionally, cngplp can be used to configure the printer (it's a GUI)

Thursday, June 2, 2011

Test a serial port

Use a loopback cable: connect pin 2 and 3. Data sent out come back on the receive line.

optionally configure it to disable echoing: stty -F /dev/ttyS0 -echo
Otherwise the characters are sent again and again in an infinite loop...

in a console read from the line: cat /dev/ttyS0
in another console write to the line: echo "test message" > /dev/ttyS0

check if it is printed in the first console...


This is to install a minimum ubuntu. It can be used to install to any folder, i.e. some local folder on which to chroot later, or a mounted drive.

First install the debootstrap package
sudo apt-get install debootstrap

Then start the job:
sudo debootstrap --arch i386 hardy /mnt http://sg.archive.ubuntu.com/ubuntu

This will install hardy on /mnt by downloading all required packages from the singapore archive.

Then chroot in the new created environment: sudo chroot /mnt
create a root passwd: passwd
write /etc/fstab, /etc/network/interfaces and /etc/hostname
mount proc and pts:
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devpts devpts /dev/pts
configure language: apt-get install language-pack-en
under Debian: apt-get install locales; dpkg-reconfigure locales
install a kernel and GRUB: apt-get install linux-image grub

write MBR and create GRUB images:
(from outside the chroot, i.e. from a normal console): sudo grub-install --root-directory=/mnt /dev/sdc
This will install the GRUB images in /mnt/boot/grub and write the MBR on disk sdc
Then from the chroot environment: update-grub
this will write a menu.lst (the GRUB config) for you

then install whatever you want using apt-get

Remove executable permission on all files except directories

find . -type f -print0 | xargs -0 chmod -x

find . : search the current directory recursively
-type f : select only regular files (-type d would select directories)
-print0 : (where 0 is a zero) print the list with each file separated by a null character rather than a space. This allow handling filenames with a space in it.

xargs : execute a cmd on each argument
-0 : (where 0 is a zero) instruct xargs that argument list is null charater separated rather than by a space. Corresponds to -print0 in find.
chmod -x : remove executable permission

password-less login with ssh

On the originating machine:
ssh-keygen -t rsaSave the key in the default file (~/.ssh/id_rsa) and do not use a passphrase. This will create a file ~/.ssh/id_rsa.pub.

Add the contents of this file to the file ~/.ssh/authorized_keys on the remote machine (i.e., the machine on which you want to log on). Whereas the id_rsa.pub file is world readable, the authorized_keys file should only be readable by you. Use chmod to set the permissions accordingly.

Create a zip from a m3u playlist

grep -v "#" test.m3u | zip -j test -@ -

"-v #" is used to discard lines starting with # (comments maybe...)
-@ is to get input from the file, here -, i.e. stdin, i.e. the output of grep
-j is to junk the path and store only the file

mplayer / mencoder / ffmpeg recipes

Concatenate AVI files
cat file1.avi file2.avi > big.avi
mencoder -ovc copy -oac copy -o out.avi -forceidx big.avi

Split video
From a start pos (4 mins 20 secs) to end:
mencoder -ss 00:04:20 -oac copy -ovc copy in.avi -o out.avi
From beginning to an end pos (11 mins 44 secs):
mencoder -endpos 00:11:44 -oac copy -ovc copy in.avi -o out.avi
From a start pos (4 mins 20 secs), extract 5 mins of video:
mencoder -ss 00:04:20 -endpos 00:05:00 -oac copy -ovc copy in.avi -o out.avi

Extract audio from video
mplayer -dumpaudio videoFile.avi -dumpfile audioFile.mp3
mplayer -ao pcm -vo null videoFile.avi
it dumps the audio to audiodump.wav

Best is to use ffmpeg:
ffmpeg -i <input media> -ss <bgn time> -t <duration> -acodec copy -vn <output file>
  • -i input media is the source media (i.e. an avi file)
  • -ss bgn time: Seek to given time position in seconds.  "hh:mm:ss[.xxx]" syntax is also supported.
  • -t duration: duration of the segment to extract
  • output file: the output file, e.g. a mp3 file (depending on the input's audio encoding)
To encode the audio stream use a different -acodec option and see extra options (bitrate, etc.)

grep, sed, awk ...

Search TEX files for \label commands and check for double ref:

cat *.tex | grep "label{" | sed 's/.*{\(.*\)}.*/\1/' | uniq -c | sort -n

extract the IP address from ifconfig

$ ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:13:72:BE:FF:63
inet addr: Bcast: Mask:
inet6 addr: fe80::213:72ff:febe:ff63/64 Scope:Link
RX packets:4801968 errors:0 dropped:0 overruns:0 frame:0
TX packets:1088918 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2559338610 (2.3 GiB) TX bytes:90195114 (86.0 MiB)

$ ifconfig eth0 | awk '/inet addr/ {FS=" "; gsub("addr:","",$2); print $2}'

Internet access from chroot

I always had internet connection from a chroot environment. However, when using wireless, it seems that it's requires one more step: resolv.conf must contains the address of a DNS server (the gateway usually).

echo nameserver > /etc/resolv.conf

Setting a custom terminal prompt

In .bashrc, add:

PROMPT_COMMAND='DIR=`pwd|sed -e "s!$HOME!~!"`; if [ ${#DIR} -gt 30 ]; then CurDir=${DIR:0:12}...${DIR:${#DIR}-15}; else CurDir=$DIR; fi'
PS1="[\$CurDir] \$ "

Backup a linux system

source: https://help.ubuntu.com/community/BackupYourSystem/TAR

Summary: the backup can be done from the system directly (i.e. no need to run from a live CD). We don't want to backup some directories: proc, sys and dev are virtual filesystems... lost+found is not useful. -p option in tar is to preserve permissions.

 sudo tar -cvpzf /backup.tar.gz -–exclude=/backup.tar.gz --exclude=/proc --exclude=/lost+found --exclude=/sys --exclude=/dev --exclude=/mnt --exclude=/media /  

For restoration: this must be done from another system, typically a live cd. We will restore to /mnt:

 sudo tar -xvpzf backup.tar.gz -C /mnt  

then recreate the missing directories:
 mkdir /proc /lost+found /sys /mnt /media  

and install grub:
 sudo grub-install --root-directory=/mnt /dev/sdc  

Purge packages

The purge package (or the --purge) option in apt-get deletes configuration files along with the package content.

To identify packages that were removed but not purge, use pdkg -l to list all packages, and grep ^rc to find the lines that start with rc.

Finally, the whole command is:

sudo apt-get purge `dpkg -l | grep ^rc | cut -d' ' -f3 | xargs echo`

undelete files from a VFAT partition

Use testdisk:
sudo testdisk /dev/sdb

- select the partition and type (Intel)
- select advanced operation, then select undelete
- find the files to undelete and press c (copy), choose where to copy
- done!

More details here:

Wednesday, June 1, 2011

Checking out TI's EZ430-Chronos watch. Besides being a watch, it offers a 3-axis accelerometer, a temperature sensor, a pressure sensor, and acts as a wireless hub (to integrate with other wearable sensors), etc. It can be programmed too.

Here are the full specs along with a list of applications

Here is the demo video

Tuesday, May 31, 2011

First exercise with ROS: a node to interface with Player

I am starting to learn ROS. I needed an exercise and I do not have any robot to play with, except Player/Stage. So I decided to write a ROS node for my Player/Stage robot. ROS already has a stack called stageros that allows to interface with Stage. Mine is different: it allows to interface with Player. Hence it can also be used to interface with Stage (via Player), but with any other Player-enabled robot as well. Anyway, it's not very useful, but it's a good experimentation platform and exercise.

- Linux (I use Debian Wheezy)
- ROS (see ROS tutorials on how to install and learn the basics)
- Player and Stage (see respective tutorials as well, mine are install from source)
- A Player configuration file and world to start a robot in Stage

I assume familiarity with ROS and Player/Stage

The final aim is to be able to use the navigation stack with the Player robot. So I followed the guidelines and how to setup a robot for the navigation stack:

This means that we will need to publish laser data on the base_scan topic, odometry data on the odom topic, publish transform configuration too, and accept velocity commands on the cmd_vel topic.

I wrote 2 versions. One version has everything in one node, the other version is made of 3 smaller nodes (one per task aforementioned). We will first check the one node version.

The code is object oriented. I found the solution better than having global variables, because it allowed better control of initialization order: some stuffs can only be created after ros::init has been called.

First of all, let's create a package.

I have created a directory where I can experiment, i.e. ~/ros_playground. I added this directory to the ROS_PACKAGE_PATH environment variable: in ~/.bashrc, after the source xxx/ros/setup.sh line added when installing ROS (see ROS tutorial), I added the following line:

Then from the ros_playground directory:

roscreate-pkg playerros_1node roscpp tf nav_msgs sensor_msgs geometry_msgs

is the name of my package. The roscreate-pkg creates a directory ~/ros_playground/playerros_1node that contains several files, including the CMakeList.txt and manifest.xml

, tf, nav_msgs, sensor_msgs and geometry_msgs are the dependencies we will need. roscpp is needed to write a C++ ROS client, tf is needed to send transform configurations, nav_msgs for the odometry messages, sensor_msgs for the laser messages, and geometry_msgs for the velocity command messages.

Code for the one node version
Create playerros.cpp in the src directory in the playerror_1node directory just created.

First the includes:

Then the class definition:

The constructor creates all the Player objects, connects to Player, sets the callback functions (when new laser or odometry data is available), sets the cmd_vel callback function when a cmd_vel message is received from another ROS node, and starts the Player thread. We will look at all of this in detail, but first the main function:

Up to here, I think everything should be quite obvious. Let's now take a look at the contructor:

Now the odometry callback function:

One note here on frames. This code defines a few frames. One is called base_link, which is the root frame of the robot, i.e. the base. The odom frame is a fixed frame; it's origin is defined by the starting position of the robot. There is also the base_link frame, which is the frame attached to the laser.

Full code: http://pastebin.com/psZyY40E

Building the code
Edit CMakeList.txt:

To build:
rosmake playerros_1node
This will compile all the dependencies and the code we just created.
In case there are errors and you just want to recompile player_node.cpp, simply type make

rosrun playerros_1node playerros_node
(Player must be running first)

The program can be tested by sending commands to the robot. This can be done using rostopic:

rostopic pub cmd_vel geometry_msgs/Twist '[0.2,0,0]' '[0,0,0]' -1

This will set the velocity to 0.2m/s

Or you can use the following program to control the robot from the keyboard.

Add the following line to CMakeList.txt to compile:
rosbuild_add_executable(teleop src/teleop.cpp)