Monthly Archives: November 2010

Linux WIFI commands

Hardware

This section gives some infos about various hardware related topics regarding Overo Wifi.

Module

Overo Wifi solution is based on an Wi2Wi chip based on Marvell’s industry leading 88W8686 which brings 802.11(b/g) wifi.

MMC

Overo fire’s WiFi port connected to MMC port 2 in 4 bit configuration.

Connector and Antenna

For 802.11b/g (Wifi) to work on an Overo Air COM or Overo Fire COM, a u.fl antenna must be connected to J2 on Overo Air or Fire COMs. The location of J2 is shown here.

Note: J3 is the antenna location when using BlueTooth. J3 also takes a u.fl antenna.

Note that two (2) u.fl antennae come with each Overo Fire COM and with each Overo Air COM.

Software

Official Overo pre-built Linux images or developer images contain already support for Overo Wifi. However, wifi configuration depending on your local wifi environment still has to be done.

There is also a thin-firmware driver and firmware that permit you to utilize the mac80211 drives in the Linux kernel. This is useful if you want to experiment with running an AP, 802.11s mesh, or other types of experiments on your Overo.

Boot messages

At Overo boot, you should get something like

...
libertas_sdio: Libertas SDIO driver
libertas_sdio: Copyright Pierre Ossman
libertas_sdio mmc1:0001:1: firmware: requesting sd8686_helper.bin
libertas_sdio mmc1:0001:1: firmware: requesting sd8686.bin
libertas: 00:19:88:05:b5:31, fw 9.70.3p24, cap 0x00000303
libertas: PREP_CMD: command 0x00a3 failed: 2
libertas: PREP_CMD: command 0x00a3 failed: 2
libertas: eth0: Marvell WLAN 802.11 adapter 
...

Note: The two “command 0×00a3 failed” messages are harmless, and have to do with features that are not supported.

Test

For test of basic functionality, do the following at command line (after log in as root / no password):

root@overo:~# <strong>iwconfig wlan0 essid any</strong>
root@overo:~# <strong>ifconfig wlan0 up</strong>
root@overo:~# <strong>iwlist wlan0 scan</strong>

what should list the wifi’s visible, then.

Unencypted wifi

Some default builds do not enable any Wifi. You may need to edit /etc/network/interfaces to include a section which looks like:

allow-hotplug wlan0                                                             
auto wlan0                                                                      
iface wlan0 inet dhcp                                                           
        pre-up /sbin/iwconfig wlan0 essid any                                   
        wireless_mode managed

The problem is this setup is not reliable! we’re waiting for a solution.

WEP encryption

  • Edit /etc/network/interfaces to have only for wlan0 (don’t touch the other entries):
iwconfig wlan0 essid "My Wireless Network"
iwconfig wlan0 key my-hex-key
ifdown wlan0
ifup wlan0

WPA encryption

  • Edit /etc/network/interfaces to have only for wlan0 (don’t touch the other entries):
allow-hotplug wlan0
iface wlan0 inet dhcp
      pre-up wpa_supplicant -Dwext -iwlan0 -c/etc/wpa_supplicant.conf -B
      down killall wpa_supplicant
  • Create /etc/wpa_supplicant.conf containing:
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
eapol_version=1
ap_scan=1
fast_reauth=1

network={
      ssid="add-your-ascii-ssid"
      proto=WPA2                 # try WPA RSN if you WPA2 fails
      key_mgmt=WPA-PSK
      pairwise=CCMP TKIP
      group=CCMP TKIP
      scan_ssid=1
      psk="add-your-ascii-passphrase"
      priority=10
}

Connect to network

To connect to the wireless network when the configuration is done, do the following:

  • Take down the wireless network (it might already be down, but try to be sure):
# ifdown wlan0
  • Then, bring it up again:
# ifup wlan0

Issues

Many users have reported issues with wifi data throughput being limited to about 100kB/second. It is theorized this is due to lack of SDIO IRQ support in the OMAP3 MMC driver. A patch is being investigated which reportedly achieves 13Mbps.

Additionally, the driver does not support power management at present. The use of iwconfig power commands such as the following will fail:

iwconfig wlan0 power on

Therefore, the wifi module always consumes close to 1 Watt of power when turned on.

NetworkManager

If NetworkManager is installed, this would probably not work. Check if it is installed by:

# opkg list_installed | grep networkmanager

If it is installed, remove it:

# opkg remove networkmanager

This if NetworkManager is not needed. NetworkManager uses a different configuration.

Links

Do you well-know about pthread?

Thread Basics:
  • Thread operations include thread creation, termination, synchronization (joins,blocking), scheduling, data management and process interaction.
  • A thread does not maintain a list of created threads, nor does it know the thread that created it.
  • All threads within a process share the same address space.
  • Threads in the same process share:
    • Process instructions
    • Most data
    • open files (descriptors)
    • signals and signal handlers
    • current working directory
    • User and group id
  • Each thread has a unique:
    • Thread ID
    • set of registers, stack pointer
    • stack for local variables, return addresses
    • signal mask
    • priority
    • Return value: errno
  • pthread functions return “0” if OK.


Thread Creation and Termination:

Example: pthread1.c

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;pthread.h&gt;

void *print_message_function( void *ptr );

main()
{
     pthread_t thread1, thread2;
     char *message1 = "Thread 1";
     char *message2 = "Thread 2";
     int  iret1, iret2;

    /* Create independent threads each of which will execute function */

     iret1 = <a href="http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_create">pthread_create</a>( &amp;thread1, NULL, print_message_function, (void*) message1);
     iret2 = pthread_create( &amp;thread2, NULL, print_message_function, (void*) message2);

     /* Wait till threads are complete before main continues. Unless we  */
     /* wait we run the risk of executing an exit which will terminate   */
     /* the process and all threads before the threads have completed.   */

     <a href="http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_join">pthread_join</a>( thread1, NULL);
     pthread_join( thread2, NULL); 

     printf("Thread 1 returns: %d\n",iret1);
     printf("Thread 2 returns: %d\n",iret2);
     exit(0);
}

void *print_message_function( void *ptr )
{
     char *message;
     message = (char *) ptr;
     printf("%s \n", message);
}

Compile:

  • C compiler: cc -lpthread pthread1.c
    or
  • C++ compiler: g++ -lpthread pthread1.c

Run: ./a.out
Results:

Thread 1
Thread 2
Thread 1 returns: 0
Thread 2 returns: 0

Details:

  • In this example the same function is used in each thread. The arguments are different. The functions need not be the same.
  • Threads terminate by explicitly calling pthread_exit, by letting the function return, or by a call to the function exit which will terminate the process including any threads.
  • Function call: pthread_create
        int pthread_create(pthread_t * thread, 
                           const pthread_attr_t * attr,
                           void * (*start_routine)(void *), 
                           void *arg);

    Arguments:

    • thread – returns the thread id. (unsigned long int defined in bits/pthreadtypes.h)
    • attr – Set to NULL if default thread attributes are used. (else define members of the struct pthread_attr_t defined in bits/pthreadtypes.h) Attributes include:
      • detached state (joinable? Default: PTHREAD_CREATE_JOINABLE. Other option: PTHREAD_CREATE_DETACHED)
      • scheduling policy (real-time? PTHREAD_INHERIT_SCHED,PTHREAD_EXPLICIT_SCHED,SCHED_OTHER)
      • scheduling parameter
      • inheritsched attribute (Default: PTHREAD_EXPLICIT_SCHED Inherit from parent thread: PTHREAD_INHERIT_SCHED)
      • scope (Kernel threads: PTHREAD_SCOPE_SYSTEM User threads: PTHREAD_SCOPE_PROCESS Pick one or the other not both.)
      • guard size
      • stack address (See unistd.h and bits/posix_opt.h _POSIX_THREAD_ATTR_STACKADDR)
      • stack size (default minimum PTHREAD_STACK_SIZE set in pthread.h),

    • void * (*start_routine) – pointer to the function to be threaded. Function has a single argument: pointer to void.
    • *arg – pointer to argument of function. To pass multiple arguments, send a pointer to a structure.
  • Function call: pthread_exit
        void pthread_exit(void *retval);
    

    Arguments:

    • retval – Return value of thread.

    This routine kills the thread. The pthread_exit function never returns. If the thread is not detached, the thread id and return value may be examined from another thread by using pthread_join.
    Note: the return pointer *retval, must not be of local scope otherwise it would cease to exist once the thread terminates.

  • [C++ pitfalls]: The above sample program will compile with the GNU C and C++ compiler g++. The following function pointer representation below will work for C but not C++. Note the subtle differences and avoid the pitfall below:
    void print_message_function( void *ptr );
    ...
    ...
    iret1 = pthread_create( &amp;thread1, NULL, (void*)&amp;print_message_function, (void*) message1);
    ...
    ...


Thread Synchronization:

The threads library provides three synchronization mechanisms:

  • mutexes – Mutual exclusion lock: Block access to variables by other threads. This enforces exclusive access by a thread to a variable or set of variables.
  • joins – Make a thread wait till others are complete (terminated).
  • condition variables – data type pthread_cond_t

Mutexes:

Mutexes are used to prevent data inconsistencies due to operations by multiple threads upon the same memory area performed at the same time or to prevent race conditions where an order of operation upon the memory is expected. A contention or race condition often occurs when two or more threads need to perform operations on the same memory area, but the results of computations depends on the order in which these operations are performed. Mutexes are used for serializing shared resources such as memory. Anytime a global resource is accessed by more than one thread the resource should have a Mutex associated with it. One can apply a mutex to protect a segment of memory (“critical region”) from other threads. Mutexes can be applied only to threads in a single process and do not work between processes as do semaphores.

Example threaded function:

Without Mutex With Mutex
int counter=0;

/* Function C */
void functionC()
{

   counter++

}
/* Note scope of variable and mutex are the same */
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int counter=0;

/* Function C */
void functionC()
{
   pthread_mutex_lock( &amp;mutex1 );
   counter++
   pthread_mutex_unlock( &amp;mutex1 );
}
Possible execution sequence
Thread 1 Thread 2 Thread 1 Thread 2
counter = 0 counter = 0 counter = 0 counter = 0
counter = 1 counter = 1 counter = 1 Thread 2 locked out.
Thread 1 has exclusive use of variable counter
counter = 2

If register load and store operations for the incrementing of variable counter occurs with unfortunate timing, it is theoretically possible to have each thread increment and overwrite the same variable with the same value. Another possibility is that thread two would first increment counter locking out thread one until complete and then thread one would increment it to 2.

Sequence Thread 1 Thread 2
1 counter = 0 counter=0
2 Thread 1 locked out.
Thread 2 has exclusive use of variable counter
counter = 1
3 counter = 2

Code listing: mutex1.c

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;pthread.h&gt;

void *functionC();
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int  counter = 0;

main()
{
   int rc1, rc2;
   pthread_t thread1, thread2;

   /* Create independent threads each of which will execute functionC */

   if( (rc1=pthread_create( &amp;thread1, NULL, &amp;functionC, NULL)) )
   {
      printf("Thread creation failed: %d\n", rc1);
   }

   if( (rc2=pthread_create( &amp;thread2, NULL, &amp;functionC, NULL)) )
   {
      printf("Thread creation failed: %d\n", rc2);
   }

   /* Wait till threads are complete before main continues. Unless we  */
   /* wait we run the risk of executing an exit which will terminate   */
   /* the process and all threads before the threads have completed.   */

   pthread_join( thread1, NULL);
   pthread_join( thread2, NULL); 

   exit(0);
}

void *functionC()
{
   <a href="http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_mutex_lock">pthread_mutex_lock</a>( &amp;mutex1 );
   counter++;
   printf("Counter value: %d\n",counter);
   <a href="http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_mutex_unlock">pthread_mutex_unlock</a>( &amp;mutex1 );
}

Compile: cc -lpthread mutex1.c
Run: ./a.out
Results:

Counter value: 1
Counter value: 2

When a mutex lock is attempted against a mutex which is held by another thread, the thread is blocked until the mutex is unlocked. When a thread terminates, the mutex does not unless explicitly unlocked. Nothing happens by default.


Joins:

A join is performed when one wants to wait for a thread to finish. A thread calling routine may launch multiple threads then wait for them to finish to get the results. One waits for the completion of the threads with a join.

Sample code: join1.c

#include &lt;stdio.h&gt;
#include &lt;pthread.h&gt;

#define NTHREADS 10
void *thread_function(void *);
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int  counter = 0;

main()
{
   pthread_t thread_id[NTHREADS];
   int i, j;

   for(i=0; i &lt; NTHREADS; i++)
   {
      <a href="http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_create">pthread_create</a>( &amp;thread_id[i], NULL, thread_function, NULL );
   }

   for(j=0; j &lt; NTHREADS; j++)
   {
      <a href="http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_join">pthread_join</a>( thread_id[j], NULL); 
   }

   /* Now that all threads are complete I can print the final result.     */
   /* Without the join I could be printing a value before all the threads */
   /* have been completed.                                                */

   printf("Final counter value: %d\n", counter);
}

void *thread_function(void *dummyPtr)
{
   printf("Thread number %ld\n", <a href="http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_self">pthread_self</a>());
   pthread_mutex_lock( &amp;mutex1 );
   counter++;
   pthread_mutex_unlock( &amp;mutex1 );
}

Compile: cc -lpthread join1.c
Run: ./a.out
Results:

Thread number 1026
Thread number 2051
Thread number 3076
Thread number 4101
Thread number 5126
Thread number 6151
Thread number 7176
Thread number 8201
Thread number 9226
Thread number 10251
Final counter value: 10


Condition Variables:

A condition variable is a variable of type pthread_cond_t and is used with the appropriate functions for waiting and later, process continuation. The condition variable mechanism allows threads to suspend execution and relinquish the processor until some condition is true. A condition variable must always be associated with a mutex to avoid a race condition created by one thread preparing to wait and another thread which may signal the condition before the first thread actually waits on it resulting in a deadlock. The thread will be perpetually waiting for a signal that is never sent. Any mutex can be used, there is no explicit link between the mutex and the condition variable.

Functions used in conjunction with the condition variable:

Example code: cond1.c

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;pthread.h&gt;

pthread_mutex_t count_mutex     = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t condition_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  condition_cond  = PTHREAD_COND_INITIALIZER;

void *functionCount1();
void *functionCount2();
int  count = 0;
#define COUNT_DONE  10
#define COUNT_HALT1  3
#define COUNT_HALT2  6

main()
{
   pthread_t thread1, thread2;

   pthread_create( &amp;thread1, NULL, &amp;functionCount1, NULL);
   pthread_create( &amp;thread2, NULL, &amp;functionCount2, NULL);
   pthread_join( thread1, NULL);
   pthread_join( thread2, NULL);

   exit(0);
}

void *functionCount1()
{
   for(;;)
   {
      <a href="http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_mutex_lock">pthread_mutex_lock</a>( &amp;condition_mutex );
      while( count &gt;= COUNT_HALT1 &amp;&amp; count &lt;= COUNT_HALT2 )
      {
         <a href="http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_cond_wait">pthread_cond_wait</a>( &amp;condition_cond, &amp;condition_mutex );
      }
      <a href="http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_mutex_unlock">pthread_mutex_unlock</a>( &amp;condition_mutex );

      pthread_mutex_lock( &amp;count_mutex );
      count++;
      printf("Counter value functionCount1: %d\n",count);
      pthread_mutex_unlock( &amp;count_mutex );

      if(count &gt;= COUNT_DONE) return(NULL);
    }
}

void *functionCount2()
{
    for(;;)
    {
       pthread_mutex_lock( &amp;condition_mutex );
       if( count &lt; COUNT_HALT1 || count &gt; COUNT_HALT2 )
       {
          <a href="http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_cond_signal">pthread_cond_signal</a>( &amp;condition_cond );
       }
       pthread_mutex_unlock( &amp;condition_mutex );

       pthread_mutex_lock( &amp;count_mutex );
       count++;
       printf("Counter value functionCount2: %d\n",count);
       pthread_mutex_unlock( &amp;count_mutex );

       if(count &gt;= COUNT_DONE) return(NULL);
    }

}

Compile: cc -lpthread cond1.c
Run: ./a.out
Results:

Counter value functionCount1: 1
Counter value functionCount1: 2
Counter value functionCount1: 3
Counter value functionCount2: 4
Counter value functionCount2: 5
Counter value functionCount2: 6
Counter value functionCount2: 7
Counter value functionCount1: 8
Counter value functionCount1: 9
Counter value functionCount1: 10
Counter value functionCount2: 11

Note that functionCount1() was halted while count was between the values COUNT_HALT1 and COUNT_HALT2. The only thing that has been ensures is that functionCount2 will increment the count between the values COUNT_HALT1 and COUNT_HALT2. Everything else is random.

The logic conditions (the “if” and “while” statements) must be chosen to insure that the “signal” is executed if the “wait” is ever processed. Poor software logic can also lead to a deadlock condition.

Note: Race conditions abound with this example because count is used as the condition and can’t be locked in the while statement without causing deadlock. I’ll work on a cleaner example but it is an example of a condition variable.


Thread Scheduling:

When this option is enabled, each thread may have its own scheduling properties. Scheduling attributes may be specified:

  • during thread creation
  • by dynamically by changing the attributes of a thread already created
  • by defining the effect of a mutex on the thread’s scheduling when creating a mutex
  • by dynamically changing the scheduling of a thread during synchronization operations.

The threads library provides default values that are sufficient for most cases.


Thread Pitfalls:
  • Race conditions: While the code may appear on the screen in the order you wish the code to execute, threads are scheduled by the operating system and are executed at random. It cannot be assumed that threads are executed in the order they are created. They may also execute at different speeds. When threads are executing (racing to complete) they may give unexpected results (race condition). Mutexes and joins must be utilized to achieve a predictable execution order and outcome.
  • Thread safe code: The threaded routines must call functions which are “thread safe”. This means that there are no static or global variables which other threads may clobber or read assuming single threaded operation. If static or global variables are used then mutexes must be applied or the functions must be re-written to avoid the use of these variables. In C, local variables are dynamically allocated on the stack. Therefore, any function that does not use static data or other shared resources is thread-safe. Thread-unsafe functions may be used by only one thread at a time in a program and the uniqueness of the thread must be ensured. Many non-reentrant functions return a pointer to static data. This can be avoided by returning dynamically allocated data or using caller-provided storage. An example of a non-thread safe function is strtok which is also not re-entrant. The “thread safe” version is the re-entrant version strtok_r.
  • Mutex Deadlock: This condition occurs when a mutex is applied but then not “unlocked”. This causes program execution to halt indefinitely. It can also be caused by poor application of mutexes or joins. Be careful when applying two or more mutexes to a section of code. If the first pthread_mutex_lock is applied and the second pthread_mutex_lock fails due to another thread applying a mutex, the first mutex may eventually lock all other threads from accessing data including the thread which holds the second mutex. The threads may wait indefinitely for the resource to become free causing a deadlock. It is best to test and if failure occurs, free the resources and stall before retrying.
        ...
        pthread_mutex_lock(&amp;mutex_1);
        while ( pthread_mutex_trylock(&amp;mutex_2) )  /* Test if already locked   */
        {
           pthread_mutex_unlock(&amp;mutex_1);  /* Free resource to avoid deadlock */
           ...
           /* stall here   */
           ...
           pthread_mutex_lock(&amp;mutex_1);
        }
        count++;
        pthread_mutex_unlock(&amp;mutex_1);
        pthread_mutex_unlock(&amp;mutex_2);
        ...
    

    The order of applying the mutex is also important. The following code segment illustrates a potential for deadlock:

        void *function1()
        {
           ...
           pthread_mutex_lock(&amp;lock1);           <strong><em>- Execution step 1</em></strong>
           pthread_mutex_lock(&amp;lock2);           <strong><em>- Execution step 3 DEADLOCK!!!</em></strong>
           ...
           ...
           pthread_mutex_lock(&amp;lock2);
           pthread_mutex_lock(&amp;lock1);
           ...
        } 
    
        void *function2()
        {
           ...
           pthread_mutex_lock(&amp;lock2);           <strong><em>- Execution step 2</em></strong>
           pthread_mutex_lock(&amp;lock1);
           ...
           ...
           pthread_mutex_lock(&amp;lock1);
           pthread_mutex_lock(&amp;lock2);
           ...
        } 
    
        main()
        {
           ...
           pthread_create(&amp;thread1, NULL, function1, NULL);
           pthread_create(&amp;thread2, NULL, function1, NULL);
           ...
        }

    If function1 acquires the first mutex and function2 acquires the second, all resources are tied up and locked.

  • Condition Variable Deadlock: The logic conditions (the “if” and “while” statements) must be chosen to insure that the “signal” is executed if the “wait” is ever processed.


Thread Debugging:


Thread Man Pages:


Links:

News Groups:

  • comp.programming.threads
  • comp.unix.solaris

Testing: ROS USB Camera drivers

Meanwhile ROS appears to have the opposite problem, with multiple developers writing drivers that perform the same basic tasks. I suppose it’s better to have too many options than too few but figuring out which driver to use can take some time. So to save you time and energy we will be testing and rating various ROS drivers to save you time and energy.

This week we are testing USB camera drivers for performance and functionality.
Here are the options we are testing.

Probe
The probe driver, from the Brown Robotics Group, uses GStreamer to broadcast data to an image topic. The upside of this is that it is very flexible and it is easy to connect to just about any camera. It can also be used to connect to more than just cameras, for example with the right incantations it can be used to connect to things like mjpeg streams sent over http.

On the downside, figuring out the right incantations to get anything to work can take a while. One option is to launch the driver from a terminal, which may make it easier to get GStreamer setup.

$ export PROBE_CONFIG="v4l2src device=/dev/video1 ! video/x-raw-rgb, width=320, height=240, framerate=30/1 ! ffmpegcolorspace ! identity name=ros ! fakesink"
$ rosrun probe probe

probe launch file

&lt;launch&gt;
  &lt;env name="PROBE_CONFIG" value="v4l2src device=/dev/video1 ! video/x-raw-rgb, width=320, height=240, framerate=30/1 ! ffmpegcolorspace ! identity name=ros ! fakesink" /&gt;
  &lt;node name="probe" pkg="probe" type="probe" respawn="false" output="screen"/&gt;
&lt;/launch&gt;

usb_cam
Developed by the Bosch Research and Technology Center for their Segway RMP based robot, the usb_cam driver offers good performance and reasonable configuration options. It is also the only driver considered that currently support the camera_info topic. Unfortunately it doesn’t support saving the calibration to a file via set_camera_info. So tricking the camera calibration process into working in the boxturtle release requires editing the source.

~/ros/stacks/image_pipeline/camera_calibration/nodes/cameracalibrator.py

...

class CalibrationNode:

    def __init__(self, chess_size, dim):
        # assume any non-default service names have been set.  Wait for the service to become ready
#        for svcname in ["camera", "left_camera", "right_camera"]:
        for svcname in ["left_camera", "right_camera"]:
            remapped = rospy.remap_name(svcname)
            if remapped != svcname:
                fullservicename = "%s/set_camera_info" % remapped

...

usb_cam launch file

&lt;launch&gt;
    &lt;node name="usb_cam" pkg="usb_cam" type="usb_cam_node" output="screen" &gt;
        &lt;param name="video_device" value="/dev/video1" /&gt;
        &lt;param name="image_width" value="640" /&gt;
        &lt;param name="image_height" value="480" /&gt;
        &lt;param name="pixel_format" value="yuyv" /&gt;
        &lt;param name="camera_frame_id" value="usb_cam" /&gt;
        &lt;param name="io_method" value="mmap"/&gt;
        &lt;rosparam param="D"&gt;[0.032095, -0.238155, 0.000104, -0.002138, 0.0000]
        &lt;rosparam param="K"&gt;[723.715912, 0.000000, 318.180121, 0.000000, 719.919423, 280.697379, 0.000000, 0.000000, 1.000000]
        &lt;rosparam param="R"&gt;[1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]
        &lt;rosparam param="P"&gt;[723.715912, 0.000000, 318.180121, 0.000000, 0.000000, 719.919423, 280.697379, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000]
    &lt;/node&gt;
&lt;/launch&gt;

uvc_cam
Developed at the Stanford AI Lab, the uvc_cam driver may not have the highest performance but it seems to have more of the camera controls implemented. It also has some interesting support tools included, including a program that can be used to enumerate the available camera devices.

uvc_cam launch file

&lt;launch&gt;
    &lt;node name="uvc_cam" pkg="uvc_cam" type="senderIT" output="screen" &gt;
        &lt;param name="device" value="/dev/video1" /&gt;
        &lt;param name="topic" value="/camera/image" /&gt;
        &lt;param name="width" value="640" /&gt;
        &lt;param name="height" value="480" /&gt;
        &lt;param name="fps" value="30" /&gt;
    &lt;/node&gt;
&lt;/launch&gt;

gencam_cu
Over at Colorado University they have developed the gencam_cu driver. This driver uses OpenCV to access the camera. The driver has pretty good performance however there appears to be no way to configure the resolution. It does however support compressed_image_transport which is convenient.

gencam_cu launch file

&lt;launch&gt;
    &lt;node name="gencam_cu" pkg="gencam_cu" type="gencam_cu" output="screen" &gt;
        &lt;param name="camera_index" value="1" /&gt;
    &lt;/node&gt;
&lt;/launch&gt;

logitech_usb_webcam
Actually, this isn’t another driver, it’s just some launch files that work with usb_cam.

Original source from : http://www.iheartrobotics.com/2010/05/testing-ros-usb-camera-drivers.html