please update auto focus algorithm 1- in phase1 O...
创建于:2026年10月13日
使用 GPT-5.6 Thinking 回答 Chat01
创建于:2026年10月13日
使用 GPT-5.6 Thinking 回答 Chat01
please update auto focus algorithm
1- in phase1 OBJ searching it trying to get highest score, like find best 32 while scanning, then back to score less than 32 like 22, fix it maybe it gets wrong position
2- i noticed that when find high score like 4 5 6 30 4 2 3..etc continue, once find it can stop its like pyramid peak
3- when focus is less than 2, try make it further range alittle like i clicked focus 2 times or something like that but make farther range
4- critical note dont change anything else try dont change much, just a little as 3 points
I’ll make only targeted autofocus changes: keep the best OBJ peak instead of drifting past it, stop coarse climbing once a clear pyramid peak is confirmed, and slightly widen the search only when focus is very low (<2). I’ll avoid touching lighting, capture, zoom, or unrelated motor logic.
I found the main issue behind point 1: the code already remembers the highest stopped score globally, but at the end of fine search it can overwrite that winner with a lower re-measured score. That matches your “found 32, then goes back to ~22” observation, so I’ll preserve the highest measured position instead of letting the final recheck discard it.
I also confirmed the moving focus values are logged during OBJ motion, but this push-button hill-climb does not currently use that live peak to choose/revisit the position. I’m going to reuse that existing live-peak information rather than redesigning the autofocus state machine; this keeps the change small and directly addresses the “32 seen while scanning” case.
The patch is now limited to mainwindow.cpp; mainwindow.h, autofocus.cpp, and autofocus.h stay untouched. The low-focus behavior is also narrow: only an OBJ run that starts below score 2 gets a slightly longer coarse range (15 mm instead of 10 mm); normal runs keep the original range.
Updated with only small autofocus changes in mainwindow.cpp; the other three files are untouched.
OBJ phase 1 peak handling: the existing code already tracks live focus peaks while the motor is moving. (mainwindow.cpp) Now if it sees something like 4 → 5 → 6 → 30 → 4, it stops the coarse search and fine-scans around the estimated 30 position instead of continuing away. The live 30 is used as a position hint and is rechecked while stopped, so a motion-noise spike is not blindly accepted.
Don’t lose the best score/position: previously the fine result could replace an earlier stronger coarse result. (mainwindow.cpp) Now if coarse found a verified 32 and fine recheck gives 22, the algorithm keeps the position of the stronger verified measurement rather than throwing it away.
Very-low focus gets slightly farther OBJ search: normal OBJ coarse range remains 10 mm, as before. (mainwindow.cpp) Only when the starting OBJ focus is < 2, it can search up to 15 mm.
I did not change mainwindow.h, autofocus.cpp, or autofocus.h. A full Qt compile isn't available in this environment, but I verified the patch applies cleanly and checked the edited paths.
please back arabic messages and for zoom make new professional equestions depend on this data
The following are the inspection values,
given that cam is the starting point relative to the camera and obj is the starting point relative to the objective,
and the distance between the camera and the objective equals cam + obj + an unknown constant value:
| obj | cam | x |
| 17.4 | 9 | 1.65524 |
| 18 | 14.7 | 1.853116667 |
| 18.5 | 27.5 | 2.357511111 |
| 19 | 36.5 | 2.6823 |
| 19.5 | 68.1 | 3.926533333 |
| 19.8 | 78.1 | 4.3013 |
| 20 | 94.1 | 4.91576 |
| 20.2 | 122.1 | 5.9344 |
| 20.3 | 172.1 | 7.8916 |
I’ll keep the autofocus changes as-is, restore the Arabic-facing messages/comments that were garbled, and update only the zoom calibration. For the zoom math, I’ll fit the provided obj/cam/x measurements and choose a stable equation that maps requested x back to motor positions without changing unrelated behavior.
pythonimport numpy as np, math, pandas as pd obj=np.array([17.4,18,18.5,19,19.5,19.8,20,20.2,20.3],float) cam=np.array([9,14.7,27.5,36.5,68.1,78.1,94.1,122.1,172.1],float) x=np.array([1.65524,1.853116667,2.357511111,2.6823,3.926533333,4.3013,4.91576,5.9344,7.8916],float) s=obj+cam coef=np.polyfit(s,x,1) coef, s (array([0.03758806, 0.62655703]), array([ 26.4, 32.7, 46. , 55.5, 87.6, 97.9, 114.1, 142.3, 192.4]))
pythonpred=coef[0]*s+coef[1] res=x-pred rmse=np.sqrt(np.mean(res**2)) maxerr=np.max(abs(res)) list(zip(s,x,pred,res)), rmse,maxerr ([(np.float64(26.4), np.float64(1.65524), np.float64(1.618881778770109), np.float64(0.036358221229890963)), (np.float64(32.7), np.float64(1.853116667), np.float64(1.8556865484507745), np.float64(-0.002569881450774414)), (np.float64(46.0), np.float64(2.357511111), np.float64(2.3556077288877346), np.float64(0.0019033821122653727)), (np.float64(55.5), np.float64(2.6823), np.float64(2.7126942863427064), np.float64(-0.030394286342706245)), (np.float64(87.6), np.float64(3.926533333), np.float64(3.919270969953715), np.float64(0.007262363046284914)), (np.float64(97.89999999999999), np.float64(4.3013), np.float64(4.306427974352263), np.float64(-0.005127974352262754)), (np.float64(114.1), np.float64(4.91576), np.float64(4.915354524959688), np.float64(0.0004054750403117424)), (np.float64(142.29999999999998), np.float64(5.9344), np.float64(5.9753377797207605), np.float64(-0.0409377797207604)), (np.float64(192.4), np.float64(7.8916), np.float64(7.858499519562243), np.float64(0.03310048043775726))], np.float64(0.023820407005287893), np.float64(0.0409377797207604))
pythonL=np.log(x) # existing obj coefficients: pred_obj=((0.1760222*L-1.6729109)*L+5.1422488)*L+15.2942523 print(pd.DataFrame({'x':x,'obj':obj,'pred':pred_obj,'err':pred_obj-obj})) print('rmse',np.sqrt(np.mean((pred_obj-obj)**2)), 'max',np.max(abs(pred_obj-obj))) # resulting cam using sum linear inversion pred_sum=(x-0.626557)/0.03758806 pred_cam=pred_sum-pred_obj print('cam rmse',np.sqrt(np.mean((pred_cam-cam)**2)), 'max',np.max(abs(pred_cam-cam))) print(pd.DataFrame({'x':x,'cam':cam,'pred':pred_cam,'err':pred_cam-cam}))
pythonfrom sklearn.metrics import mean_squared_error for deg in range(1,7): c=np.polyfit(x,obj,deg); po=np.polyval(c,x) cc=np.polyfit(x,cam,deg); pc=np.polyval(cc,x) print("deg x",deg,"obj rmse",np.sqrt(np.mean((po-obj)**2)),"max",np.max(abs(po-obj)),"cam rmse",np.sqrt(np.mean((pc-cam)**2)),"max",np.max(abs(pc-cam))) print("ln") for deg in range(1,7): c=np.polyfit(L,obj,deg); po=np.polyval(c,L) cc=np.polyfit(L,cam,deg); pc=np.polyval(cc,L) print("deg ln",deg,"obj",np.sqrt(np.mean((po-obj)**2)),np.max(abs(po-obj)),"cam",np.sqrt(np.mean((pc-cam)**2)),np.max(abs(pc-cam)))
pythona,b=coef b/a np.float64(16.669044681849638)
The data supports a cleaner calibration interpretation: fitting x against cam + obj gives a very strong linear relation, which corresponds to an estimated fixed mechanical/optical offset of about 16.669 mm. I’ll use that for the total camera–objective distance, while using shape-preserving interpolation for the obj split so every supplied inspection point is honored exactly and the curve stays smooth between them.
pythonimport numpy as np s=obj+cam a,b=np.polyfit(s,x,1) pred=a*s+b ss_res=((x-pred)**2).sum() ss_tot=((x-x.mean())**2).sum() r2=1-ss_res/ss_tot a,b,b/a,r2 (np.float64(0.03758805867947069), np.float64(0.6265570296320829), np.float64(16.669044681849638), np.float64(0.9998512747933355))
pythonfor deg in range(1,6): c=np.polyfit(x,s,deg) ps=np.polyval(c,x) err=ps-s print(deg, np.sqrt(np.mean(err**2)), np.max(abs(err)), c)
pythonimport scipy.optimize as opt, numpy as np, math def f_exp(x,c,a,b): return c-a*np.exp(-b*x) popt,_=opt.curve_fit(f_exp,x,obj,p0=[20.5,6,0.5],maxfev=10000) popt, np.sqrt(np.mean((f_exp(x,*popt)-obj)**2)), np.max(abs(f_exp(x,*popt)-obj)) (array([20.33713704, 8.02450402, 0.63421606]), np.float64(0.09805437383682913), np.float64(0.1720056184757297))
pythonimport numpy as np, pandas as pd from scipy.interpolate import PchipInterpolator xv=np.array([1.65524,1.853116667,2.357511111,2.6823,3.926533333,4.3013,4.91576,5.9344,7.8916]) objv=np.array([17.4,18,18.5,19,19.5,19.8,20,20.2,20.3]) sumv=np.array([26.4,32.7,46,55.5,87.6,97.9,114.1,142.3,192.4]) po=PchipInterpolator(xv,objv) ps=PchipInterpolator(xv,sumv) for z in [2,3,4,5,6,7]: o=float(po(z)); s=float(ps(z)); c=s-o print(z,o,c,s)
The zoom calibration now reproduces all 9 inspection points exactly—for example, the first point returns OBJ 17.4 / CAM 9.0, and the last returns OBJ 20.3 / CAM 172.1. Between points it uses a monotone cubic curve, so it stays smooth without the oscillation risk of a high-degree polynomial.
Done. I updated only mainwindow.cpp.
The Arabic text is restored from the broken Ø... / Ù... encoding back to proper Arabic, including the sample dialogs and the existing Arabic comments. This was only text/encoding restoration—no related logic was changed.
For zoom, I replaced the previous approximation with a calibration based directly on your 9 inspection measurements. The physical relationship from your data is approximately:
with .
For the actual motor commands, I used shape-preserving monotone cubic interpolation on:
OBJ(x)SUM(x) = OBJ + CAMCAM(x) = SUM(x) - OBJ(x)This is preferable to a large polynomial because it is smooth, does not oscillate between calibration points, and reproduces all 9 measured points exactly. For example, x = 1.65524 returns OBJ = 17.4, CAM = 9.0, and x = 7.8916 returns OBJ = 20.3, CAM = 172.1.
The autofocus changes from the previous version are still preserved.
still not arabic, make it in zip file and same it in file format that accept arabic and make sure arabic is exist
I’ll package a verified UTF-8 version and a ZIP. I’ll also inspect the actual bytes in mainwindow.cpp to make sure real Arabic Unicode characters are present—not mojibake like Ø.../Ù...—and save a BOM-compatible copy for editors that need it.
The source itself does contain real Arabic Unicode now (I verified 1,513 Arabic characters and zero Ø/Ù mojibake markers). The remaining problem is most likely how the editor detects the encoding, so I’m converting the delivered .cpp to UTF-8 with BOM, which Qt Creator/Visual Studio recognize much more reliably.
Done. I rebuilt the source as UTF-8 with BOM, specifically to make Arabic display correctly in Qt Creator / Visual Studio.
I verified the actual file bytes:
EF BB BFØ / Ù mojibake characters remainتم تصوير هذه العينة من قبل, تحضير العينة, برجاء تحضير العينة وإدخالها, and تخطيThe ZIP contains mainwindow.cpp plus an encoding verification note.
great work, now need update, when zoom is changed back CAM and OBJ to 0 first both of them then go to position of zoom
I’ll change only the zoom move sequence: whenever a zoom change is applied, OBJ and CAM will first return to 0, then the normal calibrated zoom targets will be sent. I’ll keep the UTF-8 BOM/Arabic encoding and the autofocus changes intact.
I found the existing zoom state machine is sequential (OBJ target → CAM target). I’m extending that same mechanism rather than adding a second system: OBJ → 0, CAM → 0, then OBJ → calibrated target, CAM → calibrated target, and only after that autofocus continues.
Done. Zoom movement now follows this sequence every time zoom is applied:
OBJ → 0 → CAM → 0 → OBJ → new zoom position → CAM → new zoom position → autofocus continues.
I kept everything else unchanged, including the new zoom calibration and autofocus improvements. The source is still UTF-8 with BOM; I verified the Arabic remains intact with 1,513 Arabic characters and no broken Ø/Ù encoding.