trust

  • ****
  • 301
Re: Bimode aircraft code changes
« Reply #75 on: May 11, 2021, 01:23:06 am »
Most of the bimode functions seem to be working fine, but one new issue has come up.
I modified GetCurrentFrameType to return the mode the wing is currently in - but it appears this does not change the behavior of VelcoticityRoam, RTB or any of the pathfollower functions once armed. It would seem I need to run some function whenever I change modes to initialize these functions for VTOL or fixedwing control parameters.
  Do I run pathFollowerHandler with newinit set to 1 or something else?

Re: Bimode aircraft code changes
« Reply #76 on: May 11, 2021, 09:28:58 am »
You are looking in the right place as long as you can limit it to when the wing position or FMS switch changes and don't call it with newinit=1 constantly.

Better yet, to be more certain that it is really treated as an FMS change (including which handler to call, etc.), I would modify flight/modules/ManualControl/manualcontrol.c to watch this sensor and do all the stuff it does when the FMS actually changes.

manualcontrol.c is where the FMS is read and acted on and where pathFollowerHandler() or other handler (like for non-GPS flight modes) is called from.
« Last Edit: May 11, 2021, 09:55:33 am by TheOtherCliff »

trust

  • ****
  • 301
Re: Bimode aircraft code changes
« Reply #77 on: May 13, 2021, 11:38:14 pm »
I modified code to generate a mode change state flag so I can execute some code only once when mode changes.
I dug through the code - what concerns me is all the parameters that need to change when switching from Vtol to FixedWing when using pathFollower.
I found code that initializes this: pathFollowerSetActiveController
This code calls pathFollowerInitializeControllersForFrameType to init controllers for wing type.
 I would think I need to execute what this does every time I change wing mode.

I also see that calling SettingsUpdatedCb calls GetCurrentFrameType - and SettingsUpdatedCb calls and sets the active controllers if the frameType changes. So that looks like what I need to call when mode changes. Is the parameter a dummy parameter (says unused)?

I notice one other confusing factor in this function. It defines  a local frameType and sets it to the global frameType. Then it calls GetCurrentFrameType and sets the LOCAL frameType to that value. It uses that to check and see if frameType has changed, and then calls pathFollowerInitializeControllersForFrameType. But I don't see where the global value of frameType is updated. Where/when should I update the global frameType?
My version of GetCurrentFrameType gets the current frame type based on sensors and switches.
Does this make sense?

trust

  • ****
  • 301
Re: Bimode aircraft code changes
« Reply #78 on: May 13, 2021, 11:54:32 pm »
Arg. I see there is a DIFFERENT version of SettingsUpdatedCb in many different modules.
??

trust

  • ****
  • 301
Re: Bimode aircraft code changes
« Reply #79 on: May 14, 2021, 12:22:12 am »
Ok. I get that these are all private local functions and vars for each module.
But can I access just the one I need that's in pathfollower.cpp?

Re: Bimode aircraft code changes
« Reply #80 on: May 14, 2021, 11:11:09 pm »
I modified code to generate a mode change state flag so I can execute some code only once when mode changes.
I dug through the code - what concerns me is all the parameters that need to change when switching from Vtol to FixedWing when using pathFollower.
I found code that initializes this: pathFollowerSetActiveController
This code calls pathFollowerInitializeControllersForFrameType to init controllers for wing type.
 I would think I need to execute what this does every time I change wing mode.
As this has never been done before, it seems that you are finding more things that need to be tweaked.  I haven't been in this code as much as you have now.

Re: Bimode aircraft code changes
« Reply #81 on: May 15, 2021, 12:09:09 am »
Ok. I get that these are all private local functions and vars for each module.
But can I access just the one I need that's in pathfollower.cpp?

The obvious quick change that comes to mind is to make that variable a global.  That works best if you have one setter and possibly multiple getters.

Be aware that this is run under a multi-tasking supervisor.  Setting a global (or even a local through a global setter function) should be done from only one thread if at all possible.  If more than just that thread reads it, the read should be done atomically and if necessary, steps taken to mitigate it being changed just before or just after the read.

For multiple setters, the more typical change would be to put the change in a setter function where anything that must go along with the change can be put and locking against reentrancy can be done to limit access to one thread at a time.

Imagine thread #1 of 2 setters is setting it one way, and a timer interrupt causes a context switch to the other thread, some time in here, switch bounce causes it to change wing tilt sensor state.  How should the interrupting thread handle this?  How should the interrupted thread handle this?

To cause additional nausea, look over these things that I did to avoid threading issues, and grok the reasons they may be necessary:  :)
Code: [Select]
cliff@i925 ~/dev/librepilot/1609 $ grep -nr __sync_ flight
flight/modules/GPS/GPS.c:548:    if (__sync_fetch_and_add(&mutex, 1) == 0) {
flight/modules/GPS/ubx_autoconfig.c:241:    if (__sync_fetch_and_add(&mutex, 1) == 0) {

Code: [Select]
cliff@i925 ~/dev/librepilot/1609 $ grep -n current_step flight/modules/GPS/ubx_autoconfig.c
169:static volatile bool current_step_touched = false;
221:static void set_current_step_if_untouched(initSteps_t new_steps)
226:    if (!current_step_touched) {
229:    if (current_step_touched) {
527:    current_step_touched = false;
618:        set_current_step_if_untouched(INIT_STEP_SEND_MON_VER);
626:        set_current_step_if_untouched(INIT_STEP_WAIT_MON_VER_ACK);
638:        set_current_step_if_untouched(INIT_STEP_RESET_GPS);
675:        set_current_step_if_untouched(INIT_STEP_REVO_9600_BAUD);
706:    // set_current_step_if_untouched(INIT_STEP_GPS_BAUD);
728:        set_current_step_if_untouched(INIT_STEP_REVO_BAUD);
746:            set_current_step_if_untouched(INIT_STEP_SAVE);
748:            set_current_step_if_untouched(INIT_STEP_ENABLE_SENTENCES);
768:                set_current_step_if_untouched(INIT_STEP_SAVE);
772:                set_current_step_if_untouched(INIT_STEP_CONFIGURE);
775:            set_current_step_if_untouched(step_configure ? INIT_STEP_CONFIGURE_WAIT_ACK : INIT_STEP_ENABLE_SENTENCES_WAIT_ACK);
798:                set_current_step_if_untouched(INIT_STEP_PRE_ERROR);
805:            set_current_step_if_untouched(INIT_STEP_CONFIGURE);
807:            set_current_step_if_untouched(INIT_STEP_ENABLE_SENTENCES);
821:            set_current_step_if_untouched(INIT_STEP_SAVE_WAIT_ACK);
824:            set_current_step_if_untouched(INIT_STEP_PRE_DONE);
838:        set_current_step_if_untouched(INIT_STEP_PRE_DONE);
852:        set_current_step_if_untouched(INIT_STEP_DONE);
859:        set_current_step_if_untouched(INIT_STEP_ERROR);
902:    current_step_touched    = true;

trust

  • ****
  • 301
Re: Bimode aircraft code changes
« Reply #82 on: May 15, 2021, 09:44:59 pm »
I created a public function PathFollowerSettingsUpdatedCb inside pathfollower.cpp which calls SettingsUpdatedCb, converted to a C code link so I could access it from ActuatorTask, where I check for changes, and call it ONLY when the mode switches.
   Did a flight test yesterday and today. It starts out fine, in VTOL mode, and when I switched to VR mode it held position pretty well - kept heading and tilted to stay in position despite some wind. I went back to stab2 mode, transitioned to hrz flight, then switched it to VR mode again. The plane kept flying, but did not seem to be flying back to the position when VR was set. I could not affect it's movement with any controls, other than to switchback to stab2 mode and fly it normally. Tried this twice - same results.
   I later also tried RTB - in this case it went into a sudden spiralling turn, so I switched back to stab2 mode.
Here is the video of the first part of the flight with the OSD view.


SettingsUpdatedCb inside pathfollower.cpp seems to be the right place - it checks for mode changes and updates the frameType accordingly. Not sure why this didn't work.

trust

  • ****
  • 301
Re: Bimode aircraft code changes
« Reply #83 on: May 15, 2021, 10:47:16 pm »
I'm wondering if the problem is that although it initializes controllers, it doesn't actually assign them as the activecontroller.

I see there is another function pathFollowerSetActiveController that sets these - but if I try to call it and activeContoller (the pointer) is already set, it will skip all the setting. It seems this was only meant to initialize once.
Does this make sense or is there more that needs to be done?

Re: Bimode aircraft code changes
« Reply #84 on: May 15, 2021, 11:06:04 pm »
I assume that the code was not written with changing airframe type in mind, so you will need to enhance it for that, whatever is required.

The good things are that you didn't crash, :) and that you have a reproducible problem.  Debug it on the bench.  You can try a cheap hardware debugger connected to the SWD port, or use the printf method.  :)

Print a small amount of debugging to come out an FC serial port, and watch this on your computer through an FTDI and a terminal program.

Another way I use (probably the easiest) is to use an unused UAVO (just pick one) as a scratch pad and poke some numbers there (1=it got to here, 2=it got to there) into several different UAVO variables (even the actual value of variables of interest) to correspond to different places you are debugging.  Don't forget to init that UAVO on startup if it is not already inited elsewhere.  You will also need to change that UAVO metadata via GCS System page so that e.g. every time the FC changes it, it gets sent to the GCS.

Re: Bimode aircraft code changes
« Reply #85 on: May 15, 2021, 11:30:16 pm »
What does stock VR mode do when configured in a fixed wing configuration?

I don't recall whether or not VR is appropriate for that.  I think there are other modes more suited to fixed wing?  Autocruise comes to mind.  I confess that I only know to use Attitude and RTB in my fixed wing GPS aircraft.  Is simple Attitude not good enough?  I know it doesn't fight a crosswind, but fighting the wind can cause confusion if you thing it should be pointing in one direction but it is pointing in another.  Look here for some autocruise info.
https://forum.librepilot.org/index.php?topic=4644.msg31459;topicseen#msg31459

I had hoped that running all the code that runs when you do a normal FMS change would do all you need.  I know that there are different controller sections for the different aircraft configurations.  You will just need to make sure that that gets updated.  Hopefully there aren't any "inits that shouldn't be done while armed/flying", or that they can be made airworthy.

trust

  • ****
  • 301
Re: Bimode aircraft code changes
« Reply #86 on: May 16, 2021, 02:46:59 am »
Thanks for the debugging suggestions - I'd been using some of the vars as you say to check internal states.
VR on fixed wing has the plane do circles or figure 8s back to the start point.
If I startup with my bimodefundata.TypeSwitchEnable flag set to 0, it doesn't use my version of GetCurrentFrameType and uses the default set airframeType. I currently have it set to FixedWing. Then when I switch to VR mode it does the above movements - which is what I want.
In the just performed test, I set the flag to 1. So when system initialized, it saw it was in VTOL mode so initialized to VTL mode. That part worked fine.
But after it transitioned to hrz mode, switching to VR mode - it didn't fly the pattern described above. Just kept going, as if it didn't know where to go, or wasn't in VR mode.

trust

  • ****
  • 301
Re: Bimode aircraft code changes
« Reply #87 on: May 16, 2021, 07:55:05 pm »
Looking over the code & trying to understand the flow, I'm thinking of using the following code to deactivate the current activeController, then check the wing status and set activeController based on the current state & flight mode when the wing mode changes - thoughts?

// deactivate activeController & set update activeController
static void pathFollowerReactiveController(__attribute__((unused)) UAVObjEvent *ev)
{
 
    if (activeController) {
        activeController->Deactivate();
        activeController = 0;
    }

    pathFollowerSetActiveController();

    if (activeController) {
        activeController->ObjectiveUpdated();
    }
}

Re: Bimode aircraft code changes
« Reply #88 on: May 17, 2021, 09:57:47 am »
In the just performed test, I set the flag to 1. So when system initialized, it saw it was in VTOL mode so initialized to VTL mode. That part worked fine.
But after it transitioned to hrz mode, switching to VR mode - it didn't fly the pattern described above. Just kept going, as if it didn't know where to go, or wasn't in VR mode.

I guess the thing to test next would be if it works correctly in FW mode if started in FW mode.  If that is the case, then it is "just" a matter of completely changing the mode after startup.

Re: Bimode aircraft code changes
« Reply #89 on: May 17, 2021, 09:59:45 am »
Looking over the code & trying to understand the flow, I'm thinking of using the following code to deactivate the current activeController, then check the wing status and set activeController based on the current state & flight mode when the wing mode changes - thoughts?

// deactivate activeController & set update activeController
static void pathFollowerReactiveController(__attribute__((unused)) UAVObjEvent *ev)
{
 
    if (activeController) {
        activeController->Deactivate();
        activeController = 0;
    }

    pathFollowerSetActiveController();

    if (activeController) {
        activeController->ObjectiveUpdated();
    }
}

Sounds reasonable, but I haven't been deep in this area for years, and have not researched the active controller stuff.