Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • May 07 14:09

    andrew-gresyk on 2.1.1

    (compare)

  • May 07 13:56

    andrew-gresyk on master

    2.1.1 * added `Root::isActive(… (compare)

  • Apr 28 06:07
    binromanarm closed #70
  • Apr 28 06:05
    binromanarm opened #70
  • Apr 28 06:05
    binromanarm commented #2
  • Apr 28 06:03
    binromanarm commented #2
  • Apr 13 06:07

    andrew-gresyk on 2.1.0

    (compare)

  • Apr 13 06:06

    andrew-gresyk on experimental

    (compare)

  • Apr 13 06:06

    andrew-gresyk on master

    2.1.0 + added `activeSubState(… (compare)

  • Apr 13 06:06
    andrew-gresyk closed #69
  • Apr 13 05:51
    andrew-gresyk opened #69
  • Apr 13 05:50

    andrew-gresyk on experimental

    added activeSubState() on root … (compare)

  • Apr 02 15:50

    andrew-gresyk on 2.0.0

    (compare)

  • Apr 02 15:46

    andrew-gresyk on experimental

    (compare)

  • Apr 02 15:46

    andrew-gresyk on master

    2.0.0 - added `select<>()` tra… (compare)

  • Apr 02 15:46
    andrew-gresyk closed #68
  • Apr 02 15:25
    andrew-gresyk synchronize #68
  • Apr 02 15:25

    andrew-gresyk on experimental

    disabled snippets (compare)

  • Apr 02 15:21
    andrew-gresyk synchronize #68
  • Apr 02 15:21

    andrew-gresyk on experimental

    fixing GCC build (compare)

Andrew Gresyk
@andrew-gresyk
Hey @spiderkeys_gitlab
I'd normally just use the actor reference as context, just like you're suggesting:
class AMyActor {
using M = hfsm2::MachineT<
    hfsm2::Config::ContextT<AMyActor&>
>;

using FSM = M::Root<...>;

FSM::Instance fsm;
};
AMyActor::AMyActor()
    : fsm(*this)
Andrew Gresyk
@andrew-gresyk
Gitter wouldn't allow me to edit the above example any more for some reason to fix it a bit further, but the idea is there I think.
Latest HFSM2 / FFSM2 support references, pointers and value types as contexts, so using a pointer to an actor is also an option.
Charles Cross
@spiderkeys_gitlab
@andrew-gresyk awesome, thanks for the clarification
one more quick question, as I didn't find much info in the docs on orthogonal regions: would I be correct in intuiting that they always update their states in the order declared in the region's template?
Andrew Gresyk
@andrew-gresyk
they do, yes
DJuego
@DJuego
Well, @andrew-gresyk . Congratulations for the new version 1.9.0 of HFSM2!! It's been a while since I've worked with any project involving a finite state machine. But you can believe me: I'm looking forward to it. It is my desire to use HFSM2 in the context of a robotic platform I am working with. :-)
1 reply
Charles Cross
@spiderkeys_gitlab
Hi @andrew-gresyk, I've gotten a bit further into integrating HFSM2 into our robotics project; really nice to work with. There is one slightly unexpected behaviour that I encountered and I just wanted to check with you if there is a way of avoiding it. I modeled my overall HFSM into a 2-level state+substate, using Composite regions (with head states) as the states, and just states as the substates. There is some logic that i want to call every for every update of the region, so I overrode the head state's update() method and performed that logic there. This logic contains error checks, like loss of connectivity, timeouts expiring, etc, and is meant to pre-emptively exit the region upon detection of these issues. While this works, I noticed that when one of these errors occurred and I called changeTo<SomeOtherRegion> from the head's update method, the currently active substate update method got called immediately afterwards, despite the request to exit the region. Is this expected, and is there any way to "force" deactivation of a region immediately to avoid the region's substates getting updated? Perhaps there is a better way to achieve this? I'm trying to avoid putting the same error-checking code in every substate, since this logic is common to all of them.
Charles Cross
@spiderkeys_gitlab
I've tried a lot of alternative methods, like composing the "State" as an orthogonal region containing the "pre-update check" state and the original Composite region containing the substates (same behaviour as just doing the check/transition in the Composite's head state), as well as trying to use an Injection's preUpdate() method to call a lambda with a reference to the FSM that evokes the transition (the inner state's update methods still get called here as well).
Apologies if this just sounds like word soup to you :sweat_smile:
Charles Cross
@spiderkeys_gitlab
So far my only working approach is to create a map of StateID->PreUpdate std::functions and evoke "state_preupdate_functions fsm.stateId() ;" before each fsm.update() in the main loop.
But I was hoping to find a way to embed the logic into the FSM transition-related code self-contained
Andrew Gresyk
@andrew-gresyk

Hey @spiderkeys_gitlab
Thank you!
What you can do - is use event handling for handling errors.
There's an example in https://github.com/andrew-gresyk/HFSM2/blob/master/examples/advanced_event_handling/main.cpp for that.

You can have your FSM react() to CheckForErrors event before the recursive update()

Charles Cross
@spiderkeys_gitlab
Thanks, that seems to work pretty well!
Andrew Gresyk
@andrew-gresyk
Awesome ;)
DJuego
@DJuego
I have not used HFSM for some time but I am delighted that the development is still alive. :-) Thanks @andrew-gresyk. For me your HFSM2 still holds the gold medal in the FSM specialty.
Andrew Gresyk
@andrew-gresyk
thanks @DJuego ;)
DJuego
@DJuego
Hello, @andrew-gresyk!!
I inform you that today, after so long, I have returned to HFSM2 (and the deterministic world of finite state machines) :-).
I have started by recalling a little bit my previous experience with HFSM2.
This time I want to apply it to a wheel-based mobile robotic platform. Let's see if I succeed!
At the moment what I miss the most is the documentation, which is very incomplete. Especially what has to do with the advanced features of HFSM2. :-/
DJuego
@DJuego
The table of contents of the user's guide is promising... but lacking in content development. What a pity!
Andrew Gresyk
@andrew-gresyk
Hey @DJuego
It easy to underestimate how much time it takes to write good docs.
I can definitely use some help with writing documentation, since it always ends up being the activity with the lowest payout for me :-(
For now, I'm focusing my efforts on the next library that implements a generic planner, which takes up most of my free time.
Meanwhile, if you describe your goal - I'll do my best to assist.
Also, if you have a specific use case, I can make an example to demo how that could be done, and include it in the library distribution.
DJuego
@DJuego
Thank you very much, @andrew-gresyk !!!
DJuego
@DJuego
And happy that you are engaged in a new project related to the area!
klaudiusz223
@klaudiusz223
Hello everybody, Hello @andrew-gresyk
Thank You for great library.
I use Your library with success for embedded programming on ESP32 (xtensa core) with esp-idf.
I use the actor reference as the context, as suggested here in the chat.
Till now I have managed to overcome all problems I encountered.
But now I want to define actor as a template class and I'm struggling with this.
Here is the code

#define HFSM2_ENABLE_PLANS
#include <hfsm2/machine.hpp>
#include <doctest/doctest.h>

template<typename E>
class CtrlBTempl {
    public:
        CtrlBTempl():
            _machine(*this){};
        E f(){return E{};};
    private:
        //states
        struct RegionDisabledState;
        struct RegionEnabledState;
            struct ReadyState;
            struct SuspendedState;

        using Config  =  typename hfsm2::Config::ContextT<CtrlBTempl<E>&>;
        using Machine = typename  hfsm2::MachineT<Config>;
        using HFSM =   typename Machine::template PeerRoot<   RegionDisabledState,
                                        typename Machine::template Composite<RegionEnabledState,
                                                            ReadyState,
                                                            SuspendedState
                                        >
                            >;

        struct RegionDisabledState : HFSM::State {
            using HFSM::State::react;
            // error: ‘Control’ has not been declared
            // void enter(Control& control){control._().f(); };
            // void react(const E&, FullControl& control) {control.changeTo<RegionEnabledState>();}
        };

        struct RegionEnabledState : HFSM::State {
            using HFSM::State::react;
        };

        struct ReadyState : HFSM::State {
            using HFSM::State::react;
        };

        struct SuspendedState : HFSM::State {
            using HFSM::State::react;
        };

        typename HFSM::Instance _machine;
};




TEST_CASE("template_context_test")
{
    CtrlBTempl<int> cbt;
}
klaudiusz223
@klaudiusz223
The problem is:
error: ‘Control’ has not been declared
I would appreciate for any hints how to solve this issue.
Andrew Gresyk
@andrew-gresyk
Hi @klaudiusz223
Thank you :)
Let me have a look.
Andrew Gresyk
@andrew-gresyk

Adding using typename HFSM::State::PlanControl; to the state declarations fixes the problem.
Also, keep in mind that both enter() and exit() take PlanControl, not Control.

Here's the complete list:

void entryGuard   (GuardControl&)
void exitGuard    (GuardControl&)

void enter        (PlanControl&)    
void reenter      (PlanControl&)    
void exit         (PlanControl&)    

void update       (FullControl&)    
void react        (const TEvent&, FullControl&)    
void planSucceeded(FullControl&)    
void planFailed   (FullControl&)
klaudiusz223
@klaudiusz223
Hi @andrew-gresyk, Thank You very much.
jeste76
@jeste76
Hello,
first of all, thanks for this great statemachine implementation. I am currently using it on embedded device too.
I was just wondering: Is there any function, that is called on every statechange inside a given region? First I thought the exit method of the regions-super-state would be called in every statechange. But it seems that this is not the case.
Is there anythin like this, I can use for this purpose? Our goal is to reset a timer on every transition, so timings from one state wont affect other states. I am aware I can achieve what I want by inserting this call all of the states inside my region. But thats a lot of boilerplate.
Andrew Gresyk
@andrew-gresyk
Hi @jeste76
Thanks!
There's no function like that in a region, but!
You can use state injections to have your states share a common logic
Andrew Gresyk
@andrew-gresyk
Just keep in mind, the *Reverse*() methods are deprecated, and due removal in the next version, they are an artifact of a failed experiment :)
jeste76
@jeste76
Thanks, I will try that.
jeste76
@jeste76
Works for me, but it seems the documentation regarding this feature is a little outdated. Some hoursago I tried the same, but the docs told me to use FSM::Base to derive from.
However thanks to the testcase in your link, I got it to work.
Andrew Gresyk
@andrew-gresyk
Excellent.
Docs are outdated, unfortunately.
Best to use tests as examples, most functionality is covered there and tests are always up-to-date.
klaudiusz223
@klaudiusz223
Hi,
I experienced non deterministic application behavior using HFSM2 on ESP32. I think it was related to 2 cores of ESP32.
This manifested itself, for example, in the fact that there was no transition from one state to another even if there was no other possibility. e.g. the machine reacted to the event, but despite the react function was executed, (what could be seen in logs), and even if in react function changeTo transition was included, there was no transition to other state.
I suspect that preemption took place at that time and when there was a return to the place of execution of the program in which the transition should take place, the program did not work properly.
I pinned all my machines to only one core of CPU and now I can't reproduce this issue anymore. Previosuly it was quaite easy to reproduce.
Does anyone have experience in using HFSM2 in mulitcore embeded system? I would like to be sure that I realy solved my issue so any hint how to prove this is welcome.
@andrew-gresyk You probaly use your framework in multicore enviroment on desktop
Andrew Gresyk
@andrew-gresyk
Hi @klaudiusz223
HFSM2 leaves the multithreaded support to be implemented by the user
It's no surprise that a race condition or any other artifact of multithreaded execution would manifest itself, if no care is taken to account for that.
If are using HFSM2 in a multithreaded environment, it should probably be protected by a critical section, or some other thread / process synchronization primitive.
klaudiusz223
@klaudiusz223
Hi @andrew-gresyk Thank You for answer. I need to take a closer look at this topic.
klaudiusz223
@klaudiusz223
@andrew-gresyk I hope You, Your family and friends are safe.
Be brave and proud during this difficult time for You and Your nation.
My thoughts are with You and Your nation
Andrew Gresyk
@andrew-gresyk
Thanks for your support @klaudiusz223, it means a lot!
DJuego
@DJuego
:-O
@andrew-gresyk!, I didn't know you were Ukrainian! Now I just realized that the colors of the *FSM2 logo are those of the ukrainian flag.
DJuego
@DJuego
I find it amazing that you still find the time and the motivation to make updates to this fantastic and powerful personal project of yours.
Andrew Gresyk
@andrew-gresyk
Yes, these are the colors of the ukrainian flag :)
I'm using both libraries in my own code, and I've got no plans to abandon them yet.