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

Improve Overall Performance #6

Open
Bonifatius94 opened this issue Oct 23, 2022 · 8 comments
Open

Improve Overall Performance #6

Bonifatius94 opened this issue Oct 23, 2022 · 8 comments

Comments

@Bonifatius94
Copy link

Bonifatius94 commented Oct 23, 2022

Hi guys,

I'm using your PySocialForce package to model a robot / pedestrian interaction in a 2D world. It's really a great effort from your side to create this package and put it on PyPI. Unfortunately, it's a bit too slow for my reinforcement learning purposes in order to achieve a reasonable amount of training episodes for my robot. (I know I could scale out with A3C, but I'm just a poor student 😂)

I've seen you've already put Numba optimizations into your code and modeled everything as NumPy array, so you're probably aware of the fact that performance is critical to a simulation environment. Have you ever profiled your package, e.g. with cProfile or the new Scalene? (I know, silly question, but I'll have to ask anyways. I can create a profile for you if you want 😂)

I think you've still got lots of Python C-API overhead in your routines which could easily be eliminated by more Numba vectorizations. For example, you're computing the forces sequentially (https://github.com/yuxiang-gao/PySocialForce/blob/master/pysocialforce/simulator.py#L78). And for modeling the forces you're using OOP inheritance which could be replaced by a single function returning a float (https://github.com/yuxiang-gao/PySocialForce/blob/master/pysocialforce/forces.py#L39).

I'm willing to make a major contribution to your project in the near future in case I can figure out some sensible optimizations. Are you interested in a collaboration of any kind? I'll be carrying out this optimization anyways because I need a faster training for my master thesis 😂

Best wishes,
Marco

@Bonifatius94
Copy link
Author

Your obstacle force seems to take 98% of computation time when I instantiate a 80x80 world with 10 random obstacles. This linspace in scene.py is really bad for performance.

With actual 2D vector math this is almost for free. Just a bit of unit circle rotations to compute orthogonal directions to the obstacle lines, shifted by 90 deg, then intersecting the obstacle line with its orthogonal projection starting from the point to be checked. Line/line intersection can be programmed like so: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection

I'll send you an updated version soon 😉

@yuxiang-gao
Copy link
Owner

yuxiang-gao commented Oct 26, 2022

Hi @Bonifatius94 ,
Thanks for your interests in this project. That sounds amazing.
I've been meaning to going back to this project for a while but never found the right time. I definitely would like to take up on your offer for a collaboration of some sort.
Regarding the obstacle force calculation, I think issue #2 also touched on this. I agree the linespace thing is not very optimal representation of the obstacles. My original thoughts was to precompute the potential field for the obstacles instead of calculating them on the fly but I never got around to implement it as we internally use another simulator for training and finding the closest obstacle was handled by the simulator.
Your proposal sounds reasonable for obstacles of geometric shapes and I think it is an pretty elegant solution for small maps.
Please let me know what kind of assistance I can provide.

Best,
Yuxiang

@Bonifatius94
Copy link
Author

@yuxiang-gao Oh that would be great if we could collaborate 😄 I'm currently getting into this repulsive force theory which I'm not familiar with. Let's see if I can figure out a more lightweight approach to this algorithm, shouldn't be too hard, I think 😄

And yeah, as already said, I really need better performance because it's a show stopper for my RL trainings 😅

@Bonifatius94
Copy link
Author

Bonifatius94 commented Oct 26, 2022

I'm trying the approach from this video with those two formulas for line/point distance and/or line segment/line intersection 😄

I'm currently a bit occupied with calculating the partial derivative by x / y coords of the pedestrian's position, but this should at least work. What's your opinion on this approach? 😉

@Bonifatius94
Copy link
Author

One question: You're initializing the forces with following. Is this meant to represent the forces for each pedestrian in separate x / y components? I'm just wondering, but it would totally make sense if I'm thinking about it because of the partial derivatives to compute the force in the first place 😂

force = np.zeros((self.peds.size(), 2))

@Bonifatius94
Copy link
Author

I think I figured it out. At least it's now so fast that the SocialForce dominates. See here on my fork.

I didn't check if the force does the right thing though. We might need to experiment a bit and verify my math proofs 😂

@Bonifatius94
Copy link
Author

I've debugged my obstacle force in a Jupyter notebook and it seems to work as expected. I'll try to convert those examples into unit tests. But now, some of your unit test scenarios seem to fail. Can you help me with debugging @yuxiang-gao ? 😉

And there is also an inherent issue with the potential field approach because it produces really weird behavior in a "walk through gate" scenario. Are you familiar with this problem and know an answer to this? 🤔

@Bonifatius94
Copy link
Author

I've created a branch where I removed all my bold refactorings and just made the minimal effort to put my new obstacle force in. You can have a look at it and merge if you like. I'm now working towards training my robot AI 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants