I'm embarassed but still haven't studied the sync code in detail (i'll try and get back at some stage if a higher authority doesn't first).
I just got round to reading the code. The following is my understanding only - it may not be totally accurate but there is some truth.
I have put the init_sync right after the start command right now. Is that correct?
You can do it anywhere before you use a command that relies on "syncat" although I remember (edit: found that in this thread
here ) reading a post that described the camera should be in record mode (since that's more a reflection of how busy the camera would be while shooting). Slightly related - the camera tick counter (ms since being turned on) and the PC system time will diverge over time e.g.
http://chdk.setepontos.com/index.php?topic=8769.msg107950#msg107950 When using your shoot code with the sync time a number is written after every "shoot". How do I need to understand this value? Is it milliseconds?
It is ms. It is an approximation of what each cameras tick counter value will be at "syncat" future ms from the value captured by multicam function mc:cmd(cmd,opts) and assigned to variable "tstart" when ustime.new() is executed - "tstart" is the ms representation of the PC system µseconds that have passed since the "epoch".
Some more detail of how, I think, the initial synch works:
The following description is repeated for each camera -- function "mc:init_sync_cam(lcon,count)" records the PC system time in var "t0". At this same time command "tick" (the actual text value "tick") is sent to the camera script (which takes an unknown, as yet, transmission period) . On receipt of "tick" the camera script runs its function "cmds.tick() "get_tick_count()". This tick count value is sent back (which also takes an unknown, as yet, transmission period) to the waiting "lcon:wait_msg(...)" and is assigned to variable "msg.status" and is ultimately passed to function "mc:init_sync_single_send" as parameter "rt0" (as is "t0" via parameter "lt0")
Now, if the "tick" command transmission period was zero (and other complications to be mentioned later did not arise) we would already have a very accurate relationship between the PC system time (since epoch) and each cam (ticks since turn on). For example, to calculate a particular cameras tick relating to the current instant all we would need do is take the difference between the current instantaneous PC ( since epoch) system time [which occurs in function mc:cmd(cmd,opts) and is assigned to variable "tstart" by "ustime.new()"] and the previously recorded "lt0" and add this difference value to the previously recorded camera tick count "rt0". To calculate a future tick value just add, say, "syncat" ms to this value (to allow for relevant "syncat" command transmission to all cameras). This is mentioned in code by multicam comment:
--[[
get camera tick matching tstart + syncat
<camera base time> + <tstart - local base time> + syncat
]]
In reality - if the transmission time period to send the "tick" command were known then it could be subtracted from "rt0" to align the Camera tick with the PC time (lt0).
This adjustment is modelled in the following PC side code:
function mc:init_sync_single_send(i,lcon,lt0,rt0,ticks,sends)
local tsend = ustime.new()
lcon:write_msg('tick')
sends[i] = ustime.diffms(tsend)
My understanding (without confidence) is that "lcon:write_msg('tick')" here involves both transmission to the camera and an acknowledgment feedback from it (ack e.g. whether camera script is running status) i.e. ustime.diffms(tsend) will not execute until after the camera acknowledgment is received. This round-trip period will vary. By default, the average of 10 of these round trip periods [ustime.diffms(tsend)] is calculated (recorded in "send_stats.mean") and, without better knowledge of how much of the trip relates to each path, is divided by 2. The result is that the camera tick is adjusted as:
rtadj = rt0 - send_stats.mean/2
I'm not currently sure the purpose of the 2nd adjustment (tick_stats.mean), to give the final camera tick relation to the PC time since epoch (lt0) as:
rtadj = rt0 - tick_stats.mean - send_stats.mean/2
And my 3rd question: what time currency is minimum sync delay in?
ms.
Some of the other concerns
http://chdk.setepontos.com/index.php?topic=8769.msg107968#msg107968:
"but the sync is quite bad because:
1) get_tick_count only works in 10ms increments
2) sleep only works in 10ms increments"(can't quote
as normal from that comment for some reason)
Edit: some other related comment
All that said, I think ~30 ms max deviation is about the as good as the current code can do:
The 10ms tick counter means that the "same" time on two cameras could be ~20ms apart, and the handoff from kbd_task to capt_seq that uses a 10ms sleep loop.
and some basis for calculation
http://chdk.setepontos.com/index.php?topic=8769.msg107985#msg107985