@@ -409,7 +409,12 @@ def estimate_model(self):
409409 print ("===============================================================================" )
410410 print (" Preparing Model Features " )
411411 print ("===============================================================================" )
412- self .X , self .y , self .coef_name_list = self .assemble_regression_matrices (["lin" ,"rot" ])
412+ configuration = []
413+ if self .estimate_forces :
414+ configuration .append ("lin" )
415+ if self .estimate_moments :
416+ configuration .append ("rot" )
417+ self .X , self .y , self .coef_name_list = self .assemble_regression_matrices (configuration )
413418 self .initialize_optimizer ()
414419 self .optimizer .estimate_parameters (self .X , self .y )
415420 self .generate_optimization_results ()
@@ -462,7 +467,8 @@ def generate_optimization_results(self):
462467 metrics_dict = self .optimizer .compute_optimization_metrics ()
463468 coef_list = self .optimizer .get_optimization_parameters ()
464469 model_dict = {}
465- model_dict .update (self .rotor_config_dict )
470+ if hasattr (self , 'rotor_config_dict' ):
471+ model_dict .update (self .rotor_config_dict )
466472 if hasattr (self , 'aero_config_dict' ):
467473 model_dict .update (self .aero_config_dict )
468474 self .generate_model_dict (coef_list , metrics_dict , model_dict )
@@ -481,45 +487,49 @@ def generate_optimization_results(self):
481487 def compute_residuals (self ):
482488
483489 y_pred = self .optimizer .predict (self .X )
484- _ ,y_forces ,_ = self .assemble_regression_matrices (["lin" ])
485- _ ,y_moments ,_ = self .assemble_regression_matrices (["rot" ])
486-
487- y_forces_measured = np .zeros (y_forces .shape )
488- y_forces_measured [0 ::3 ] = y_forces [0 :int (y_forces .shape [0 ]/ 3 )]
489- y_forces_measured [1 ::3 ] = y_forces [int (y_forces .shape [0 ]/ 3 ):int (2 * y_forces .shape [0 ]/ 3 )]
490- y_forces_measured [2 ::3 ] = y_forces [int (2 * y_forces .shape [0 ]/ 3 ):y_forces .shape [0 ]]
491-
492- y_forces_pred = np .zeros (y_forces .shape )
493- y_forces_pred [0 ::3 ] = y_pred [0 :int (y_forces .shape [0 ]/ 3 )]
494- y_forces_pred [1 ::3 ] = y_pred [int (y_forces .shape [0 ]/ 3 ):int (2 * y_forces .shape [0 ]/ 3 )]
495- y_forces_pred [2 ::3 ] = y_pred [int (2 * y_forces .shape [0 ]/ 3 ):y_forces .shape [0 ]]
496-
497- y_moments_measured = np .zeros (y_moments .shape )
498- y_moments_measured [0 ::3 ] = y_moments [0 :int (y_moments .shape [0 ]/ 3 )]
499- y_moments_measured [1 ::3 ] = y_moments [int (y_moments .shape [0 ]/ 3 ):int (2 * y_moments .shape [0 ]/ 3 )]
500- y_moments_measured [2 ::3 ] = y_moments [int (2 * y_moments .shape [0 ]/ 3 ):y_moments .shape [0 ]]
501-
502- y_moments_pred = np .zeros (y_moments .shape )
503- y_moments_pred [0 ::3 ] = y_pred [y_moments .shape [0 ]:int (4 * y_moments .shape [0 ]/ 3 )]
504- y_moments_pred [1 ::3 ] = y_pred [int (4 * y_moments .shape [0 ]/ 3 ):int (5 * y_moments .shape [0 ]/ 3 )]
505- y_moments_pred [2 ::3 ] = y_pred [int (5 * y_moments .shape [0 ]/ 3 ):]
506-
507- error_y_forces = y_forces_pred - y_forces_measured
508- error_y_moments = y_moments_pred - y_moments_measured
509-
510- stacked_error_y_forces = np .array (error_y_forces )
511- acc_mat = stacked_error_y_forces .reshape ((- 1 , 3 ))
512- residual_force_df = pd .DataFrame (acc_mat , columns = [
513- "residual_force_x" , "residual_force_y" , "residual_force_z" ])
514- self .data_df = pd .concat (
515- [self .data_df , residual_force_df ], axis = 1 , join = "inner" ).reindex (self .data_df .index )
490+ if self .estimate_forces :
491+ _ ,y_forces ,_ = self .assemble_regression_matrices (["lin" ])
492+ y_forces_measured = np .zeros (y_forces .shape )
493+ y_forces_measured [0 ::3 ] = y_forces [0 :int (y_forces .shape [0 ]/ 3 )]
494+ y_forces_measured [1 ::3 ] = y_forces [int (y_forces .shape [0 ]/ 3 ):int (2 * y_forces .shape [0 ]/ 3 )]
495+ y_forces_measured [2 ::3 ] = y_forces [int (2 * y_forces .shape [0 ]/ 3 ):y_forces .shape [0 ]]
516496
517- stacked_error_y_moments = np .array (error_y_moments )
518- mom_mat = stacked_error_y_moments .reshape ((- 1 , 3 ))
519- residual_moment_df = pd .DataFrame (mom_mat , columns = [
520- "residual_moment_x" , "residual_moment_y" , "residual_moment_z" ])
521- self .data_df = pd .concat (
522- [self .data_df , residual_moment_df ], axis = 1 , join = "inner" ).reindex (self .data_df .index )
497+ y_forces_pred = np .zeros (y_forces .shape )
498+ y_forces_pred [0 ::3 ] = y_pred [0 :int (y_forces .shape [0 ]/ 3 )]
499+ y_forces_pred [1 ::3 ] = y_pred [int (y_forces .shape [0 ]/ 3 ):int (2 * y_forces .shape [0 ]/ 3 )]
500+ y_forces_pred [2 ::3 ] = y_pred [int (2 * y_forces .shape [0 ]/ 3 ):y_forces .shape [0 ]]
501+
502+ error_y_forces = y_forces_pred - y_forces_measured
503+
504+ stacked_error_y_forces = np .array (error_y_forces )
505+ acc_mat = stacked_error_y_forces .reshape ((- 1 , 3 ))
506+ residual_force_df = pd .DataFrame (acc_mat , columns = [
507+ "residual_force_x" , "residual_force_y" , "residual_force_z" ])
508+ self .data_df = pd .concat (
509+ [self .data_df , residual_force_df ], axis = 1 , join = "inner" ).reindex (self .data_df .index )
510+
511+ if self .estimate_moments :
512+ _ ,y_moments ,_ = self .assemble_regression_matrices (["rot" ])
513+
514+ y_moments_measured = np .zeros (y_moments .shape )
515+ y_moments_measured [0 ::3 ] = y_moments [0 :int (y_moments .shape [0 ]/ 3 )]
516+ y_moments_measured [1 ::3 ] = y_moments [int (y_moments .shape [0 ]/ 3 ):int (2 * y_moments .shape [0 ]/ 3 )]
517+ y_moments_measured [2 ::3 ] = y_moments [int (2 * y_moments .shape [0 ]/ 3 ):y_moments .shape [0 ]]
518+
519+ y_moments_pred = np .zeros (y_moments .shape )
520+ y_moments_pred [0 ::3 ] = y_pred [y_moments .shape [0 ]:int (4 * y_moments .shape [0 ]/ 3 )]
521+ y_moments_pred [1 ::3 ] = y_pred [int (4 * y_moments .shape [0 ]/ 3 ):int (5 * y_moments .shape [0 ]/ 3 )]
522+ y_moments_pred [2 ::3 ] = y_pred [int (5 * y_moments .shape [0 ]/ 3 ):]
523+
524+ error_y_moments = y_moments_pred - y_moments_measured
525+
526+
527+ stacked_error_y_moments = np .array (error_y_moments )
528+ mom_mat = stacked_error_y_moments .reshape ((- 1 , 3 ))
529+ residual_moment_df = pd .DataFrame (mom_mat , columns = [
530+ "residual_moment_x" , "residual_moment_y" , "residual_moment_z" ])
531+ self .data_df = pd .concat (
532+ [self .data_df , residual_moment_df ], axis = 1 , join = "inner" ).reindex (self .data_df .index )
523533
524534 def plot_model_predicitons (self ):
525535
@@ -533,9 +543,14 @@ def plot_scatter(ax, title, dataframe_x, dataframe_y, dataframe_z, color='blue')
533543
534544 y_pred = self .optimizer .predict (self .X )
535545
536- if (self .estimate_forces and self .estimate_moments ):
546+ fig = plt .figure ("Residual Visualization" )
547+
548+ model_plots .plot_airspeed_and_AoA (
549+ self .data_df [["V_air_body_x" , "V_air_body_y" , "V_air_body_z" , "angle_of_attack" ]], self .data_df ["timestamp" ])
550+
551+ if (self .estimate_forces ):
537552 _ ,y_forces ,_ = self .assemble_regression_matrices (["lin" ])
538- _ , y_moments , _ = self . assemble_regression_matrices ([ "rot" ])
553+
539554 y_forces_measured = np .zeros (y_forces .shape )
540555 y_forces_measured [0 ::3 ] = y_forces [0 :int (y_forces .shape [0 ]/ 3 )]
541556 y_forces_measured [1 ::3 ] = y_forces [int (y_forces .shape [0 ]/ 3 ):int (2 * y_forces .shape [0 ]/ 3 )]
@@ -546,6 +561,19 @@ def plot_scatter(ax, title, dataframe_x, dataframe_y, dataframe_z, color='blue')
546561 y_forces_pred [1 ::3 ] = y_pred [int (y_forces .shape [0 ]/ 3 ):int (2 * y_forces .shape [0 ]/ 3 )]
547562 y_forces_pred [2 ::3 ] = y_pred [int (2 * y_forces .shape [0 ]/ 3 ):y_forces .shape [0 ]]
548563
564+ model_plots .plot_force_predictions (
565+ y_forces_measured , y_forces_pred , self .data_df ["timestamp" ])
566+
567+ ax1 = fig .add_subplot (2 , 2 , 1 , projection = '3d' )
568+ plot_scatter (ax1 , "Residual forces [N]" , "residual_force_x" ,
569+ "residual_force_y" , "residual_force_z" , 'blue' )
570+ ax3 = fig .add_subplot (2 , 2 , 3 , projection = '3d' )
571+ plot_scatter (ax3 , "Measured Forces [N]" ,
572+ "measured_force_x" , "measured_force_y" , "measured_force_z" , 'blue' )
573+
574+ if (self .estimate_moments ):
575+ _ ,y_moments ,_ = self .assemble_regression_matrices (["rot" ])
576+
549577 y_moments_measured = np .zeros (y_moments .shape )
550578 y_moments_measured [0 ::3 ] = y_moments [0 :int (y_moments .shape [0 ]/ 3 )]
551579 y_moments_measured [1 ::3 ] = y_moments [int (y_moments .shape [0 ]/ 3 ):int (2 * y_moments .shape [0 ]/ 3 )]
@@ -556,46 +584,18 @@ def plot_scatter(ax, title, dataframe_x, dataframe_y, dataframe_z, color='blue')
556584 y_moments_pred [1 ::3 ] = y_pred [int (4 * y_moments .shape [0 ]/ 3 ):int (5 * y_moments .shape [0 ]/ 3 )]
557585 y_moments_pred [2 ::3 ] = y_pred [int (5 * y_moments .shape [0 ]/ 3 ):]
558586
559- model_plots .plot_force_predictions (
560- y_forces_measured , y_forces_pred , self .data_df ["timestamp" ])
561- model_plots .plot_moment_predictions (
562- y_moments_measured , y_moments_pred , self .data_df ["timestamp" ])
563- model_plots .plot_airspeed_and_AoA (
564- self .data_df [["V_air_body_x" , "V_air_body_y" , "V_air_body_z" , "angle_of_attack" ]], self .data_df ["timestamp" ])
565-
566- elif (self .estimate_forces ):
567- y_forces_pred = y_pred
568- model_plots .plot_force_predictions (
569- y_forces_measured , y_forces_pred , self .data_df ["timestamp" ])
570- model_plots .plot_airspeed_and_AoA (
571- self .data_df [["V_air_body_x" , "V_air_body_y" , "V_air_body_z" , "angle_of_attack" ]], self .data_df ["timestamp" ])
572-
573- elif (self .estimate_moments ):
574- y_moments_pred = y_pred
575587 model_plots .plot_moment_predictions (
576588 y_moments_measured , y_moments_pred , self .data_df ["timestamp" ])
577- model_plots .plot_airspeed_and_AoA (
578- self .data_df [["V_air_body_x" , "V_air_body_y" , "V_air_body_z" , "angle_of_attack" ]], self .data_df ["timestamp" ])
579-
580- fig = plt .figure ("Residual Visualization" )
581- ax1 = fig .add_subplot (2 , 2 , 1 , projection = '3d' )
582- plot_scatter (ax1 , "Residual forces [N]" , "residual_force_x" ,
583- "residual_force_y" , "residual_force_z" , 'blue' )
584-
585- ax2 = fig .add_subplot (2 , 2 , 2 , projection = '3d' )
586-
587- plot_scatter (ax2 , "Residual Moments [Nm]" , "residual_moment_x" ,
588- "residual_moment_y" , "residual_moment_z" , 'blue' )
589589
590- ax3 = fig .add_subplot (2 , 2 , 3 , projection = '3d' )
590+ ax2 = fig .add_subplot (2 , 2 , 2 , projection = '3d' )
591591
592- plot_scatter (ax3 , "Measured Forces [N] " ,
593- "measured_force_x" , "measured_force_y " , "measured_force_z " , 'blue' )
592+ plot_scatter (ax2 , "Residual Moments [Nm]" , "residual_moment_x " ,
593+ "residual_moment_y " , "residual_moment_z " , 'blue' )
594594
595- ax4 = fig .add_subplot (2 , 2 , 4 , projection = '3d' )
595+ ax4 = fig .add_subplot (2 , 2 , 4 , projection = '3d' )
596596
597- plot_scatter (ax4 , "Measured Moments [Nm]" ,
598- "measured_moment_x" , "measured_moment_y" , "measured_moment_z" , 'blue' )
597+ plot_scatter (ax4 , "Measured Moments [Nm]" ,
598+ "measured_moment_x" , "measured_moment_y" , "measured_moment_z" , 'blue' )
599599
600600 linear_model_plots .plot_covariance_mat (self .X , self .coef_name_list )
601601
0 commit comments