-
Notifications
You must be signed in to change notification settings - Fork 16.7k
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
wayBack library #6675
wayBack library #6675
Conversation
@@ -125,6 +125,11 @@ | |||
#include "afs_copter.h" | |||
#endif | |||
|
|||
|
|||
#if USE_WAYBACK == ENABLED | |||
#include "/AP_WayBack/AP_WayBack.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should add AP_Wayback to wscript and make.inc, instead of giving a path to the file !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes but as I sayd I never build this library into real Copter code so all changes outside AP_Wayback folder are just "proof-of-concept", samples of usage and needs to be corrected
libraries/AP_WayBack/AP_WayBack.cpp
Outdated
|
||
|
||
bool AP_WayBack::start(){ | ||
if(points==NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better use nullptr
ping @squilter |
{ | ||
float denom,numera,numerb; | ||
|
||
denom = (p4.y-p3.y) * (p2.x-p1.x) - (p4.x-p3.x) * (p2.y-p1.y); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better declare and instentiate directly !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this gives a fastest code, checked by debugger. Moreover this is a part of working-in-years plugin to PHP so I don't want to change anything for compatibility
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fasted code.. on embedded ARM architecture?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and in CortexM4F too :) GCC don't likes to optimize out classes and arrays, so stores data to memory even it can be calculated in registers. I always check assembly listings of my code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moreover that Cortex has "composite" commands like vfma which used when compiling such code and not used in case load-mul-store. This code turns to
80a5a7a: ee07 1a10 vmov s14, r1
80a5a7e: 6859 ldr r1, [r3, #4]
80a5a80: 681b ldr r3, [r3, #0]
80a5a82: ee05 3a90 vmov s11, r3
80a5a86: 6843 ldr r3, [r0, #4]
80a5a88: ee08 1a10 vmov s16, r1
80a5a8c: ee05 3a10 vmov s10, r3
80a5a90: 6801 ldr r1, [r0, #0]
80a5a92: 686b ldr r3, [r5, #4]
80a5a94: ee08 1a90 vmov s17, r1
80a5a98: ee06 2a90 vmov s13, r2
80a5a9c: ee07 3a90 vmov s15, r3
80a5aa0: 6829 ldr r1, [r5, #0]
80a5aa2: ee75 5ae6 vsub.f32 s11, s11, s13
80a5aa6: ee35 9a67 vsub.f32 s18, s10, s15
80a5aaa: ee06 1a10 vmov s12, r1
80a5aae: ee38 8a47 vsub.f32 s16, s16, s14
80a5ab2: ee36 6a68 vsub.f32 s12, s12, s17
80a5ab6: ee29 9a25 vmul.f32 s18, s18, s11
80a5aba: ee76 8ae8 vsub.f32 s17, s13, s17
80a5abe: ee35 7a47 vsub.f32 s14, s10, s14
80a5ac2: eea8 9a06 vfma.f32 s18, s16, s12
80a5ac6: 4604 mov r4, r0
80a5ac8: ee28 8a28 vmul.f32 s16, s16, s17
80a5acc: ee77 7ac5 vsub.f32 s15, s15, s10
80a5ad0: eea5 8a87 vfma.f32 s16, s11, s14
80a5ad4: ee67 8aa8 vmul.f32 s17, s15, s17
80a5ad0: eea5 8a87 vfma.f32 s16, s11, s14
80a5ad4: ee67 8aa8 vmul.f32 s17, s15, s17
80a5ad8: eeb0 0a48 vmov.f32 s0, s16
80a5adc: eee6 8a07 vfma.f32 s17, s12, s14
one load per element - and all calculations in registers, almost without any VMOV
But if classes used and results saved to class members then optimization limited to one line
pos_vector = Vector3f(packet.x * 100.0f, packet.y * 100.0f, -packet.z * 100.0f);
8027df2: ed9f 6a18 vldr s12, [pc, #96] ; 8027e54
8027df6: ed9d 7a16 vldr s14, [sp, #88] ; 0x58
8027dfa: eddd 7a17 vldr s15, [sp, #92] ; 0x5c
8027dfe: eddd 6a15 vldr s13, [sp, #84] ; 0x54
8027e02: ee27 7a06 vmul.f32 s14, s14, s12
8027e06: ee67 7ac6 vnmul.f32 s15, s15, s12
8027e0a: ee66 6a86 vmul.f32 s13, s13, s12
8027e12: edcd 6a08 vstr s13, [sp, #32]
8027e16: ed8d 7a09 vstr s14, [sp, #36] ; 0x24
8027e1a: edcd 7a0a vstr s15, [sp, #40]
but this line looks much better, sure
Also GCC don't likes to remove class methods even they are "inline" so all cool .is_zero() turns to real calls with creation of temporary variable in stack:
if (delta_pos_xyz.is_zero()) {
80a231a: 4628 mov r0, r5
80a231c: edcd 0a06 vstr s1, [sp, #24]
80a2320: edcd 7a07 vstr s15, [sp, #28]
80a2324: f7b1 f912 bl 805354c <_ZNK7Vector3IfE7is_zeroEv>
80a2328: b938 cbnz r0, 80a233a
and even const function much worse than #defines - we got real function instead of true constant:
float AP_Proximity_LightWareSF40C::distance_min() const
{
return 0.20f;
}
80a3290: ed9f 0a01 vldr s0, [pc, #4] ; 80a3298
80a3294: 4770 bx lr
Well, we will need at good pass to correct the coding style ! and I saw some malloc and goto ... |
I optimize programs for size and speed, not for style. Video was some time earlier in already closed issue. |
old video - https://www.youtube.com/watch?v=D5UGfn47i8U |
extern const AP_HAL::HAL& hal; | ||
|
||
AP_WayBack::Point* AP_WayBack::points; | ||
uint16_t AP_WayBack::max_num_points=0; // size of storage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with C+11 all of these class variables are set to zero for you, manually setting them to zero just wastes flash space. Please remove all non-zero init values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the above "code style", and definitely NO waste space because GCC just skips all 0-initialization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whoops, sorry. I thought these were in the class header. The ones in the header are fine. However, what are these variables doing here? They belong in the class as a member variable. What happens if there are two instances of the class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These variables are static members because this class is intended to be static by design: we have just only one point-of-start. Creation of another instances can be checked and prohibited if it needs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Creation of another instances can be checked
but only if you know to check for it. Best to be fully-static or a real class. Please see the entire codebase as an example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lots of drones are Linux based and don't care about another few KB of RAM. Please fix it so multiple class instances don't wreak havoc. All other classes work that way. We're not asking to be annoying, we want it to always work and to be n00b dev resistant as much as possible where possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lots of drones are Linux based
may be but I use 6g flight controller in 110g to 3kg drones with only 196k of memory, and definitely do this library for own needs too.
Check for multiple class instances will be added, but if there will be variant of hal.scheduler->register_io_process() that accepts AP_HAL::Proc and not only AP_HAL::MemberProc then class could be fully static.
UPD. Fully static is much worse than current state, panic() will be called on 2 instantiate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're indirectly using it like a singleton by making an assumption it will never be called twice.
Here's how DataFlash handles that check as an intentional singleton. For this type of class I suggest you simply make it like all the other classes so it's flexible.
https://github.com/ArduPilot/ardupilot/blob/master/libraries/DataFlash/DataFlash.h#L58
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry but DataFlash & Co are the worst code I've ever seen :)
Again, there will be check for 2nd instance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check for 2nd instantiate added.
libraries/AP_WayBack/AP_WayBack.cpp
Outdated
|
||
|
||
// move forward on STEPS good points | ||
uint16_t AP_WayBack::move_forw(uint16_t from, uint16_t steps){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please see the style guide:
http://ardupilot.org/dev/docs/style-guide.html
specifically, functions have { on line below,
all if statements requires { }
space after "if" and before { so it's readable.
space between =
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
writing code for speed is good, but if its hard to read and is a different style than the rest of the codebase then it becomes unmaintainable and that's far worse to have in your codebase. Therefore, we have set up some guidelines. Nothing personal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can be fixed by any code formatter, isn't it? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup! Should be quite easy for you to fix :)
char buffer[SERIAL_BUFSIZE]; | ||
|
||
|
||
void getSerialLine(char *cp ){ // получение строки |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments in russian :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes sure, do you want to delete them all?
PS. Just open github in Chrome
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please make comments in English (again, please use the rest of the codebase as an example)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are only 2 possibilities: either I delete all comments by shell script, or them remains as it is. I do not want to waste my time
Ha! I wish I had known earlier. The loop pruning and simplifying are almost exactly the same as I did it. That's pretty neat that we separately arrived at very similar algorithms. This will definitely be a good topic for the dev call. I'll make sure to take a closer look at how this works. If you are going be available for the dev call, you should check out #6682 before. |
typedef struct POINT { | ||
float x; | ||
float y; | ||
// enum POINT_STATUS status; // this field should be changed to NAN in X coord as boolean flag |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
points are only 2D? I'm not sure how useful that is in reality
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have already discussed this question before. The world does not have a roof so the return altitude does as it was set.
@night-ghost have you seen #6682 ? |
sure not, but why the question? |
because they are solving the same problem. It would not make sense to accept both of these PRs into master so a hard decision need to be made. I suggest @night-ghost and @squilter work together to get a single best solution. |
Looked. Probably it is intended to achieve the same goal, but the implementation is fundamentally different: that solution is designed just for those "copters with Linux and a bucket of memory," and a bunch of processor power in the addition. I process an array of points without allocating additional memory and without quadratic complexity like
Is there any process timings? UPD. But the best thing is that that code shows how to inject points into the RTL state machine, so I can now do it myself. So I can help to get rid of a hard decision and close this PR |
added Panic on 2nd instantiate
… into wayBack2 Conflicts: libraries/AP_WayBack/AP_WayBack.cpp libraries/AP_WayBack/AP_WayBack.h
Let me go one-by-one
The initial implementation is a library and a flight mode for copter. The library should work fine for rover as well, and the plan was to implement that after the library has been merged.
No, it runs on a pixhawk
My implementation uses about 2kb of ram. Yours uses more than 30kb. If you were referring to the std::vector that I am using, that is just temporary, and will get replaced by a small (<1kb) array.
The cleanup algorithms should never use more than about 5% of the CPU time, but I expect that they will actually use more like 1% |
yeah, with only 100 points
I define a space for thousands points, not for only 100, so library tries to allocate as much memory as possible. But there is no additional allocations. If it gets 32k it will be place for 4000 points, with 100 points it requires 800 bytes only.
Your algorithm has a places with quadratic complexity so that places will take more time that 490Hz loop allows or needs to break by time (as I see) and to start to work again from beginning. What it will do in case of boat which has 12 hour journey by the tributaries of the river? The boat can not to fly up higher and return by a straight line, but can to have a lots of working time. My library checked on real GPS tracks like Moscow-Vladivostok with loops in town, and works for years here . In any case I don't interested in this PR anymore |
I can't get working Copter because I can't find a right place to inject points to RTL state machine, but library itself works fine in testing. Needed changes in code can be found by searching "USE_WAYBACK"
UPD. there should be call to wayback.end() somewhere on disarm