@@ -151,6 +151,7 @@ def export_trajectory_to_txt(
151151 motivation_model : mm .MotivationModel ,
152152 output_file = "output.txt" ,
153153 geometry_file = "geometry.xml" ,
154+ motivation_csv : pathlib .Path | None = None ,
154155 df = 10 ,
155156 v0 = 1.2 ,
156157 radius = 0.18 ,
@@ -174,14 +175,10 @@ def export_trajectory_to_txt(
174175 # Sort by frame within each trajectory
175176 group = group .sort_values (by = "frame" )
176177 traj = group [["x" , "y" ]].values
177- agent_value = motivation_model .motivation_strategy .get_value (agent_id = traj_id )
178178
179179 # Calculate speed for this trajectory
180180 speed = compute_speed (traj , df , fps )
181- # if agent_value > 1.0:#green
182- values .extend ([- 1 ] * len (speed ))
183- # else:#blue
184- # values.extend([10]*len(speed))
181+ values .extend ([0.0 ] * len (speed ))
185182
186183 # Store speed and corresponding frame indices
187184 speeds .extend (speed )
@@ -194,9 +191,42 @@ def export_trajectory_to_txt(
194191 df_data .loc [frame_indices , "speed" ] = speed_series
195192 df_data ["color" ] = (df_data ["speed" ] / v0 * 255 ).clip (0 , 255 ).astype (int )
196193 else :
197- value_series = pd .Series (values , index = frame_indices )
198- df_data .loc [frame_indices , "value" ] = value_series
199- df_data ["color" ] = df_data ["value" ]
194+ if motivation_csv is not None and motivation_csv .exists ():
195+ motivation_df = pd .read_csv (motivation_csv )
196+ if not ("frame" in motivation_df .columns and "id" in motivation_df .columns ):
197+ motivation_df = pd .read_csv (
198+ motivation_csv ,
199+ names = [
200+ "frame" ,
201+ "id" ,
202+ "time" ,
203+ "motivation" ,
204+ "x" ,
205+ "y" ,
206+ "value" ,
207+ "rank_abs" ,
208+ "rank_q" ,
209+ "payoff_p" ,
210+ "rank_update_flag" ,
211+ ],
212+ )
213+ motivation_slice = motivation_df [["frame" , "id" , "motivation" ]].copy ()
214+ df_data = df_data .merge (
215+ motivation_slice ,
216+ on = ["frame" , "id" ],
217+ how = "left" ,
218+ suffixes = ("" , "_m" ),
219+ )
220+ if "motivation_m" in df_data .columns :
221+ df_data ["motivation" ] = df_data ["motivation" ].fillna (
222+ df_data ["motivation_m" ]
223+ )
224+ df_data .drop (columns = ["motivation_m" ], inplace = True )
225+ df_data ["motivation" ] = df_data ["motivation" ].fillna (0.0 )
226+ else :
227+ value_series = pd .Series (values , index = frame_indices )
228+ df_data .loc [frame_indices , "motivation" ] = value_series
229+ df_data ["color" ] = (df_data ["motivation" ] * 255 ).clip (0 , 255 ).astype (int )
200230
201231 # Write the formatted data to the output file
202232 with open (output_file , "w" ) as f :
@@ -430,52 +460,6 @@ def init_simulation(
430460 return simulation , geometry_open
431461
432462
433- def adjust_radius_with_distance (
434- position_y : float ,
435- motivation_i : float ,
436- min_value : float = 0.1 ,
437- max_value : float = 0.5 ,
438- y_min : float = - 1 , # Start reducing radius from this y position
439- y_max : float = 19 , # Exit position where radius should be min_value
440- min_motivation : float = 1 ,
441- ) -> float :
442- """
443- Adjust the radius based on agent's motivation level and distance to exit.
444-
445- :param position_y: The pedestrian's current y position.
446- :param motivation_i: The agent's motivation level (1 <= motivation_i <= 3).
447- :param min_value: Minimum radius near the exit (y_max).
448- :param max_value: Maximum radius when far from the exit.
449- :param y_min: Position where radius starts decreasing.
450- :param y_max: Position where radius is minimal.
451- :return: Adjusted radius.
452- """
453- max_motivation = 3.6 / 1.2
454- # Ensure position_y is within the defined range
455- position_y = max (min (position_y , y_max ), y_min )
456-
457- # Compute distance-based factor (1 when far, 0 when at exit)
458- distance_factor = (y_max - position_y ) / (y_max - y_min )
459-
460- # Compute motivation-dependent base radius (inverse relationship)
461- motivation_radius = max_value - (max_value - min_value ) * (
462- motivation_i - min_motivation
463- ) / (max_motivation - min_motivation )
464- # print("-----------------------")
465- # print(f"{y_min = }, {y_max = }")
466- # print(f"{min_value = }, {max_value = }")
467- # print(
468- # f"{position_y = }, {motivation_i = }, {min_motivation = }, {motivation_radius = } "
469- # )
470- # print(
471- # f"{min_value = }, {motivation_radius = }, {distance_factor = }, --> {min_value + (motivation_radius - min_value) * distance_factor}"
472- # )
473- # input()
474-
475- # Scale radius based on distance factor
476- return min_value + (motivation_radius - min_value ) * distance_factor
477-
478-
479463def process_agent (
480464 agent : jps .Agent ,
481465 door : Point ,
@@ -528,30 +512,7 @@ def process_agent(
528512 motivation_i
529513 )
530514
531- # Usage in the agent model
532- do_adjust_radius = False
533- if "do_adjust_radius" in _data ["motivation_parameters" ]:
534- do_adjust_radius = _data ["motivation_parameters" ]["do_adjust_radius" ]
535-
536- if do_adjust_radius : # Adjust radius based on distance to exit
537- min_value_y = _data ["motivation_parameters" ]["adjust_radius_y_min" ]
538- max_value_y = _data ["motivation_parameters" ]["adjust_radius_y_max" ]
539- min_value_radius = _data ["motivation_parameters" ]["min_radius" ]
540- max_value_radius = _data ["motivation_parameters" ]["max_radius" ]
541- min_motivation = _data ["motivation_parameters" ]["min_value_low" ]
542- agent .model .radius = adjust_radius_with_distance (
543- position_y = position [1 ],
544- motivation_i = motivation_i ,
545- min_value = min_value_radius , # Smallest radius near the exit
546- max_value = max_value_radius , # Largest radius when far away
547- y_min = min_value_y , # Start decreasing radius here
548- y_max = max_value_y , # Minimum radius at exit
549- min_motivation = min_motivation ,
550- )
551- else :
552- agent .model .radius = _data ["velocity_init_parameters" ][
553- "radius"
554- ] # Fixed radius at the exit
515+ agent .model .radius = _data ["velocity_init_parameters" ]["radius" ]
555516
556517 # 0,3
557518 # 1,6
@@ -1057,16 +1018,18 @@ def main(
10571018 trajectory_data , walkable_area = read_sqlite_file (output_path )
10581019 output_file = "jpsvis_files" + pathlib .Path (output_path ).stem + ".txt"
10591020 geometry_file = pathlib .Path (output_path ).stem + "_geometry.xml"
1021+ motivation_csv = output_path .with_name (output_path .stem + "_motivation.csv" )
10601022 logging .info (f"Using: { geometry_file } " )
10611023 v0_mean = 1.2
10621024 export_trajectory_to_txt (
10631025 trajectory_data ,
10641026 motivation_model ,
10651027 output_file = output_file ,
10661028 geometry_file = geometry_file ,
1029+ motivation_csv = motivation_csv ,
10671030 df = 10 ,
10681031 v0 = v0_mean ,
1069- by_speed = True ,
1032+ by_speed = False ,
10701033 )
10711034
10721035 polygon_to_xml (walkable_area = walkable_area , output_file = geometry_file )
0 commit comments