Monday, April 27, 2015

Building OpenCV's HTML documentation

OpenCV has become the de facto standard vision processing library, but the project remains surprisingly obscure in several areas, particularly in relation to building and installation tasks. For example, it took me a couple hours to discover how to build the project's HTML documentation (though to be fair, I was looking into it concurrently with other work).

For those also struggling with this, see this question in the OpenCV Q&A site. In short, it gives the following instructions:
  1. Install Sphinx;
  2. Run cmake on your OpenCV source base as explained in the installation instructions, perhaps adding the -D BUILD_DOCS=ON option for good measure;
  3. Run make html_docs to build the documentation in HTML format.
If everything goes well the HTML documentation will be built to the subfolder doc/_html/ inside the build output folder. If not, check if the output of the cmake call reported items Build Documentation and Sphinx both set to YES. You may also check the cmake script cmake/OpenCVDetectPython.cmake inside your OpenCV source base for potential problems.

Wednesday, April 8, 2015

Internet sharing for Intel Edison on Linux

Recently I got hold of an Intel Edison with accompanying Arduino Expansion Board. The awkward development setup process (which requires two separate USB cable connections to a host computer) didn't make for a stellar first impression, but the possibilities of a full x86-64 computer that fits in a matchbox are intriguing. Of course, the fact both Linux and ROS are more-or-less readily available for the platform made the whole proposition a lot more interesting.

After flashing Edison with ubilinux the first order of business was getting the thing connected to the Internet. Edison includes an on-board wi-fi card and can simulate an ethernet port through its USB connections to the host computer, but bureaucratic questions would make a direct connection to my lab's network difficult. So I set up my notebook (Edison's host computer) as a local gateway, enabling Internet sharing through the virtual usb0 interface.

The procedure documented below was developed on a Kubuntu 14.04 host and ubilinux Edison unit, but it should be adaptable to other Linux distributions. It is largely based on a previous post on wireless Internet sharing; in fact that may be a better option, if unlike me you have a wireless interface to spare.

First open a command prompt and start a root session with su, then follow the steps below:

Step 1: Install Dnsmasq

Dnsmasq is a tool for setting up small networks. Install it from the command line by typing:
apt-get install dnsmasq
As it is the dnsmasq service will be automatically started when the computer boots, but we need better control than that. So change the default settings to manual start:
update-rc.d -f dnsmasq remove

Step 2: Configuration Files

Create or update the following config file with the contents below:

/etc/dnsmasq.conf
# disables dnsmasq reading any other files like /etc/resolv.conf for nameservers
no-resolv
# Interface to bind to
interface=usb0
# Specify starting_range,end_range,lease_time
dhcp-range=usb0,192.168.100.100,192.168.100.199,12h
# dns addresses to send to the clients
server=8.8.8.8
server=8.8.4.4

Step 3: Interface Scripts

Add the scripts below to your system:

/usr/local/bin/usb0start.sh
#!/bin/sh

ETH=eth0
USB=usb0
IP=192.168.100.99
MASK=255.255.255.0

# Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

# Setup USB interface
ifconfig $USB up $IP netmask $MASK

# Start dnsmasq
/etc/init.d/dnsmasq start

# Enable NAT
iptables --flush
iptables --table nat --flush
iptables --delete-chain
iptables --table nat --delete-chain
iptables --table nat --append POSTROUTING --out-interface $ETH -j MASQUERADE
iptables --append FORWARD --in-interface $USB -j ACCEPT

/usr/local/bin/usb0stop.sh
#!/bin/bash

USB=usb0

# Stops DNS making service
/etc/init.d/dnsmasq stop

# Asked nice the first time...
killall dnsmasq

ifconfig $USB down
Make sure to create the scripts from the root account, so they'll have the right ownership. Also don't forget to give them running permission:
chmod +x /usr/local/bin/usb0start.sh
chmod +x /usr/local/bin/usb0stop.sh

Step 4: Edison Configuration

Connect Edison to the host computer and start a remote session. Change the following configuration file as below:

/etc/network/interfaces
# Disable auto connection, enable DHCP
iface usb0 inet dhcp
#auto usb0
#iface usb0 inet static
#    address 192.168.2.15
#    netmask 255.255.255.0

Usage

After performing the steps above, you should be able to start the local gateway by running the usb0start.sh script:
sudo /usr/local/bin/usb0start.sh

Then on the Edison environment, start the usb0 interface:
ifup usb0

After you're done with Edison, the gateway can be deactivated by running the usb0stop.sh script:
sudo /usr/local/bin/usb0stop.sh

Troubleshooting

If Edison cannot lease an IP from the host computer or see IP addresses beyond the gateway, you can enable logging on Dnsmasq by adding the following lines to the /etc/dnsmasq.conf file:
log-queries
log-dhcp

Then use tail -f /var/log/syslog to check for messages.

On Kubuntu the network manager tried to setup the usb0 interface using eth0's configuration every time it was turned on, messing the DHCP service. This was solved by explicitly binding the configuration to eth0 on the network manager's GUI.

Monday, April 6, 2015

ROS and my first pull request

I had been putting it off for a long time, but a couple weeks ago I finally decided to bite the bullet and port my research code to ROS. After a bit of a rough start reinstalling my OS from scratch – I had recently upgraded my notebook to Kubuntu 14.10, but the latest ROS distribution (Indigo) wouldn't install on anything past 14.04 – and coming to terms with the catkin build system, I quickly fell in love with its modular approach to software development.

One of the many little conveniences ROS offers are parameters, which among other things greatly simplify management of program arguments. The ROS C++ client library provides several ways to retrieve parameter values, and optionally provide defaults for when they are not defined. One of those ways is the ros::param::param template function, which can be used to write initialization code like this:
std::string path;
std::string format;
double fps;

param("~path", path, "video.mpg");
param("~format", format, "MPEG");
param("~fps", fps, 30.0);

VideoRecorder recorder(path, format, fps);
However I disliked having to declare variables to get to the parameter values, just to pass them straight to a constructor or function call and then disregard them. So I wrote an alternative version of the template function that retrieved the value as a return instead of an output argument:
template<class T> T param(const std::string& name, const T& fallback)
{
  T value;
  param(name, value, fallback);
  return value;
}
So I could rewrite the code above as:
VideoRecorder recorder(param("~path", "video.mpg"),
                       param("~format", "MPEG"),
                       param("~fps", 30.0));
At first I had separate copies of this function on each of my ROS projects, but soon I realized it would be great if I could contribute it to the official roscpp code base. After a bit of stumbling about looking for the right place to proposed it, I ended up submitting the change myself as a pull request. Overall the process went very smoothly, though there are some tips I wish I had been given before I started:
  • You'll want to compile and run tests on the code you intend to submit (believe me, even a change as small as the one above was not without a couple coding errors), so remember to create a catkin workspace into which to clone the forked repository;
  • You may think that your change is trivial and will be done in a single commit, but it's likely your submission will go through several revisions before it's accepted. To keep things organized, create a new branch before starting your work;
  • Beware of line-ending whitespace – there are a few lurking around in source files, and if your editor automatically removes them you'll end with an unnecessarily large (and likely unacceptable) diff;
  • That said if you do mess up, don't bother trying to amend the initial commit – simply submit additional commits with the required changes or reversals (this is where having a separate branch may come in handy).
Open communities are not always noted for being welcoming to beginners, even less so in technical circles. But I have nothing but praise for the ros_comm community and the fairly friendly and constructive exchange they had with me. Keep up the good work people!

Saturday, July 13, 2013

Setup a Wireless Access Point with Linux Mint 15 (Olivia)

In these days of tablets, smartphones and other "connected" devices, the ability to share a fast wired Internet connection via wi-fi can be very useful, specially at home or small offices. Wireless routers aren't very expensive and are simple enough to install – yet I have always thought they're kind of wasteful, considering most computers today ship with wi-fi interfaces, or can be fitted with USB cards that sell for pennies.

With Linux, wi-fi interfaces can be configured to operate in master mode, so they can accept client connections just like a dedicated router would. This is a huge improvement over "ad-hoc" wi-fi network sharing, because:
  1. Many mobile devices do not connect to "ad-hoc" access points;
  2. The WEP authentication standard used on those connections is known to be flawed, in contrast to the newer WPA standard used in "master mode" connections.
Today I updated my desktop to the latest Linux Mint 15 (Olivia), and as I went about configuring a Wireless Access Point (WAP) on it for my other devices, I took the time to document my changes to the system, so I can more easily reproduce them in future upgrades – and hopefully, also help others to setup a WAP with Mint.

The procedure I came up with was largely inspired by this blog post. It assumes the existence of a wired interface eth0 (which provides access to the Internet) and a mac80211-compatible wireless interface wlan0 (which will be configured to accept client connections in "master mode").

First open a command prompt and start a root session with su, then follow the steps below:

Step 1: Install Applications

Type the command below to install the required services:
apt-get install hostapd dnsmasq
As it is the services will be automatically started when the computer boots, but we need better control than that. So change the default settings to manual start:
update-rc.d -f hostapd remove
update-rc.d -f dnsmasq remove

Step 2: Configuration Files

Create or update the following config files with the contents below:

/etc/hostapd/hostapd.conf
interface=wlan0
driver=nl80211
ssid=hotspot # Your WAP name, change it to something more unique
hw_mode=g
channel=6 # You may want to change this if the channel is too crowded
wpa=1
wpa_passphrase=hotspot_password # Password for clients
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP CCMP
wpa_ptk_rekey=600

/etc/dnsmasq.conf
# disables dnsmasq reading any other files like /etc/resolv.conf for nameservers
no-resolv
# Interface to bind to
interface=wlan0
# Specify starting_range,end_range,lease_time
dhcp-range=10.0.0.3,10.0.0.20,12h
# dns addresses to send to the clients
server=8.8.8.8
server=8.8.4.4

Step 3: Interface Scripts

Add the scripts below to your system:

/etc/network/if-up.d/wapstart
#!/bin/sh

WIRE=eth0
WIFI=wlan0

# Only run script for wired interface
if [ ! "$IFACE" = "$WIRE" ]
then
    exit 0
fi

# Setup wireless interface
ifconfig $WIFI up 10.0.0.1 netmask 255.255.255.0

# Start dnsmasq
/etc/init.d/dnsmasq start

#Enable NAT
iptables --flush
iptables --table nat --flush
iptables --delete-chain
iptables --table nat --delete-chain
iptables --table nat --append POSTROUTING --out-interface $WIRE -j MASQUERADE
iptables --append FORWARD --in-interface $WIFI -j ACCEPT

# Start the Wireless Access Point service
/etc/init.d/hostapd start

exit 0

/etc/network/if-post-down.d/wapstop
#!/bin/bash

WIRE=eth0
WIFI=wlan0

# Only run script for wired interface
if [ ! "$IFACE" = "$WIRE" ]
then
    exit 0
fi

# Stops Wireless Access Point services
/etc/init.d/hostapd stop
/etc/init.d/dnsmasq stop

# Asked nice the first time...
killall dnsmasq
killall hostapd

ifconfig $WIFI down
Make sure to create the scripts from the root account, so they'll have the right ownership. Also don't forget to give them running permission:
chmod +x /etc/network/if-up.d/wapstart
chmod +x /etc/network/if-post-down.d/wapstop

Usage

After performing the steps above, you should be able to start the WAP by stopping and restarting the wired interface:
ifconfig eth0 down
ifconfig eth0 up
From now on it will also be automatically started at boot time.

Troubleshooting

Make sure the wireless interface is turned "on" in the network manager applet before you start, as hostapd may fail to start otherwise.

Also check /etc/init.d/hostapd for whether the variable DAEMON_CONF is set; if not, set it to the path of the config file:
DAEMON_CONF=/etc/hostapd/hostapd.conf

Tuesday, March 19, 2013

John Nash Vindicated?

Kaspersky Lab's Global Research & Analysis Team (GReAT) reports some unsettling details on the MiniDuke malware:

(...) If the target system meets the pre-defined requirements, the malware will use Twitter (unbeknownst to the user) and start looking for specific tweets from pre-made accounts. These accounts were created by MiniDuke’s Command and Control (C2) operators and the tweets maintain specific tags labeling encrypted URLs for the backdoors.

Once the infected system locates the C2, it receives encrypted backdoors that are obfuscated within GIF files and disguised as pictures that appear on a victim’s machine.

Once they are downloaded to the machine, they can fetch a larger backdoor which carries out the cyberespionage activities, through functions such as copy file, move file, remove file, make directory, kill process and of course, download and execute new malware and lateral movement tools.


An espionage system that talks to his masters via hidden messages in public media? I guess we all owe Mr. Nash an apology then...

Monday, March 18, 2013

Straight out of a Jetsons episode, the future of robotic manufacture


With its vaguely humanoid frame and cartoonish screen-drawn eyes, Baxter looks like an early-20th century artist's impression of a robot. And indeed, in many ways it is closer from those old ideals of pervasive robotics than the practical restrictions we have come to expect from industrial robots. Will Knight writes:

Baxter is the first of a new generation of smarter, more adaptive industrial robots. Conventional industrial robots are expensive to program, incapable of handling even small deviations in their environment, and so dangerous that they have to be physically separated from human workers by cages. (...) Baxter, however, can be programmed more easily than a Tivo and can deftly respond to a toppled-over part or shifted table. And it is so safe that Baxter’s developer, Rethink Robotics, which loaned Baxter to Vanguard Plastics, believes it can work seamlessly alongside its human coworkers.

Saturday, January 19, 2013

Genkou Youshi Template for OpenOffice / LibreOffice

Writing assignments on genkou youshi are a staple of Japanese language classes. Tradition and the need to practice Kanji writing often dictate that such works be handwritten, but there's no reason one couldn't first compose the text on a computer (where editing, revision and indeed writing itself are much easier) and only reach to paper and pencil when the final version is ready.

Experience has taught me that hand-copying texts from a computer screen is much quicker and less error-prone when both digital document and paper share the same layout, and of course it's best if I can print genkou youshi sheets at my own leisure, rather than go out and buy them (not many stationery shops this side of the world have them, anyway). Searching the web it is relatively easy to find a genkou youshi template for Microsoft Word, but Open Document Format equivalents are harder to come by – and while it's possible to use the Word templates on OpenOffice / LibreOffice, rendering problems such as misaligned grids and hidden hanging punctuation are often present, which is kind of frustrating for a die-hard Linux user like me.

Today as I sit down to try and create a genkou youshi template on LibreOffice, I decided to try and look it out one last time – and there I found a genkou youshi Open Template on the OpenOffice Templates web site. I'm kind of baffled as to how I didn't come across it earlier (apparently it was uploaded in 2009), so I thought I'd link to it here, so others who might also be looking for it have a better chance of finding it. So there.