Latest changes without errors

Dependents:   SNOCC_V1 SNOCC_V2

Committer:
gstedile
Date:
Mon May 15 22:52:28 2017 +0000
Revision:
9:c17042fc1c98
Parent:
8:8b37dcdc2b36
Child:
10:08e1dc33199e
SNOCC_V2 with SD

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gstedile 0:9faff39f9aa2 1 /* VCO DATA Library
gstedile 0:9faff39f9aa2 2 * Copyright (c) 2008-2010, sford
gstedile 0:9faff39f9aa2 3 *
gstedile 0:9faff39f9aa2 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
gstedile 0:9faff39f9aa2 5 * of this software and associated documentation files (the "Software"), to deal
gstedile 0:9faff39f9aa2 6 * in the Software without restriction, including without limitation the rights
gstedile 0:9faff39f9aa2 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
gstedile 0:9faff39f9aa2 8 * copies of the Software, and to permit persons to whom the Software is
gstedile 0:9faff39f9aa2 9 * furnished to do so, subject to the following conditions:
gstedile 0:9faff39f9aa2 10 *
gstedile 0:9faff39f9aa2 11 * The above copyright notice and this permission notice shall be included in
gstedile 0:9faff39f9aa2 12 * all copies or substantial portions of the Software.
gstedile 0:9faff39f9aa2 13 *
gstedile 0:9faff39f9aa2 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
gstedile 0:9faff39f9aa2 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
gstedile 0:9faff39f9aa2 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
gstedile 0:9faff39f9aa2 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
gstedile 0:9faff39f9aa2 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
gstedile 0:9faff39f9aa2 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
gstedile 0:9faff39f9aa2 20 * THE SOFTWARE.
gstedile 0:9faff39f9aa2 21 */
gstedile 1:9a2a94ffbffb 22
gstedile 0:9faff39f9aa2 23 #include "VCODATA.h"
gstedile 5:cec68064dda8 24
gstedile 1:9a2a94ffbffb 25 //#include <math.h>
gstedile 1:9a2a94ffbffb 26
gstedile 0:9faff39f9aa2 27
gstedile 0:9faff39f9aa2 28 /*############################################################################
gstedile 0:9faff39f9aa2 29 ##############################################################################*/
gstedile 0:9faff39f9aa2 30
gstedile 0:9faff39f9aa2 31
gstedile 0:9faff39f9aa2 32
gstedile 7:302b432beab9 33 //---------------------------------------------------------------------------------------------------------------------------------------
gstedile 7:302b432beab9 34 /* CONSTRUCTORES: */
gstedile 0:9faff39f9aa2 35
gstedile 7:302b432beab9 36 VCODATA::VCODATA(NAVDATA InitData, int Vel_Max){
gstedile 8:8b37dcdc2b36 37 vel_max= Vel_Max; // Velocidad máxima.
gstedile 7:302b432beab9 38 DeltaV=1;
gstedile 8:8b37dcdc2b36 39 InitData.paddata(); // Inicializamos el vector LAST_NAV_DATA con valores default. Las constantes Klong, Klat; Ksen y ZH no se modifican.
gstedile 8:8b37dcdc2b36 40 NAV_DATA = new NAVDATA[vel_max+1]; // Array de "vel_max+1" elementos tipo NAVDATA. Posicion 101 para el Objeto a validar.
gstedile 7:302b432beab9 41 for (int i=0;i<=vel_max;i+=1)
gstedile 8:8b37dcdc2b36 42 this->NAV_DATA[i]= InitData; // Inicializa NAV_DATA[]. Carga el array repitiendo Initdata en todas las posiciones.
gstedile 0:9faff39f9aa2 43 }
gstedile 0:9faff39f9aa2 44
gstedile 8:8b37dcdc2b36 45 VCODATA::VCODATA(const VCODATA &VCOOBJ){ // Cosntructor copia.
gstedile 8:8b37dcdc2b36 46 vel_max=VCOOBJ.vel_max;
gstedile 8:8b37dcdc2b36 47 DeltaV=1;
gstedile 8:8b37dcdc2b36 48 NAV_DATA = new NAVDATA[vel_max+1]; // Array de "vel_max+1" elementos tipo NAVDATA. Posicion 101 para el Objeto a validar.
gstedile 8:8b37dcdc2b36 49 for (int i=0;i<=vel_max;i+=1)
gstedile 8:8b37dcdc2b36 50 this->NAV_DATA[i]= VCOOBJ.NAV_DATA[i]; // Copio todos los objetos NAV_DATA del VCOOBJ a este.
gstedile 8:8b37dcdc2b36 51 }
gstedile 8:8b37dcdc2b36 52
gstedile 8:8b37dcdc2b36 53
gstedile 7:302b432beab9 54 //---------------------------------------------------------------------------------------------------------------------------------------
gstedile 7:302b432beab9 55 //store_data (NAVDATA LastData): Almacena el objeto LastData
gstedile 3:75e22a2e2109 56
gstedile 3:75e22a2e2109 57 void VCODATA::store_data (NAVDATA LastData){
gstedile 7:302b432beab9 58
gstedile 7:302b432beab9 59 if (fabs(this->NAV_DATA[vel_max].LAST_NAV_DATA[speed_p] - LastData.LAST_NAV_DATA[speed_p])< this->DeltaV){
gstedile 7:302b432beab9 60
gstedile 7:302b432beab9 61 this->merge_data(LastData); // Combina los datos del actual con el anterior y los deja en la posicion [vel_max].
gstedile 7:302b432beab9 62 this->NAV_DATA[int(LastData.LAST_NAV_DATA[speed_p])] = this->NAV_DATA[vel_max]; // Carga el objeto en NAV_DATA tomando como índice a la parte entera de la velocidad.
gstedile 7:302b432beab9 63 }
gstedile 7:302b432beab9 64 else this->NAV_DATA[vel_max]=LastData; // Cargo el entrante en la posicion [vel_max], reemplazando al anterior.
gstedile 7:302b432beab9 65
gstedile 7:302b432beab9 66 }
gstedile 7:302b432beab9 67
gstedile 7:302b432beab9 68
gstedile 7:302b432beab9 69
gstedile 3:75e22a2e2109 70
gstedile 7:302b432beab9 71
gstedile 4:af09ad305303 72
gstedile 7:302b432beab9 73 //---------------------------------------------------------------------------------------------------------------------------------------
gstedile 7:302b432beab9 74 /* get_VCO(): Obtiene la Velocidad Crucero Optima (VCO)*/
gstedile 4:af09ad305303 75
gstedile 5:cec68064dda8 76 int VCODATA::get_VCO(){
gstedile 5:cec68064dda8 77 int GET_Min=0;
gstedile 7:302b432beab9 78 enum find {NO, SI, POSIBLE};
gstedile 8:8b37dcdc2b36 79 int Ratio_Min=6; // Entorno de evaluación de Máximos / Mínimos.
gstedile 5:cec68064dda8 80 int n_events_eps=0; // Cantidad de valores de v menores al Minimo (o mayores al Máximo) dentro del entorno Ratio_Min para evaluar validez de Minimo (o Maximo segun sea el caso).
gstedile 8:8b37dcdc2b36 81 int n_events_critical=3; //Cantidad de ocurrencias para considerar la invalidéz del mínimo (o máximo) hallado;
gstedile 8:8b37dcdc2b36 82 float ConsMin=100; // Consumo mínimo inicial.
gstedile 8:8b37dcdc2b36 83 float ConsMAX=0; // Consumo máximo inicial.
gstedile 5:cec68064dda8 84 int VCO=-1;
gstedile 7:302b432beab9 85 find GET_MAX=NO;
gstedile 5:cec68064dda8 86
gstedile 7:302b432beab9 87 for (int vel=0;vel<vel_max;vel++){
gstedile 8:8b37dcdc2b36 88 if(GET_MAX==SI){ // Si halle el maximo y
gstedile 8:8b37dcdc2b36 89 if(GET_Min == 0){ // no encontré el Minimo. (Aun no halle la VCO)
gstedile 6:d575bd17b617 90 if (this->NAV_DATA[vel].LAST_NAV_DATA[cons_mile_p]<=ConsMin){ //La curva sigue decreciendo
gstedile 5:cec68064dda8 91 ConsMin=this->NAV_DATA[vel].LAST_NAV_DATA[cons_mile_p];
gstedile 5:cec68064dda8 92 }
gstedile 5:cec68064dda8 93 else{
gstedile 9:c17042fc1c98 94 int vel2=0;
gstedile 9:c17042fc1c98 95 float ConsMin2=0;
gstedile 9:c17042fc1c98 96 n_events_eps=0;
gstedile 5:cec68064dda8 97 for (int eps=1; eps < Ratio_Min;eps++){
gstedile 6:d575bd17b617 98 if (this->NAV_DATA[vel+eps].LAST_NAV_DATA[cons_mile_p]<=ConsMin) {//hay valores menores al minimo hallado en un entorno de v?
gstedile 5:cec68064dda8 99 n_events_eps++;
gstedile 9:c17042fc1c98 100 if (n_events_eps==1){
gstedile 9:c17042fc1c98 101 ConsMin2=this->NAV_DATA[vel+eps].LAST_NAV_DATA[cons_mile_p];
gstedile 9:c17042fc1c98 102 vel2=vel+eps;
gstedile 9:c17042fc1c98 103 }
gstedile 5:cec68064dda8 104 }
gstedile 8:8b37dcdc2b36 105 }
gstedile 9:c17042fc1c98 106 if (n_events_eps >= n_events_critical){ // falso minimo (hay muchos valores menores al minimo hallado)
gstedile 9:c17042fc1c98 107 ConsMin=ConsMin2;
gstedile 9:c17042fc1c98 108 vel=vel2; // nueva ubicación del minimo
gstedile 9:c17042fc1c98 109 }
gstedile 8:8b37dcdc2b36 110 else {
gstedile 5:cec68064dda8 111 GET_Min=1;
gstedile 5:cec68064dda8 112 VCO=vel-1;
gstedile 8:8b37dcdc2b36 113 }
gstedile 5:cec68064dda8 114 }
gstedile 5:cec68064dda8 115 }
gstedile 5:cec68064dda8 116 }
gstedile 5:cec68064dda8 117
gstedile 5:cec68064dda8 118 else{
gstedile 8:8b37dcdc2b36 119 if (this->NAV_DATA[vel].LAST_NAV_DATA[cons_mile_p]>=ConsMAX){ //La curva sigue creciendo o se mantiene cte.
gstedile 7:302b432beab9 120 ConsMAX=this->NAV_DATA[vel].LAST_NAV_DATA[cons_mile_p];
gstedile 7:302b432beab9 121 GET_MAX=POSIBLE;
gstedile 5:cec68064dda8 122 }
gstedile 5:cec68064dda8 123 else{
gstedile 9:c17042fc1c98 124 n_events_eps=0;
gstedile 9:c17042fc1c98 125 float ConsMAX2=0;
gstedile 7:302b432beab9 126 if (GET_MAX==POSIBLE){
gstedile 9:c17042fc1c98 127 int vel2=0;
gstedile 5:cec68064dda8 128 for (int eps=1; eps<Ratio_Min;eps++){
gstedile 5:cec68064dda8 129 if (this->NAV_DATA[vel+eps].LAST_NAV_DATA[cons_mile_p]>ConsMAX) {//hay valores mayores al maximo hallado en un entorno de v?
gstedile 9:c17042fc1c98 130 n_events_eps++;
gstedile 9:c17042fc1c98 131 if (n_events_eps==1){
gstedile 9:c17042fc1c98 132 ConsMAX2=this->NAV_DATA[vel+eps].LAST_NAV_DATA[cons_mile_p];
gstedile 9:c17042fc1c98 133 vel2=vel+eps;
gstedile 5:cec68064dda8 134 }
gstedile 5:cec68064dda8 135 }
gstedile 9:c17042fc1c98 136 }
gstedile 9:c17042fc1c98 137 if (n_events_eps > n_events_critical) { // falso maximo (hay muchos valores mayores al maximo hallado)
gstedile 9:c17042fc1c98 138 vel=vel2; // nueva ubicación del maximo siguiente
gstedile 9:c17042fc1c98 139 ConsMAX=ConsMAX2;
gstedile 9:c17042fc1c98 140 }
gstedile 7:302b432beab9 141 else GET_MAX=SI;
gstedile 9:c17042fc1c98 142
gstedile 9:c17042fc1c98 143
gstedile 7:302b432beab9 144 }
gstedile 5:cec68064dda8 145 }
gstedile 5:cec68064dda8 146 }
gstedile 5:cec68064dda8 147
gstedile 5:cec68064dda8 148 }
gstedile 5:cec68064dda8 149
gstedile 9:c17042fc1c98 150 return (VCO);
gstedile 9:c17042fc1c98 151
gstedile 7:302b432beab9 152 }
gstedile 7:302b432beab9 153
gstedile 7:302b432beab9 154 //---------------------------------------------------------------------------------------------------------------------------------------
gstedile 7:302b432beab9 155 //interpolate(): Interpola los valores de consumo para completar la curva.
gstedile 7:302b432beab9 156
gstedile 7:302b432beab9 157 void VCODATA::interpolate(){
gstedile 7:302b432beab9 158 int x_P1=0;//this->get_next_P(0);
gstedile 7:302b432beab9 159 int x_P2=this->get_next_P(x_P1);
gstedile 7:302b432beab9 160 while (x_P2>0 ) { // Puntos validos? (Si es no válido get_next devuelve -1).
gstedile 7:302b432beab9 161 if ( x_P2>x_P1+1) this->interp_x1_x2(x_P1, x_P2); // Interpola entre los 2 puntos dados.
gstedile 7:302b432beab9 162 x_P1=x_P2;
gstedile 7:302b432beab9 163 x_P2=this->get_next_P(x_P2);
gstedile 7:302b432beab9 164 }
gstedile 7:302b432beab9 165 }
gstedile 7:302b432beab9 166
gstedile 8:8b37dcdc2b36 167 //---------------------------------------------------------------------------------------------------------------------------------------
gstedile 8:8b37dcdc2b36 168 //get_next_P(int x_value): Retorna la ordenada del siguiente valor recolectado, que no es resultado de la interpolacion.
gstedile 7:302b432beab9 169
gstedile 7:302b432beab9 170 int VCODATA::get_next_P(int x_value){
gstedile 7:302b432beab9 171 int i=1;
gstedile 7:302b432beab9 172 int j=i+x_value;
gstedile 7:302b432beab9 173 while (j<=vel_max){
gstedile 7:302b432beab9 174 if ( this->NAV_DATA[j].LAST_NAV_DATA[cons_mile_p] <=0 || this->NAV_DATA[j].LAST_NAV_DATA[cons_interpolated] == 1) j++; // Avanzar mientras haya valores ya interpolados, nulos, o -1 (caso de distancia recorrida nula-->0 milla)
gstedile 7:302b432beab9 175 else break;
gstedile 7:302b432beab9 176 }
gstedile 7:302b432beab9 177 if (j>vel_max)return(-1); // Llego al final sin hallar punto válido.
gstedile 7:302b432beab9 178 else return(j);
gstedile 7:302b432beab9 179 }
gstedile 7:302b432beab9 180
gstedile 8:8b37dcdc2b36 181 //---------------------------------------------------------------------------------------------------------------------------------------
gstedile 8:8b37dcdc2b36 182 //interp_x1_x2(int x1,int x2): Interpola la matríz de datos tomando puntos de la recta que pasa por x1 y x2
gstedile 8:8b37dcdc2b36 183
gstedile 7:302b432beab9 184 void VCODATA::interp_x1_x2(int x1,int x2){
gstedile 7:302b432beab9 185 float step=(this->NAV_DATA[x2].LAST_NAV_DATA[cons_mile_p] - this->NAV_DATA[x1].LAST_NAV_DATA[cons_mile_p])/(x2-x1); // Pendiente: A
gstedile 7:302b432beab9 186 for (int i=x1+1; i<x2; i++){
gstedile 7:302b432beab9 187 this->NAV_DATA[i].LAST_NAV_DATA[cons_mile_p]= (i-x1)*step + this->NAV_DATA[x1].LAST_NAV_DATA[cons_mile_p]; // Y= Ax + B
gstedile 7:302b432beab9 188 this->NAV_DATA[i].LAST_NAV_DATA[cons_interpolated]=1;
gstedile 7:302b432beab9 189 }
gstedile 7:302b432beab9 190 }
gstedile 7:302b432beab9 191
gstedile 8:8b37dcdc2b36 192 //---------------------------------------------------------------------------------------------------------------------------------------
gstedile 8:8b37dcdc2b36 193 //merge_data(NAVDATA LastVector): Modifica los valores del array LAST_NAV_DATA del objeto almacenado en la ultima posicion de NAV_DATA,
gstedile 8:8b37dcdc2b36 194 // combinándolos con LastVector.
gstedile 8:8b37dcdc2b36 195
gstedile 7:302b432beab9 196
gstedile 7:302b432beab9 197 void VCODATA::merge_data(NAVDATA LastVector){
gstedile 7:302b432beab9 198 // El ultimo vector se guarda para validar el siguiente. El mismo ya contiene los promedios. Puede evaluarse dejar siempre los últimos valores en vez del promedio.
gstedile 7:302b432beab9 199 // El valor que se almacena en la matriz, siempre es el promedio del último vector guardado con el recientemente ingresado.
gstedile 7:302b432beab9 200 this->NAV_DATA[vel_max].LAST_NAV_DATA[longitude_f]=LastVector.LAST_NAV_DATA[longitude_f];
gstedile 7:302b432beab9 201 this->NAV_DATA[vel_max].LAST_NAV_DATA[latitude_f]=LastVector.LAST_NAV_DATA[latitude_f];
gstedile 7:302b432beab9 202 this->NAV_DATA[vel_max].LAST_NAV_DATA[time_f]=LastVector.LAST_NAV_DATA[time_f];
gstedile 7:302b432beab9 203 this->NAV_DATA[vel_max].LAST_NAV_DATA[distance_p]+=LastVector.LAST_NAV_DATA[distance_p];
gstedile 7:302b432beab9 204 this->NAV_DATA[vel_max].LAST_NAV_DATA[speed_p]=(this->NAV_DATA[vel_max].LAST_NAV_DATA[speed_p] + LastVector.LAST_NAV_DATA[speed_p])/2; //Promedio de velocidades;
gstedile 7:302b432beab9 205 this->NAV_DATA[vel_max].LAST_NAV_DATA[consumption_f]=LastVector.LAST_NAV_DATA[consumption_f];
gstedile 7:302b432beab9 206 this->NAV_DATA[vel_max].LAST_NAV_DATA[consumption_p]+=LastVector.LAST_NAV_DATA[consumption_p];
gstedile 7:302b432beab9 207 this->NAV_DATA[vel_max].LAST_NAV_DATA[cons_mile_p]= (LastVector.LAST_NAV_DATA[cons_mile_p]+this->NAV_DATA[vel_max].LAST_NAV_DATA[cons_mile_p])/2; //Promedio-->Evaluar recalcular en base a los otros datos.
gstedile 7:302b432beab9 208 this->NAV_DATA[vel_max].LAST_NAV_DATA[cons_hour_p]=(LastVector.LAST_NAV_DATA[cons_hour_p]+this->NAV_DATA[vel_max].LAST_NAV_DATA[cons_hour_p])/2; //Promedio-->Evaluar recalcular en base a los otros datos. ;
gstedile 7:302b432beab9 209 this->NAV_DATA[vel_max].LAST_NAV_DATA[cons_interpolated]=0;
gstedile 7:302b432beab9 210 }
gstedile 7:302b432beab9 211
gstedile 8:8b37dcdc2b36 212 //---------------------------------------------------------------------------------------------------------------------------------------
gstedile 8:8b37dcdc2b36 213 // smooth(int n_dots,VCODATA SMOOTH_MTRX): Suaviza la curva discreta, promediando n puntos del entorno de cada punto.
gstedile 8:8b37dcdc2b36 214 // SMOOTH_MTRX es una copia de esta matríz (this) la cual resultará suavizada.
gstedile 8:8b37dcdc2b36 215
gstedile 8:8b37dcdc2b36 216 void VCODATA::smooth(int n_dots,VCODATA &REFERENCE_MTRX){
gstedile 8:8b37dcdc2b36 217 int n_int=int (n_dots/2);
gstedile 8:8b37dcdc2b36 218 int n_dif_l=0; // Valor para sesgar el entorno de promediado, respecto de la posicion actual, en caso de n par.
gstedile 8:8b37dcdc2b36 219 if ((n_dots%n_int)==0)n_dif_l=1; // si n es par entonces tomo una muestra menos del lado derecho. Elijo esta forma porque
gstedile 8:8b37dcdc2b36 220 // al discretizar la curva hemos redondeado hacia abajo los valores de velocidad; esto significa que el
gstedile 8:8b37dcdc2b36 221 // valor de consumo asociado a una velocidad fue desplazado hacia la izquierda, por lo tanto, promediandolo
gstedile 8:8b37dcdc2b36 222 // con valores corresp. a velocidades con cierto sesgo hacia izquierda, mejora la representación y mas aún
gstedile 8:8b37dcdc2b36 223 // con respecto al caso opuesto. Debe pensarse estadisticamente teniendo en cuenta que
gstedile 8:8b37dcdc2b36 224 // la media de cada periodo de velocidades se encuentra en el medio del período. Ejemplo:
gstedile 8:8b37dcdc2b36 225 // | c1 c3
gstedile 8:8b37dcdc2b36 226 // | cm12
gstedile 8:8b37dcdc2b36 227 // | c2
gstedile 8:8b37dcdc2b36 228 // |__x1________xm12_x2__________x3 vemos que el valor real de velocidad de xm12 es mas cercano a x2 que el real de c2.
gstedile 8:8b37dcdc2b36 229 for (int j=0;j<vel_max;j++){
gstedile 8:8b37dcdc2b36 230 float sum_cons=0;
gstedile 8:8b37dcdc2b36 231 int n_samp=0;
gstedile 8:8b37dcdc2b36 232 this->NAV_DATA[j]=REFERENCE_MTRX.NAV_DATA[j]; // Copia de objetos NAVDATA
gstedile 8:8b37dcdc2b36 233 for (int i=-n_int;i<=n_int-n_dif_l;i++){// si es impar va desde (n-1)/2 muestras a la izq, la propia muestra y (n-1)/2 muestras a la deracha.
gstedile 8:8b37dcdc2b36 234 // si es par reduce una muestra a la derecha. (n/2) a izq, la propia y n/2-1 a derecha.
gstedile 8:8b37dcdc2b36 235 if (j+i>=0 && j+i<vel_max){ // para excluir valores de velocidad fuera de rango. (extremos)
gstedile 8:8b37dcdc2b36 236 n_samp++;
gstedile 8:8b37dcdc2b36 237 sum_cons+= REFERENCE_MTRX.NAV_DATA[i+j].LAST_NAV_DATA[cons_mile_p];
gstedile 8:8b37dcdc2b36 238 }
gstedile 8:8b37dcdc2b36 239 }
gstedile 8:8b37dcdc2b36 240 if (n_samp>0){
gstedile 8:8b37dcdc2b36 241
gstedile 8:8b37dcdc2b36 242 this->NAV_DATA[j].LAST_NAV_DATA[cons_mile_p]= sum_cons/n_samp;
gstedile 8:8b37dcdc2b36 243 this->NAV_DATA[j].LAST_NAV_DATA[cons_interpolated]=2; // 2: Valor promediado.
gstedile 8:8b37dcdc2b36 244 }
gstedile 7:302b432beab9 245
gstedile 8:8b37dcdc2b36 246
gstedile 8:8b37dcdc2b36 247 }
gstedile 8:8b37dcdc2b36 248 }