Autofokus-Modus der EOS per Software schalten
Der beschriebene Umbau des Objektivs zu Festhalten der Fokuseinstellung war von Anfang an ein ärgerlicher Workaround.
Eine erste Linderung brachte schon die Fokus-Einstellung „AI Servo“. Damit wird immerhin die Aufnahme nicht blockiert wenn die Kamera nicht scharfstellen kann. Manchmal sehen die Kreuzsensoren aber genug Licht um anzusprechen, aber zu wenig um wirklich scharf zu stellen und dann ist bei schlechten Lichtverhältnissen das Bild nicht mehr scharf zu bekommen.
Schon seit längerer Zeit war klar, dass das EOS-Utility von Canon eine Umschaltung zwischen AF und MF auch per Software schafft, nur mit gphoto2 ist dies trotz schier unendlicher Versuchsreihen einfach nicht gelungen.
Durch einen mühseligen USB-Trace des EOS-Utility habe ich dann mit der Zeit herausgefunden, was dort anders läuft und warum es damit funktioniert.
Der Trick ist folgender: Neben dem „Capture“-Kommando gibt es in der PTP-Kommunikation bei Canon auch ein „Release“-Kommando, das quasi den Auslöseknopf betätigt. Wie beim echten Auslöser kann man diesen sowohl halb als auch voll durchdrücken: Beim halben Drücken wird nur scharf gestellt, beim vollen Drücken wird ausgelöst.
Um den ersten Schritt zu überspringen müssen im PTP-Datenstrom beide Kommandos unmittelbar nacheinander geschickt werden. Dann stellt die Kamera nicht erst scharf, sondern löst unmittelbar aus. Genau so macht es auch das EOS-Utility.
Mit gphoto2 kann ab der Version 2.4.11 (muss selbst compiliert werden) zwar über den Parameter „eosremoterelease“ der virtuelle Auslöseknopf gedrückt werden, die besagte schnelle Abfolge von halb und voll drücken ist aber trotzdem nicht möglich.
Ich habe deshalb einen Patch für libgphoto2 gemacht, mit dem mittels
gphoto2 --set-config eosremoterelease=4
genau dieses Verhalten ausgelöst werden kann.
Auf der Download-Seite kann eine compilierte Version heruntergeladen werden, die die Binaries enthält und unter allen OpenWRT-Versionen ab 10.03.1-rc4 (also auch 10.03.1) für den Asus WL500GP (also brcm-2.4 oder brcm47xx) lauffähig ist. Die Änderungen im Quellcode sind weiter unten beschrieben, der Rest ist original.
Auch das weiter oben beschriebene Shellskript wird durch diese Änderung etwas aufwendiger. Die Kamera muss ja nicht nur auslösen, sondern auch das erzeugte Bild aus dem Hauptspeicher der Kamera herunterladen.
Das geht mit der gphoto2-Option –capture-tethered, die allerdings etwas unhandlich ist weil das Programm nicht nach dem Download, sondern nach einer festen Zeit beendet. Die Zeit muss lang genug für lange Belichtung und ggf. Rauschunterdrückung sein, da kann im Extremfall gut eine Minute vergehen. Das folgende Skript generiert dazu eine hook-Funktion, die ggf. gphoto2 schon vorher beendet, damit der Vorgang zeitnah zu Ende kommt.
Das fertige Skript sieht dann beispielsweise so aus:
Hinweis: Im Download-Archiv liegt eine neuere Version, die eine andere Methode zum Upload verwendet. Die folgende Darstellung dient nur zur Veranschaulichung der Funktion.
- /usr/bin/webcam_capture
#!/bin/sh # # WebCam Bilder erzeugen # Flori Radlherr, www.radlherr.de # # Skript wird auch als hook fuer gphoto2 verwendet if [ -n "$ACTION" ] then echo "Action: $ACTION" >&2 if [ "$ACTION" = download ] then echo -n "Action: download ready ... " >&2 sleep 2 # gphoto2 beenden, da capture-tethered sonst lange blockiert killall gphoto2 fi exit 0 fi cd /tmp # Prozedur: Ein Foto aufnehmen. do_capture () { rm -f *.jpg 2>/dev/null gphoto2 --set-config eosremoterelease=3 \ --set-config eosremoterelease=4 \ --capture-tethered=80s --hook-script=$0 |\ grep -v Property >&2 # Grundzustand der Kamera wieder herstellen gphoto2 --set-config eosremoterelease=3 >&2 cat *.jpg } # Bei vorhandenem cmd-Parameter nur scharf stellen if [ -n "$1" ] then echo "Fokus neu einstellen..." >&2 gphoto2 --set-config autofocusdrive=1 --wait-event=5s 2>&1 |\ grep -v Property exit 0 fi # Bild machen if ! do_capture then # Wenns nix war, Kamera aus/einschalten echo "0" >/proc/diag/led/power sleep 2 echo "1" >/proc/diag/led/power sleep 10 do_capture fi
Im Sourcecode von libgphoto2 (Version 2.4.11) ist folgendes einzufügen:
In libgphoto2-2.4.11/camlibs/ptp2/config.c muss die Sektion „Immediate“ hinzugefügt werden.
static int _get_Canon_EOS_RemoteRelease(CONFIG_GET_ARGS) { gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget); gp_widget_set_name (*widget,menu->name); /* FIXME: remember state of release */ gp_widget_add_choice (*widget, _("None")); gp_widget_add_choice (*widget, _("On 1")); gp_widget_add_choice (*widget, _("On 2")); gp_widget_add_choice (*widget, _("Off")); gp_widget_add_choice (*widget, _("Immediate")); gp_widget_set_value (*widget, _("None")); return (GP_OK); } static int _put_Canon_EOS_RemoteRelease(CONFIG_PUT_ARGS) { uint16_t ret; const char* val; PTPParams *params = &(camera->pl->params); if (!ptp_operation_issupported(params, PTP_OC_CANON_EOS_RemoteReleaseOn)) return (GP_ERROR_NOT_SUPPORTED); gp_widget_get_value(widget, &val); if (!strcmp (val, _("None"))) return GP_OK; if (!strcmp (val, _("On 1"))) { ret = ptp_canon_eos_remotereleaseon (params, 1); } else { if (!strcmp (val, _("On 2"))) { ret = ptp_canon_eos_remotereleaseon (params, 2); } else { if (!strcmp (val, _("Immediate"))) { /* HACK by Flori Radlherr: "fire and forget" half release before release: Avoids autofocus drive while focus-switch on the lens is in AF state */ ret = ptp_canon_eos_remotereleaseon (params, 1); ret = ptp_canon_eos_remotereleaseon (params, 2); } else { if (!strcmp (val, _("Off"))) { ret = ptp_canon_eos_remotereleaseoff (params, 1); } else { gp_log (GP_LOG_DEBUG, "ptp2/canon_eos_remoterelease", "Unknown value %s", val); return GP_ERROR_NOT_SUPPORTED; } } } } if (ret != PTP_RC_OK) { gp_log (GP_LOG_DEBUG, "ptp2/canon_eos_remoterelease", "Canon EOS remote release failed: 0x%x", ret); return translate_ptp_result (ret); } /* Get the next set of event data */ ret = ptp_check_eos_events (params); if (ret != PTP_RC_OK) { gp_log (GP_LOG_ERROR,"ptp2/canon_eos_remoterelease", "getevent failed!"); return translate_ptp_result (ret); } return GP_OK; }
Sowie in libgphoto2-2.4.11/camlibs/ptp2/ptp.h folgende Definiton erweitern (Parameter hinten hinzufügen)
#define ptp_canon_eos_remotereleaseon(params,x) \
ptp_generic_no_data(params,PTP_OC_CANON_EOS_RemoteReleaseOn,2,x,1)
