Bold monospace type
denotes commands typed into the computer andMonospace typedenotes output from a command.
For a list of supported cameras, see Digital Camera Support for Unix. PTP support in cameras varies enormously, and should not be assumed, even if you are buying the latest and greatest. We have done all of our testing on a Nikon Coolpix 5700. This camera has worked well for us; note that it ships with PTP disabled; you have to re-enable it as a menu option. You'll also want the AC adapter, as leaving the camera running drains batteries quickly.
Since we've tested a small number of cameras, I would be interested in hearing your results with other units.
/sbin/lsusband look at the output. Somewhere in there you should see this (or similar if you have a different camera):
Bus 001 Device 004: ID 04b0:010d Nikon Corp.(more of listing removed)
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 Interface
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x04b0 Nikon Corp.
idProduct 0x010d
bcdDevice 1.00
iManufacturer 1 NIKON
iProduct 2 Nikon Digital Camera E5700_PTP
iSerial 3 000003115457
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 39
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 0mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 6 Imaging
bInterfaceSubClass 1 Still Image Capture
bInterfaceProtocol 1 Picture Transfer Protocol (PIMA 15470)
iInterface 0
make alltwice. The first time, it will report an error, and then the second time will succeed. Why? Good question!
-rw-rw-r-- 1 hubbard hubbard 96722 Apr 19 15:02 jusb.jar
-rwxrwxr-x 1 hubbard hubbard 49263 Apr 19 15:02 libjusb.so*
$JAVA_HOME/jre/lib/i386.On RHEL-WS v3.0, with J2SDK 1.4.2_04, that ends up being
/usr/java/j2sdk1.4.2_04/jre/lib/i386/libjusb.so
$JAVA_HOME/jre/lib/ext
make showfrom the jusb directory should dump out an XML-formatted bus listing:
<!-- Linux usbfs -->Note that this does not test the version intalled into $JAVA_HOME. That has to wait until jphoto.
<host busses='1'>
<!-- Bus #1 -->
<?addresses portid='usb-f8883000' busaddr='1'?>
<hub usb='1.1'
vendorId='0x0' productId='0x0' device-version='0.0'
product='USB OHCI Root Hub'
serial='f8883000'
class='9' subclass='0' protocol='0'
ep0-maxpacket='8' configurations='1'>
<language id='0x0'/>
<config value='1' total-length='25' attributes='40'
max-power='0 mA.' interfaces='1'>
<!-- interface 0 is claimed by: hub driver -->
<hub number='0' alt='0' endpoints='1'
class='9' subclass='0' protocol='0'>
<endpoint addr='1' direction='in' type='interrupt'
attributes='3' maxpacket='2' interval='255'/>
</hub>
</config>
Root Hub, 4 ports
overcurrent protection: global
power switching: ganged
<!-- Port 2 -->
<?addresses portid='usb-f8883000-2' busaddr='4'?>
<device usb='1.1'
vendorId='0x4b0' productId='0x10d' device-version='1.0'
manufacturer='NIKON'
product='Nikon Digital Camera E5700_PTP'
serial='000003115457'
class='0' subclass='0' protocol='0'
ep0-maxpacket='8' configurations='1'>
<language id='0x409' locale='en_US'/>
<config value='1' total-length='39' attributes='c0'
max-power='0 mA.' interfaces='1'>
<!-- interface 0 is unclaimed -->
<unknown-6 number='0' alt='0' endpoints='3'
class='6' subclass='1' protocol='1'>
<endpoint addr='4' direction='out' type='bulk'
attributes='2' maxpacket='64' interval='0'/>
<endpoint addr='3' direction='in' type='bulk'
attributes='2' maxpacket='64' interval='0'/>
<endpoint addr='1' direction='in' type='interrupt'
attributes='3' maxpacket='8' interval='10'/>
</unknown-6>
</config>
</device>
</hub>
</host>
none /proc/bus/usb usbdevfs defaults 0 0to /etc/fstab. This makes all devices world-writeable on USB, which is a rather crude solution. Finer control requires a bit more work. When you plug a USB device in, the kernel looks up the device ID in a file and then (optionally) runs what's known as a hot-plug script apppropriate for the device. This is useful for auto-mounting memory sticks, for example. For cameras, the hotplug script is
/etc/hotplug/usb/usbcamModify the third-from-end line from
chmod 0600 "${DEVICE}to
chmod 0666 ${DEVICE}This means that all digital cameras will be world-writeable, which is probably OK. Secondly, we need to add the camera to the USB ID table, so that the kernel knows to run the usbcam script. To do that, edit the /etc/hotplug/usb.usermap file, adding this entry:
# Nikon Coolpix 5700 (PTP mode)Of course, if you have a different camera, you'll have to change the above to match its ID. See http://jphoto.sourceforge.net/?selected=sync for more information.
usbcam 0x0003 0x04b0 0x010d 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
$ export CVSROOT=:pserver:anonymous@cvs.nees.org:/disks/cvs/neesgrid
$ cvs co jphoto
$ cd jphoto
$ ant
./jphoto.sh statusThis should produce something like:
PTP device at usb-f8883000-2You can take a test picture with
Manufacturer: Nikon Corporation
Model: E5700
Device Version: E5700v1.1
Serial Number: 000003115457
Extensions (0xa): Nikon PTP Extensions
Operations: 15
Modes: Pull
Object count: 4
Storage Type: Removable RAM
./jphoto.sh capturewhich produces an image in the 'images' subdirectory.
./jphoto.sh images
$ cp lib/jphoto.jar $JAVA_HOME/jre/lib/extYou will probably need to be root to do so.
$ export CVSROOT=:pserver:anonymous@cvs.nees.org:/disks/cvs/neesgrid
$ cvs co jcamera
$ cd jcameraIf you see 'BUILD SUCCESSFUL', congratulate yourself, 'cause this has been a tough one.
$ ant
$ ./jcamera.shYou should see some print statements which will let you know that JCamera started ok. It will list what cameras it finds and assign them names starting with camera1, camera2, etc. depending on how many cameras you have attached to your system. After it starts up, it will sit and wait for an NTCP connection to arrive and get the party started.
lvHost and lvPortare set to the machine running jcamera. That way, when an NTCP connection arrives, the lvplugin will open communications with jcamera, and all will be good. In my test setup, I have this section of server-config.wsdd:
<parameter name="lvHost" value="neestpm.sdsc.edu"/>Note that port 44000 is also set in the jcamera code, so if you change it here you'll need to change it there as well.
<parameter name="lvPort" value="44000"/>
ant startContainer -Dservice.port=8090
private int focalLengthArray[] = {3500, 3600, 3700, 3900, 4200, 4600, 5000, 5400,
5800, 6200, 6600, 7000, 7400, 7800, 8300, 8800,
9300, 10000, 10700, 11600, 12500, 13600, 14800,
16100, 17600, 19100, 20600, 22300, 24200, 26600,
28000 };
[hubbard@neestpm ~/code/jcamera] ls -l image/
total 3880
-rw-rw-r-- 1 hubbard hubbard 1005837 Apr 19 15:58 TR1048792482.jpg
-rw-rw-r-- 1 hubbard hubbard 982054 Apr 19 15:58 TR1815875301.jpg
-rw-rw-r-- 1 hubbard hubbard 978661 Apr 19 16:09 TR234623115.jpg
-rw-rw-r-- 1 hubbard hubbard 983473 Apr 19 16:09 TR281657422.jpg
$ export CVSROOT=:pserver:anonymous@cvs.nees.org:/disks/cvs/neesgridBefore running jclient, you need to modify the source file:
$ cvs co jclient
src/org/nees/ntcp/jclient/JClient.javaLook for the "serverURL" variable and change it to point to the address of your NTCP server.
ant run
On the machine running jclient, you should see something like this:[hubbard@wdhcp-1 ~/code/jclient] ant runOn the machine running NTCP:
Buildfile: build.xml
checkOGSA:
prepare:
[mkdir] Created dir: /Users/hubbard/code/jclient/build
[mkdir] Created dir: /Users/hubbard/code/jclient/build/classes
[mkdir] Created dir: /Users/hubbard/code/jclient/build/lib
[mkdir] Created dir: /Users/hubbard/code/jclient/docs
compile:
[javac] Compiling 1 source file to /Users/hubbard/code/jclient/build/classes
jar:
[jar] Building jar: /Users/hubbard/code/jclient/build/lib/jclient.jar
run:
[java] Opening connection to NTCP server at http://neespop.mcs.anl.gov:8090/ogsa/services/nees/ntcp/ in non-secure mode
[java] Connection opened OK, now sending openSession
[java] - Logging is working
[java] - Date: Mon Apr 19 17:57:26 CDT 2004
[java] - Version: Apache-XML-Security-J 1.0.4
[java] Proposing transaction #63921 id: TR2066439084
[java] Transaction proposal accepted. Excellent.
[java] Executing, may take 60-90 seconds
[java] Execute completed; checking status
[java] Move incomplete - transaction not terminated!!
[java] Proposing transaction #23507 id: TR304099882
[java] Transaction proposal accepted. Excellent.
[java] Executing, may take 60-90 seconds
[java] Execute completed; checking status
[java] Move incomplete - transaction not terminated!!
[java] Closing NTCP session
[java] Done.
BUILD SUCCESSFUL
Total time: 50 seconds
[hubbard@neespop ~/code/ogsa-3.0.2] ant startContainer -Dservice.port=8090One the machine running jcamera:
Buildfile: build.xml
startContainer:
startContainer:
[java] [04/19/2004 17:57:09:889 ] org.globus.ogsa.server.ServiceContainer [run:569] INFO: Starting SOAP server at: http://127.0.0.1:8090/ogsa/services/
[java] With the following persistent services:
[java]
[java] http://127.0.0.1:8090/ogsa/services/nees/ntcp/NTCPServer
[java] http://127.0.0.1:8090/ogsa/services/core/admin/AdminService
[java] http://127.0.0.1:8090/ogsa/services/core/management/OgsiManagementService
[java] http://127.0.0.1:8090/ogsa/services/core/registry/ContainerRegistryService
[java] http://127.0.0.1:8090/ogsa/services/core/jmsadapter/JMSAdapterFactoryService
[java] http://127.0.0.1:8090/ogsa/services/core/logging/OgsiLoggingService
[java] http://127.0.0.1:8090/ogsa/services/core/notification/httpg/NotificationSubscriptionFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/registry/VORegistryService
[java] http://127.0.0.1:8090/ogsa/services/samples/counter/secure/CounterFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/counter/notification/CounterFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/counter/encoded/CounterFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/counter/persistent/CounterFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/counter/basic/CounterFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/counter/delegation/CounterFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/counter/routable/MasterRedirectedCounter
[java] http://127.0.0.1:8090/ogsa/services/samples/counter/routable/LocalCounterFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/counter/generate/CounterFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/counter/deactivation/CounterFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/counter/soap-secure/CounterFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/counter/logging/CounterFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/exception/ExceptionFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/notification/SinkListenerFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/complex/NestedArrayFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/complex/NestedFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/weather/WeatherFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/serialization/SerializationService
[java] http://127.0.0.1:8090/ogsa/services/samples/google/GoogleSearchFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/any/AnyFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/servicedata/ServiceDataService
[java] http://127.0.0.1:8090/ogsa/services/samples/array/ArraySampleFactoryService
[java] http://127.0.0.1:8090/ogsa/services/samples/chat/ChatFactoryService
[java] http://127.0.0.1:8090/ogsa/services/ogsi/NotificationSubscriptionFactoryService
[java] http://127.0.0.1:8090/ogsa/services/ogsi/HandleResolverService
[java] http://127.0.0.1:8090/ogsa/services/gsi/AuthenticationService
[java] http://127.0.0.1:8090/ogsa/services/gsi/SecureNotificationSubscriptionFactoryService
[java] sending open-session dummyOpenSession
[java] OK 0 dummyOpenSession
[java] neestpm.mcs.anl.gov return dummyOpenSession I expect: dummyOpenSession
[java] In propose**********************
[java] sending propose TR2066439084 camera z displacement 3500.0
[java] OK 0 TR2066439084
[java] first token is: OK
[java] str =:TR2066439084:should be:TR2066439084:
[java] leaving propose() with true
[java] in execute*********************
[java] sending execute TR2066439084
[java] OK 0 TR2066439084
[java] got OK on execute
[java] In getControlPoint
[java] sending get-control-point dummy camera
[java] in getControlPoint for loop
[java] OK 0 dummy camera x rotation 0 y rotation 0 z displacement 3500
[java] first token is: OK
[java] str =:dummy:should be:dummy:
[java] leaving getControlPoint() *****************************
[java] In propose**********************
[java] sending propose TR304099882 camera z displacement 28000.0
[java] OK 0 TR304099882
[java] first token is: OK
[java] str =:TR304099882:should be:TR304099882:
[java] leaving propose() with true
[java] in execute*********************
[java] sending execute TR304099882
[java] OK 0 TR304099882
[java] got OK on execute
[java] In getControlPoint
[java] sending get-control-point dummy camera
[java] in getControlPoint for loop
[java] OK 0 dummy camera x rotation 0 y rotation 0 z displacement 28000
[java] first token is: OK
[java] str =:dummy:should be:dummy:
[java] leaving getControlPoint() *****************************
[java] sending close-session dummy
[java] OK 0 dummy
[hubbard@neestpm ~/code/jcamera] ant run
Buildfile: build.xml
prepare:
compile:
run:
[java] PTP device at usb-f8883000-2
[java] PTP device at usb-f8883000-2
[java] focalLenght = 28000
[java] Incoming command: open-session dummyOpenSession
[java] Response is: OK 0 dummyOpenSession
[java] Incoming command: propose TR2066439084 camera z displacement 3500.0
[java] Response is: OK 0 TR2066439084
[java] Incoming command: execute TR2066439084
[java] PTP device at usb-f8883000-2
[java] Original value
[java] we did not find code = 0
[java] returning 0
[java] vaue is { data OUT; len 16; 0; xid 0}
[java] Type: u32, Value: 3500
[java] PTP device at usb-f8883000-2
[java] PTP device at usb-f8883000-2
[java] image saved, size 971963
[java] PTP device at usb-f8883000-2
[java] deleting
[java] Response is: OK 0 TR2066439084
[java] Incoming command: get-control-point dummy camera
[java] Response is: OK 0 dummy camera x rotation 0y rotation 0 z displacement 3500
[java] Incoming command: propose TR304099882 camera z displacement 28000.0
[java] Response is: OK 0 TR304099882
[java] Incoming command: execute TR304099882
[java] PTP device at usb-f8883000-2
[java] Original value
[java] we did not find code = 0
[java] returning 0
[java] vaue is { data OUT; len 16; 0; xid 0}
[java] Type: u32, Value: 28000
[java] PTP device at usb-f8883000-2
[java] PTP device at usb-f8883000-2
[java] image saved, size 983853
[java] PTP device at usb-f8883000-2
[java] deleting
[java] Response is: OK 0 TR304099882
[java] Incoming command: get-control-point dummy camera
[java] Response is: OK 0 dummy camera x rotation 0y rotation 0 z displacement 28000
[java] Incoming command: close-session dummy
[java] Response is: OK 0 dummy
cd {directory where you installed the turbine}You may need to allocate more memory for the Java virtual machine, for that you use an additional command line argument:
cd bin
java -jar rbnbjview.jar -a {turbine IP address or name} -c "camera1/Video.jpg,camera2/Video.jpg" &
java -Xmx128M ...Note that the -c argument can take one or more channels; given the high-res nature of these images, I'd suggest only viewing one at a time. Work on the turbine is ongoing, so expect improvements to arrive rapidly.