41import matplotlib.pyplot
as plt
45plt.rc(
'text', usetex=
True)
46plt.rc(
'text.latex', preamble=
r'\usepackage{amsmath}')
49from visp.core
import ExponentialMap
50from visp.core
import HomogeneousMatrix
51from visp.core
import Math
52from visp.core
import Point
53from visp.core
import RotationMatrix
54from visp.core
import ThetaUVector
55from visp.core
import TranslationVector
57from visp.visual_features
import FeatureTranslation
58from visp.visual_features
import FeatureThetaU
60from visp.vs
import Servo
63 def __init__(self, e, norm_e, v, x, xd, c_T_w, plot_log_scale):
72 def stack(self, e, norm_e, v, x, xd, c_T_w):
80 plt.figure(figsize=(10,10))
82 plot_e = plt.subplot(2, 2, 1)
83 plot_v = plt.subplot(2, 2, 2)
84 plot_ne = plt.subplot(2, 2, 3)
85 plot_x = plt.subplot(2, 2, 4)
87 plot_e.set_title(
'error')
88 plot_v.set_title(
'camera velocity')
89 plot_x.set_title(
'point trajectory in the image plane')
92 plot_ne.set_title(
'log(norm error)')
95 plot_ne.set_title(
'norm error')
104 plot_e.legend([
'$x_1$',
'$y_1$',
'$x_2$',
'$y_2$',
'$x_3$',
'$y_3$',
'$x_4$',
'$y_4$',])
106 for i
in range(self.
vector_v.shape[1]):
108 plot_v.legend([
'$v_x$',
'$v_y$',
'$v_z$',
'$\omega_x$',
'$\omega_y$',
'$\omega_z$'])
110 for i
in range(self.
vector_x.shape[1] // 2):
112 plot_x.legend([
'$x_1$',
'$x_2$',
'$x_3$',
'$x_4$'])
113 for i
in range(self.
vector_x.shape[1] // 2):
117 output_folder = os.path.dirname(fig_filename)
118 if not os.path.exists(output_folder):
119 os.makedirs(output_folder)
120 print(
"Create output folder: ", output_folder)
122 print(f
"Figure is saved in {fig_filename}")
123 plt.savefig(fig_filename)
126 plot_traj = plt.figure().add_subplot(projection=
'3d')
131 for i
in range(len(min_s)):
132 if (max_s[i] - min_s[i]) < 1.:
135 plot_traj.axis(xmin=min_s[0], xmax=max_s[0])
136 plot_traj.axis(ymin=min_s[1], ymax=max_s[1])
139 plot_traj.set_title(
'Camera trajectory w_t_c in world space')
141 filename = os.path.splitext(fig_filename)[0] +
"-traj-w_t_c.png"
142 print(f
"Figure is saved in {filename}")
143 plt.savefig(filename)
147if __name__ ==
'__main__':
148 parser = argparse.ArgumentParser(description=
'The script corresponding to TP 4, IBVS on 4 points.')
149 parser.add_argument(
'--initial-position', type=int, default=2, dest=
'initial_position', help=
'Initial position selection (value 1, 2, 3 or 4)')
150 parser.add_argument(
'--interaction', type=str, default=
"current", dest=
'interaction_matrix_type', help=
'Interaction matrix type (value \"current\" or \"desired\")')
151 parser.add_argument(
'--plot-log-scale', action=
'store_true', help=
'Plot norm of the error using a logarithmic scale')
152 parser.add_argument(
'--no-plot', action=
'store_true', help=
'Disable plots')
154 args, unknown_args = parser.parse_known_args()
156 print(
"The following args are not recognized and will not be used: %s" % unknown_args)
159 print(f
"Use initial position {args.initial_position}")
162 c_T_w = HomogeneousMatrix()
164 if args.initial_position == 1:
166 thetau = ThetaUVector(0.0, 0.0, 0.0)
167 c_R_w = RotationMatrix(thetau)
168 c_t_w = TranslationVector(0.0, 0.0, 1.3)
171 elif args.initial_position == 2:
173 thetau = ThetaUVector(Math.rad(10), Math.rad(20), Math.rad(30))
174 c_R_w = RotationMatrix(thetau)
175 c_t_w = TranslationVector(-0.2, -0.1, 1.3)
178 elif args.initial_position == 3:
180 thetau = ThetaUVector(0.0, 0.0, Math.rad(90))
181 c_R_w = RotationMatrix(thetau)
182 c_t_w = TranslationVector(0.0, 0.0, 1.0)
185 elif args.initial_position == 4:
187 thetau = ThetaUVector(0.0, 0.0, Math.rad(180))
188 c_R_w = RotationMatrix(thetau)
189 c_t_w = TranslationVector(0.0, 0.0, 1.0)
193 raise ValueError(f
"Wrong initial position value. Values are 1, 2, 3 or 4")
196 cd_T_w = HomogeneousMatrix()
197 thetau = ThetaUVector(0, 0, 0)
198 cd_R_w = RotationMatrix(thetau)
199 cd_t_w = TranslationVector(0.0, 0.0, 1.0)
200 cd_T_w.insert(cd_R_w)
201 cd_T_w.insert(cd_t_w)
205 wX.append(Point(-0.1, 0.1, 0.0))
206 wX.append(Point( 0.1, 0.1, 0.0))
207 wX.append(Point( 0.1, -0.1, 0.0))
208 wX.append(Point(-0.1, -0.1, 0.0))
214 for i
in range(len(wX)):
216 xd[2*i:2*i+2] = [wX[i].get_x(), wX[i].get_y()]
220 t = FeatureTranslation(FeatureTranslation.cdMc)
221 tu = FeatureThetaU(FeatureThetaU.cdRc)
222 td = FeatureTranslation(FeatureTranslation.cdMc)
223 tud = FeatureThetaU(FeatureThetaU.cdRc)
227 task.setServo(Servo.EYEINHAND_CAMERA)
229 task.addFeature(t, td)
230 task.addFeature(tu, tud)
235 while (iter == 0
or norm_e > 0.0001):
236 print(f
"---- Visual servoing iteration {iter} ----")
246 cd_T_c = cd_T_w * c_T_w.inverse()
251 for i
in range(len(wX)):
253 x[2*i:2*i+2] = [wX[i].get_x(), wX[i].get_y()]
256 if args.interaction_matrix_type ==
"current":
258 task.setInteractionMatrixType(Servo.CURRENT, Servo.PSEUDO_INVERSE)
259 elif args.interaction_matrix_type ==
"desired":
261 task.setInteractionMatrixType(Servo.DESIRED, Servo.PSEUDO_INVERSE)
263 raise ValueError(f
"Wrong interaction matrix type. Values are \"current\" or \"desired\"")
266 v = task.computeControlLaw()
268 norm_e = e.frobeniusNorm()
269 Lx = task.getInteractionMatrix()
273 plot =
PlotPbvs(e, norm_e, v, x, xd, c_T_w, args.plot_log_scale)
275 plot.stack(e, norm_e, v, x, xd, c_T_w)
278 c_T_c_delta_t = ExponentialMap.direct(v, 0.040)
281 c_T_w = c_T_c_delta_t.inverse() * c_T_w
284 print(f
"norm e: \n{norm_e}")
287 print(f
"c_T_w: \n{c_T_w}")
292 print(f
"\nConvergence achieved in {iter} iterations")
296 plot.display(
"results/fig-pbvs-four-points-initial-position-" +
str(args.initial_position) +
".png")
298 print(
"Kill the figure to quit...")
__init__(self, e, norm_e, v, x, xd, c_T_w, plot_log_scale)
display(self, fig_filename)
stack(self, e, norm_e, v, x, xd, c_T_w)