@@ -32,7 +32,7 @@ from libcpp cimport bool
3232# Local imports
3333from radarsimpy.includes.radarsimc cimport (
3434 Transmitter, Receiver, TxChannel, RxChannel,
35- Radar, Target, Point, Mem_Copy, Mem_Copy_Vec3,
35+ Radar, Target, Point, TargetsManager, Mem_Copy, Mem_Copy_Vec3,
3636 Mem_Copy_Complex, IsFreeTier
3737)
3838from radarsimpy.includes.rsvector cimport Vec3
@@ -859,6 +859,185 @@ cdef Target[float_t] cp_Target(radar,
859859 mu_c,
860860 < bool > target.get(" skip_diffusion" , False ))
861861
862+
863+ @ cython.cdivision (True )
864+ @ cython.boundscheck (False )
865+ @ cython.wraparound (False )
866+ cdef void cp_AddTarget(radar,
867+ target,
868+ timestamp,
869+ mesh_module,
870+ TargetsManager[float_t] * targets_manager):
871+ """
872+ cp_Target((radar, target, ts_shape)
873+
874+ Creat Target object in Cython
875+
876+ :param Radar radar:
877+ Radar object
878+ :param dict target:
879+ Target properties
880+ :param tuple ts_shape:
881+ Shape of the time matrix
882+
883+ :return: C++ object of a target
884+ :rtype: Target
885+ """
886+ # vector of location, speed, rotation, rotation rate
887+ cdef vector[Vec3[float_t]] loc_vt
888+ cdef vector[Vec3[float_t]] spd_vt
889+ cdef vector[Vec3[float_t]] rot_vt
890+ cdef vector[Vec3[float_t]] rrt_vt
891+
892+ cdef float_t[:, :, :] locx_mv, locy_mv, locz_mv
893+ cdef float_t[:, :, :] spdx_mv, spdy_mv, spdz_mv
894+ cdef float_t[:, :, :] rotx_mv, roty_mv, rotz_mv
895+ cdef float_t[:, :, :] rrtx_mv, rrty_mv, rrtz_mv
896+
897+ cdef cpp_complex[float_t] ep_c, mu_c
898+
899+ cdef int_t ch_idx, ps_idx, sp_idx
900+ ts_shape = np.shape(timestamp)
901+ cdef int_t bbsize_c = < int_t> (ts_shape[0 ]* ts_shape[1 ]* ts_shape[2 ])
902+
903+ cdef float_t scale
904+ cdef float_t[:, :] points_mv
905+ cdef int_t[:, :] cells_mv
906+
907+ # Enhanced mesh validation and loading with improved error messages
908+ unit = target.get(" unit" , " m" )
909+ try :
910+ scale = _safe_unit_conversion(unit)
911+ except ValueError as e:
912+ raise ValueError (f" Invalid unit in target configuration: {e}" )
913+
914+ try :
915+ mesh_data = load_mesh(target[" model" ], scale, mesh_module)
916+ points_mv = mesh_data[" points" ].astype(np_float)
917+ cells_mv = mesh_data[" cells" ].astype(np.int32)
918+ except Exception as e:
919+ raise RuntimeError (f" Failed to load mesh model '{target.get('model', 'unknown')}': {e}" )
920+
921+ # Enhanced FreeTier validation using helper function
922+ _validate_mesh_for_free_tier(cells_mv.shape[0 ])
923+
924+ cdef float_t[:] origin_mv = np.array(target.get(" origin" , (0 , 0 , 0 )), dtype = np_float)
925+
926+ location = list (target.get(" location" , [0 , 0 , 0 ]))
927+ speed = list (target.get(" speed" , [0 , 0 , 0 ]))
928+ rotation = list (target.get(" rotation" , [0 , 0 , 0 ]))
929+ rotation_rate = list (target.get( " rotation_rate" , [0 , 0 , 0 ]))
930+
931+ cdef float_t[:] location_mv, speed_mv, rotation_mv, rotation_rate_mv
932+
933+ permittivity = target.get(" permittivity" , 1e38 )
934+ permeability = target.get(" permeability" , 1 )
935+ if permittivity == " PEC" :
936+ ep_c = cpp_complex[float_t](< float_t> 1e38 , < float_t> 0.0 )
937+ mu_c = cpp_complex[float_t](< float_t> 1.0 , < float_t> 0.0 )
938+ else :
939+ ep_c = cpp_complex[float_t](< float_t> np.real(permittivity), < float_t> np.imag(permittivity))
940+ mu_c = cpp_complex[float_t](< float_t> np.real(permeability), < float_t> np.imag(permeability))
941+
942+ if any (np.size(var) > 1 for var in location + speed + rotation + rotation_rate):
943+ if np.size(location[0 ]) > 1 :
944+ locx_mv = location[0 ].astype(np_float)
945+ else :
946+ locx_mv = (location[0 ] + speed[0 ]* timestamp).astype(np_float)
947+
948+ if np.size(location[1 ]) > 1 :
949+ locy_mv = location[1 ].astype(np_float)
950+ else :
951+ locy_mv = (location[1 ] + speed[1 ]* timestamp).astype(np_float)
952+
953+ if np.size(location[2 ]) > 1 :
954+ locz_mv = location[2 ].astype(np_float)
955+ else :
956+ locz_mv = (location[2 ] + speed[2 ]* timestamp).astype(np_float)
957+
958+ if np.size(speed[0 ]) > 1 :
959+ spdx_mv = speed[0 ].astype(np_float)
960+ else :
961+ spdx_mv = np.full(ts_shape, speed[0 ], dtype = np_float)
962+
963+ if np.size(speed[1 ]) > 1 :
964+ spdy_mv = speed[1 ].astype(np_float)
965+ else :
966+ spdy_mv = np.full(ts_shape, speed[1 ], dtype = np_float)
967+
968+ if np.size(speed[2 ]) > 1 :
969+ spdz_mv = speed[2 ].astype(np_float)
970+ else :
971+ spdz_mv = np.full(ts_shape, speed[2 ], dtype = np_float)
972+
973+ if np.size(rotation[0 ]) > 1 :
974+ rotx_mv = np.radians(rotation[0 ]).astype(np_float)
975+ else :
976+ rotx_mv = np.radians(
977+ rotation[0 ] + rotation_rate[0 ]* timestamp).astype(np_float)
978+
979+ if np.size(rotation[1 ]) > 1 :
980+ roty_mv = np.radians(rotation[1 ]).astype(np_float)
981+ else :
982+ roty_mv = np.radians(
983+ rotation[1 ] + rotation_rate[1 ]* timestamp).astype(np_float)
984+
985+ if np.size(rotation[2 ]) > 1 :
986+ rotz_mv = np.radians(rotation[2 ]).astype(np_float)
987+ else :
988+ rotz_mv = np.radians(
989+ rotation[2 ] + rotation_rate[2 ]* timestamp).astype(np_float)
990+
991+ if np.size(rotation_rate[0 ]) > 1 :
992+ rrtx_mv = np.radians(rotation_rate[0 ]).astype(np_float)
993+ else :
994+ rrtx_mv = np.full(ts_shape, np.radians(rotation_rate[0 ]), dtype = np_float)
995+
996+ if np.size(rotation_rate[1 ]) > 1 :
997+ rrty_mv = np.radians(rotation_rate[1 ]).astype(np_float)
998+ else :
999+ rrty_mv = np.full(ts_shape, np.radians(rotation_rate[1 ]), dtype = np_float)
1000+
1001+ if np.size(rotation_rate[2 ]) > 1 :
1002+ rrtz_mv = np.radians(rotation_rate[2 ]).astype(np_float)
1003+ else :
1004+ rrtz_mv = np.full(ts_shape, np.radians(rotation_rate[2 ]), dtype = np_float)
1005+
1006+ Mem_Copy_Vec3(& locx_mv[0 ,0 ,0 ], & locy_mv[0 ,0 ,0 ], & locz_mv[0 ,0 ,0 ], bbsize_c, loc_vt)
1007+ Mem_Copy_Vec3(& spdx_mv[0 ,0 ,0 ], & spdy_mv[0 ,0 ,0 ], & spdz_mv[0 ,0 ,0 ], bbsize_c, spd_vt)
1008+ Mem_Copy_Vec3(& rotx_mv[0 ,0 ,0 ], & roty_mv[0 ,0 ,0 ], & rotz_mv[0 ,0 ,0 ], bbsize_c, rot_vt)
1009+ Mem_Copy_Vec3(& rrtx_mv[0 ,0 ,0 ], & rrty_mv[0 ,0 ,0 ], & rrtz_mv[0 ,0 ,0 ], bbsize_c, rrt_vt)
1010+
1011+ else :
1012+ location_mv = np.array(location, dtype = np_float)
1013+ loc_vt.push_back(Vec3[float_t](& location_mv[0 ]))
1014+
1015+ speed_mv = np.array(speed, dtype = np_float)
1016+ spd_vt.push_back(Vec3[float_t](& speed_mv[0 ]))
1017+
1018+ rotation_mv = np.radians(np.array(rotation, dtype = np_float)).astype(np_float)
1019+ rot_vt.push_back(Vec3[float_t](& rotation_mv[0 ]))
1020+
1021+ rotation_rate_mv = np.radians(np.array(rotation_rate, dtype = np_float)).astype(np_float)
1022+ rrt_vt.push_back(Vec3[float_t](& rotation_rate_mv[0 ]))
1023+
1024+ # Handle deprecated parameter with enhanced warning
1025+ if " is_ground" in target:
1026+ target[" skip_diffusion" ] = target[" is_ground" ]
1027+ _warn_deprecated_parameter(" is_ground" , " skip_diffusion" )
1028+
1029+ targets_manager[0 ].AddTarget(& points_mv[0 , 0 ],
1030+ & cells_mv[0 , 0 ],
1031+ < int_t> cells_mv.shape[0 ],
1032+ Vec3[float_t](& origin_mv[0 ]),
1033+ loc_vt,
1034+ spd_vt,
1035+ rot_vt,
1036+ rrt_vt,
1037+ ep_c,
1038+ mu_c,
1039+ < bool > target.get(" skip_diffusion" , False ))
1040+
8621041@ cython.cdivision (True )
8631042@ cython.boundscheck (False )
8641043@ cython.wraparound (False )
0 commit comments