//Dentro de nbloqIII!=0
	if(maxtdins>1){
		 aj_malloc_add(ins_gone_wrong,u8int,ngrupos);
		 zeroset(ins_gone_wrong,ngrupos*sizeof(u8int));
		 aj_malloc_add(saved_tipos,char,ngrupos);
	 }

//Justo despus de matriz_Ains
		if(maxtdins>1){
		   for(uint i=0;i<ngrupos;i++){
			 if(ins_gone_wrong[i]==1/* || ins_gone_wrong[i]==3*/){	//If we enter here a second time it is more likely that there actually is a huge drift
				 uint l,ll,k;			//than an error in the iteractions that can be corrected by changing to type1 (none of these has yet happened to me)
				 k=ll=0;
				 for(uint j=0;j<i;j++){
					 l=ll;
					 ll=gx.gps_acum[j];
					 if(!grupos[j].bi) continue;
					 k+=ll-l;
				 }
			#ifdef TRACING
				 ins_wrong=1;
			#endif
				 /*if(ins_gone_wrong[i]==3){
					 saved_tipos[i]=grupos[i].tipoINS;
					 grupos[i].tipoINS=1;
					 if(bgrupocross){
						 uint kk=gx.insiemeins[i];	//this code will never get executed
						 for(uint j=0;j<ngrupos;j++){
							 if(!grupos[j].bi) continue;
							 if(gx.insiemeins[j]==kk){
								  saved_tipos[j]=saved_tipos[i];
								 grupos[j].tipoINS=1;
							 }
					 }	}
				 }*/
				 ins_gone_wrong[i]++;
				 uint indp,k1,kk;
				 indp=3*k;
				 k1=ajuste_ins(mAins+k,grupos,i,gx.gps_acum,gpss.ppio, centros,gps_a_cp,Lins+indp,&(Eins),vv/pesoinsWF,vv/pesoinsK,PRins+indp);
				 if(k1==-2) goto salida_outofmem;
				 l=ll;
				 ll=gx.gps_acum[i];
				 k1=indp+3*(ll-l);
				 for(;indp<k1;){
					 PRins[indp++]*=pesoinsWF;
					 PRins[indp++]*=pesoinsWF;
					 PRins[indp++]*=pesoinsK;
				 }
				 kk=gx.insiemeins[i];
				 if(gx.ni[i]!=infoi.ni[kk]){	//just for coherency. I don't expect this code to be ever executed
					 k+=ll-l;
					 for(uint j=i+1;j<ngrupos;j++){
						 l=ll;
						 ll=gx.gps_acum[j];
						 if(!grupos[j].bi) continue;
						 k+=ll-l;
						 if(gx.insiemeins[j]==kk){
							 ins_gone_wrong[j]=0;
							 memcpy_double(grupos[j].desplins,grupos[i].desplins,9);
							 grupos[j].derivains=grupos[i].derivains;
							 k1=3*k;
							 indp=k1-3*(ll-l);
							 matriz_Ains(mAins+k,grupos,1,gpss.ppio,centros,gx.gps_acum,gps_a_cp,Lins+indp,NULL,j);
							 for(;indp<k1;){
								 PRins[indp++]=pesoinsWF;
								 PRins[indp++]=pesoinsWF;
								 PRins[indp++]=pesoinsK;
							 }
						 }
					 }
				 }
				 FORCE_invierte=true;
		 }	 }}

int ajuste_ins(float (*mAins_g)[27], GrupoGPSINS* grupos, uint i, uint* grupos_acum, PuntoGPSINS* gpss, CentroProy* centros, uint* gps_a_cp, float* Lins, Estimador* Eins, float vvWF, float vvK, float* PRins){//Assumed at least three cc.pp. with ins coord.
	uint k,l,ll,k2;
	double MT[3][3], MMT[3][3], MD[3][3];

	ll=grupos_acum[i];
	if(i) l=grupos_acum[i-1]; else l=0;
	GrupoGPSINS* grupo=grupos+i;
	k=ll-l;

	Giro3D G,Ga;
	Giro3D* Gdif=n_malloc(Giro3D,k); if(Gdif==NULL) return -2;
	float* pf=PRins;
	Giro3D tm;
	PuntoXYZ<float> vv;
	float faux;
	double aux;

	k*=3;
	for(uint j=0;j<k;j++) pf[j]=1;

	for(uint ib=0;;ib++){
		k2=0;
		for(uint j=l;j<ll;j++){
			if(!gpss[j].bi) continue;
			mmulrot_inv(gpss[j].M,centros[gps_a_cp[j]].M,MD);
			Gdif[k2++]=Gmatriz_0_seg(MD);
		}
		G=Gmedio(Gdif,k2,(PuntoXYZ<float>*)PRins);
		MatrizRot_0(G,grupo->desplins);
		if(ib==2) break;

		vv.w=vv.fi=vv.k=0;
		for(uint j=l,k=0;j<ll;j++){
			if(!gpss[j].bi) continue;
			mmulrot_inv(centros[gps_a_cp[j]].M,gpss[j].M,MMT);
			mmulrot(grupo->desplins,MMT,MT);
			Gmatriz_aprox_rev(MT,Lins+k);
			faux=Lins[k]*Lins[k];	vv.w+=faux*pf[k++];
			faux=Lins[k]*Lins[k];	vv.fi+=faux*pf[k++];
			faux=Lins[k]*Lins[k];	vv.k+=faux*pf[k++];
		}
		vv/=k2-1;
		vv.w=sqrt(0.5F*(vv.w+vv.fi));
		vv.fi=vv.w;
		vv.k=sqrt(vv.k);
		vv/=3;
		if(vv.w<vvWF){vv.w=vvWF; vv.fi=vvWF;}
		if(vv.k<vvK) vv.k=vvK;
		for(uint j=l,k=0;j<ll;j++){
			if(!gpss[j].bi) continue;
			pf[k]=Eins->peso1(fabsf(Lins[k])/vv.w);
			pf[k+1]=Eins->peso1(fabsf(Lins[k+1])/vv.fi); k++;
			pf[k+2]=Eins->peso1(fabsf(Lins[k+2])/vv.k); k++;
		}
		if(ib<1){
			for(uint j=l,k=0;j<ll;j++){
				pf[k]*=pf[k]; k++;
				pf[k]*=pf[k]; k++;
				pf[k]*=pf[k]; k++;
		}	}
	}
	if(grupo->tipoINS==1) goto fin_calculo;

	PuntoXYZ<double>* Pins2=n_malloc(PuntoXYZ<double>,k2);
	if(Pins2==NULL){free(Gdif); return -2;}
	double* pdbl;
	k2*=3;
	pdbl=(double*)Pins2;
	for(uint j=0;j<k2;j++,pdbl++,pf++)
		*pdbl=(double)(*pf**pf);

	Mtransponer(grupo->desplins,MT);
	G.w=G.fi=G.k=0;
	tm=G;
	zeroset(Gdif,2*sizeof(Giro3D)); //Gdif ya no hace falta
	for(uint j=l,k=0;j<ll;j++,k++){
		if(!gpss[j].bi) continue;
		mmulrot_inv(gpss[j].M,centros[gps_a_cp[j]].M,MD);
		mmulrot(MD,MT,MMT);
		Ga=Gmatriz_10(MMT);	//assumed that the deriva cannot be very big
		aux=gpss[j].t;
		Ga*=aux;
		G.w+=Ga.w*Pins2[k].w;	G.fi+=Ga.fi*Pins2[k].fi;		G.k+=Ga.k*Pins2[k].k;
		tm+=Pins2[k]*aux;
		aux*=aux;
		Gdif[0]+=Pins2[k]*aux;
		Gdif[1]+=Pins2[k];
	}
	grupo->derivains.w=G.w/Gdif->w;
	grupo->derivains.fi=G.fi/Gdif->fi;
	grupo->derivains.k=G.k/Gdif->k;
	G.w=grupo->derivains.w*tm.w/Gdif[1].w;
	G.fi=grupo->derivains.fi*tm.fi/Gdif[1].fi;
	G.k=grupo->derivains.k*tm.k/Gdif[1].k;
	MatrizRot_10(G,MMT);
	mmulrot(MT,MMT,grupo->desplins);
	Minversa(grupo->desplins);
	free(Pins2);

 fin_calculo:
	free(Gdif);
	//despl y deriva calculados. Calcular ahora la matriz A y los residuos
	matriz_Ains(mAins_g,grupos,1,gpss,centros,grupos_acum,gps_a_cp,Lins,NULL,i);
	return 0;
}
