Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incomplete shot handling #154

Merged
merged 17 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
1c278e8
Addition of recording of the trajectory interruption point for RangeE…
serhiy-yevtushenko Jan 27, 2025
6e71070
Changed TestDangerSpace to pass.
serhiy-yevtushenko Jan 27, 2025
d78797f
Added test for checking the addition of last point to HitResult.traje…
serhiy-yevtushenko Jan 27, 2025
ec45133
Refactored test and added test_vertical_shot
serhiy-yevtushenko Jan 27, 2025
44a0268
Added changes as well to cython version
serhiy-yevtushenko Jan 27, 2025
da7e6b1
Changed to cythonic version of call of create_trajectory_row
serhiy-yevtushenko Jan 27, 2025
b227024
Added hash method to AbstractDimension. This allows using TrajectoryD…
serhiy-yevtushenko Jan 27, 2025
c00f180
Removed check for time point being different from last point time, as…
serhiy-yevtushenko Jan 27, 2025
f8c5e58
Fix for https://github.com/o-murphy/py-ballisticcalc/issues/150
serhiy-yevtushenko Jan 27, 2025
81317ea
Change handling of end_point inclusion through changing logic of rang…
serhiy-yevtushenko Jan 28, 2025
fd7218e
Fix of cython errors
serhiy-yevtushenko Jan 28, 2025
61f56c7
Removed commented out print statement and dependency on numpy call
serhiy-yevtushenko Jan 28, 2025
4860ced
_TrajectoryDataFilter patch
o-murphy Jan 28, 2025
7fb59b6
Renamed step to record_step, added comment
serhiy-yevtushenko Jan 28, 2025
a382947
Merge branch 'incomplete_shot_handling' of https://github.com/serhiy-…
serhiy-yevtushenko Jan 28, 2025
f47a427
Removed ranges_length and current_item members in _TrajectoryDataFilt…
serhiy-yevtushenko Jan 29, 2025
806bb7c
bump to v2.1.0b5
o-murphy Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions py_ballisticcalc.exts/py_ballisticcalc_exts/trajectory_calc.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -353,16 +353,17 @@ cdef class TrajectoryCalc:
velocity_vector = mul_c(&_dir_vector, velocity)
# endregion

min_step = min(calc_step, step)
# With non-zero look_angle, rounding can suggest multiple adjacent zero-crossings
data_filter = _TrajectoryDataFilter(filter_flags=filter_flags,
ranges_length=<int> ((maximum_range / step) + 1),
ranges_length=<int> ((maximum_range / min_step) + 1),
o-murphy marked this conversation as resolved.
Show resolved Hide resolved
time_step=time_step)
data_filter.setup_seen_zero(range_vector.y, self.__shot.barrel_elevation, self.__shot.look_angle)

#region Trajectory Loop
warnings.simplefilter("once") # used to avoid multiple warnings in a loop
cdef int it = 0
while range_vector.x <= maximum_range + calc_step:
while range_vector.x <= maximum_range + min_step:
it += 1
data_filter.current_flag = CTrajFlag.NONE

Expand Down Expand Up @@ -412,6 +413,12 @@ cdef class TrajectoryCalc:
or range_vector.y < _cMaximumDrop
or self.__shot.alt0 + range_vector.y < _cMinimumAltitude
):
ranges.append(create_trajectory_row(
time, range_vector, velocity_vector,
velocity, mach, cy_spin_drift(&self.__shot, time), self.__shot.look_angle,
density_factor, drag, self.__shot.weight, data_filter.current_flag
))

if velocity < _cMinimumVelocity:
reason = RangeError.MinimumVelocityReached
elif range_vector.y < _cMaximumDrop:
Expand All @@ -423,7 +430,7 @@ cdef class TrajectoryCalc:

#endregion
# If filter_flags == 0 then all we want is the ending value
if not filter_flags:
if len(ranges)==0:
ranges.append(create_trajectory_row(
time, range_vector, velocity_vector,
velocity, mach, cy_spin_drift(&self.__shot, time), self.__shot.look_angle,
Expand Down
20 changes: 15 additions & 5 deletions py_ballisticcalc/trajectory_calc/_trajectory_calc.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def trajectory(self, shot_info: Shot, max_range: Distance, dist_step: Distance,
filter_flags = TrajFlag.RANGE

if extra_data:
dist_step = Distance.Foot(self._config.chart_resolution)
# dist_step = Distance.Foot(self._config.chart_resolution)
filter_flags = TrajFlag.ALL

self._init_trajectory(shot_info)
Expand Down Expand Up @@ -326,15 +326,16 @@ def _integrate(self, shot_info: Shot, maximum_range: float, step: float,
# endregion

# With non-zero look_angle, rounding can suggest multiple adjacent zero-crossings
min_step = min(self.calc_step, step)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

smart, but you have to write comments there, it cause it can create misunderstanding in future, and maybe we should rename step to record_step and we can to not provide min_step, we can just redefine calc_step

self.calc_step = min(self.calc_step, record_step) 

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

# With non-zero look_angle, rounding can suggest multiple adjacent zero-crossings
self.calc_step = min(self.calc_step, step)
data_filter = _TrajectoryDataFilter(filter_flags=filter_flags,
                                    ranges_length=int((maximum_range)/ self.calc_step) + 1,
                                    time_step=time_step)
data_filter.setup_seen_zero(range_vector.y, self.barrel_elevation, self.look_angle)

# region Trajectory Loop
warnings.simplefilter("once")  # used to avoid multiple warnings in a loop
it = 0
while range_vector.x <= maximum_range + self.calc_step:
    it += 1
    data_filter.clear_current_flag()

Copy link
Owner

@o-murphy o-murphy Jan 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but i can't suggest now why this fail on 2 of your tests

possibly cause of row delta_time = self.calc_step / max(1.0, velocity)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be done - but need to be tested. My implementation was heavily affected by getting all tests pasisng

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be done - but need to be tested. My implementation was heavily affected by getting all tests pasisng
Please check it
it looks like small fix should be done, possibly assersions in tests would be not as strict

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The suggested change breaks two of the newer tests in test_end_points_are_include, and cause distance difference in distances between end points in extra_data on and off mode to be bigger than 0.2 Feet. So, I will not go with it.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The suggested change breaks two of the newer tests in test_end_points_are_include, and cause distance difference in distances between end points in extra_data on and off mode to be bigger than 0.2 Feet. So, I will not go with it.

Just intresting why it's that

data_filter = _TrajectoryDataFilter(filter_flags=filter_flags,
ranges_length=int(maximum_range / step) + 1,
ranges_length=int((maximum_range)/ min_step) + 1,
o-murphy marked this conversation as resolved.
Show resolved Hide resolved
time_step=time_step)
data_filter.setup_seen_zero(range_vector.y, self.barrel_elevation, self.look_angle)

# region Trajectory Loop
warnings.simplefilter("once") # used to avoid multiple warnings in a loop
it = 0
while range_vector.x <= maximum_range + self.calc_step:
while range_vector.x <= maximum_range + min_step:
it += 1
data_filter.clear_current_flag()

Expand All @@ -357,7 +358,9 @@ def _integrate(self, shot_info: Shot, maximum_range: float, step: float,
density_factor, drag, self.weight, data_filter.current_flag
))
if data_filter.should_break():
print(f'data_filter.should_break worked at distance {Distance.Foot(range_vector.x)>>Distance.Meter=}')
break

# endregion

# region Ballistic calculation step (point-mass)
Expand All @@ -382,6 +385,11 @@ def _integrate(self, shot_info: Shot, maximum_range: float, step: float,
or range_vector.y < _cMaximumDrop
or self.alt0 + range_vector.y < _cMinimumAltitude
):
ranges.append(create_trajectory_row(
time, range_vector, velocity_vector,
velocity, mach, self.spin_drift(time), self.look_angle,
density_factor, drag, self.weight, data_filter.current_flag
))
if velocity < _cMinimumVelocity:
reason = RangeError.MinimumVelocityReached
elif range_vector.y < _cMaximumDrop:
Expand All @@ -393,8 +401,10 @@ def _integrate(self, shot_info: Shot, maximum_range: float, step: float,
# endregion

# endregion
# If filter_flags == 0 then all we want is the ending value
if not filter_flags:
# this check supercedes not filter_flags - as it will be true in any condition
# if not filter_flags:
if len(ranges)==0:
# we need to add end value in case of not filter flag and in case of usual trajectory
ranges.append(create_trajectory_row(
time, range_vector, velocity_vector,
velocity, mach, self.spin_drift(time), self.look_angle,
Expand Down
3 changes: 3 additions & 0 deletions py_ballisticcalc/unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,9 @@ def __float__(self):
def __eq__(self, other):
return float(self) == other

def __hash__(self):
return hash((self._value, self._defined_units))

def __lt__(self, other):
return float(self) < other

Expand Down
72 changes: 72 additions & 0 deletions tests/fixtures_and_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import pytest

from py_ballisticcalc import HitResult, Distance, InterfaceConfigDict, Calculator, DragModel, TableG1, Weight, Ammo, \
Velocity, Weapon, Shot, Angular


def print_out_trajectory_compact(hit_result: HitResult, label="", distance_unit: Distance = Distance.Meter,
top_k: int = 5):
trajectory_length = len(hit_result.trajectory)
if label:
print(f'{label}: Length of trajectory: { trajectory_length=}')
else:
print(f'Length of trajectory: { trajectory_length=}')


trajectory = hit_result.trajectory
if top_k<trajectory_length:
end_start_top_k = top_k
start_end_top_k = trajectory_length - top_k-1
if end_start_top_k<start_end_top_k:
trajectory = trajectory[:end_start_top_k]+trajectory[start_end_top_k:]

for i, p in enumerate(trajectory):
if i<top_k:
index_to_print = i+1
else:
index_to_print = (trajectory_length-top_k)+i-top_k
if i==top_k and i!=trajectory_length-(top_k+1):
print("...")
print(f'{index_to_print}. ({p.distance>>distance_unit}, {p.height>>distance_unit})')


@pytest.fixture()
def zero_height_calc():
config = InterfaceConfigDict(
cMinimumVelocity=0,
cMinimumAltitude=Distance.Meter(0),
cMaximumDrop=Distance.Meter(0),
)
calc = Calculator(_config=config)
return calc


def create_shot():
drag_model = DragModel(
bc=0.759,
drag_table=TableG1,
weight=Weight.Gram(108),
diameter=Distance.Millimeter(23),
length=Distance.Millimeter(108.2),
)
ammo = Ammo(drag_model, Velocity.MPS(930))
gun = Weapon()
shot = Shot(
weapon=gun,
ammo=ammo,
)
return shot


def shot_with_relative_angle_in_degrees(angle_in_degrees: float):
shot = create_shot()
shot.relative_angle = Angular.Degree(angle_in_degrees)
return shot


@pytest.fixture()
def zero_min_velocity_calc():
config = InterfaceConfigDict(
cMinimumVelocity=0,
)
return Calculator(_config=config)
2 changes: 1 addition & 1 deletion tests/test_danger_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def setUp(self) -> None:
shot = Shot(weapon=Weapon(), ammo=ammo, winds=current_winds)
calc = Calculator()
calc.set_weapon_zero(shot, Distance.Foot(300))
self.shot_result = calc.fire(shot, trajectory_range=Distance.Yard(1000), trajectory_step=Distance.Yard(100), extra_data=True)
self.shot_result = calc.fire(shot, trajectory_range=Distance.Yard(1000), trajectory_step=Distance.Yard(1), extra_data=True)

def test_danger_space(self):
danger_space = self.shot_result.danger_space(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def test_find_index_for_distance(one_degree_shot):
)
# for reproducibility
random.seed(42)
random_indices = random.sample(range(len(shot.trajectory)), 100)
random_indices = random.sample(range(len(shot.trajectory)), min(100, len(shot.trajectory)))
start_time = time.time()

for i in random_indices:
Expand Down
Loading
Loading