Agent behaviour

i have another problem...
quickly...
this sketch aim to:
1 - sense events from input and store them to a vector Vector (the first 2 are generated internally by generateEvent(...))
2 - select an event from the vector, check if there is a plan that satisfy the event, and if positive, create a new intention with reference of event and plan
3 - put the intention to a vector
4 - take an intention from the vector and execute 1 plan's action by the using of Protothread library
->start from 1.

the circuit to try this sketch is just a button on pin 3 and the output in on serial port

it's all ok, the 2 events are correctly generated, correctly stored, and processed.
but when i push the button, it seems like it goes out of memory (or something else) and seems the watchdog reset,
starting from new.

Can anyone try this out and check if there are some problems with pointer?
thank you!!

Agent1.zip (8.14 KB)

What is Agentduino ? Is it a code generator you're writing ?

Also, is this one the PT library you're using ?

http://www.sics.se/~adam/pt/

Ok, tried you code. It restarts almost every time pin 3 goes high. The code is quite complex, and has no comments :wink: so it's difficult to make a detailed analysis... IMHO it has too many new()s, in other words it looks like it's written with a normal PC in mind, not a 2K uP. My suggestion is to carefully review every allocation and pointer passed around. Also, memory consumption should be monitored.

An example:

/* Simple Select Event Function, implementing FIFO Event queue */
bool selectNextEvent(Vector<Event> *queue, Event *next) {
	if ( queue->size() > 0 ) {
		Event nE;
		queue->getFirstAndRemove(&nE);
		*next=nE;
		return true;
	}
	return false;
}

(Please correct me if I'm wrong...)

You allocate the local variable nE.
You pass it by address to getFirstAndRemove.
You copy nE contents to *next.

Wouldn't it be the same to just pass "next" to getFirstAndRemove(), thus avoiding a (pretty useless, it seems) local variable ?

My 2 cents...

HTH

tuxduino:
What is Agentduino ? Is it a code generator you're writing ?

I've been discovered :smiley: but the name now is Agentino, or better AgentIno...
I hope to show you really soon, it's quite smart, easy (and exciting!)

tuxduino:
Also, is this one the PT library you're using ?

Svensk forskning för hållbar tillväxt| RISE

Yes, exactly that one!

tuxduino:
Ok, tried you code. It restarts almost every time pin 3 goes high. The code is quite complex, and has no comments :wink: so it's difficult to make a detailed analysis... IMHO it has too many new()s, in other words it looks like it's written with a normal PC in mind, not a 2K uP. My suggestion is to carefully review every allocation and pointer passed around. Also, memory consumption should be monitored.

An example:

/* Simple Select Event Function, implementing FIFO Event queue */

bool selectNextEvent(Vector *queue, Event *next) {
if ( queue->size() > 0 ) {
Event nE;
queue->getFirstAndRemove(&nE);
*next=nE;
return true;
}
return false;
}




(Please correct me if I'm wrong...)

You allocate the local variable nE.
You pass it by address to getFirstAndRemove.
You copy nE contents to *next.

Wouldn't it be the same to just pass "next" to getFirstAndRemove(), thus avoiding a (pretty useless, it seems) local variable ?

My 2 cents...

HTH

Ok... i have to admin... i have done so many try that i lost control :smiley:
It was my thought i had in last days that, and maybe i found the problem...
The problem is finally this...
I have "Plan" that is an abstract class, that i would like to use as an interface Java-like
to reference other plans (PlanPiano1, PlanPiano2, ... PlanPianoN) that extend Plan and ovverride act().
Later i would like to have one single vector of Plan, instantiated each one with object of the various plans.
But it's seems impossible... i make another try, with the following code (as i remember, didn't have it right now...)

Plan * vec[3];  //Or Plan **vec;
vec[0]= new PlanPiano1();
vec[1]= new PlanPiano2();
vec[2]= new PlanPiano2();

vec[0]->act();
vec[1]->act();
vec[2]->act();

And it does restart again... It seems like C++ can use abstract class to reference child class in a vector... or similar, i'm not expert on that language.
What do you think?
The fact that you try my program is very nice... very helpful community, thank you so much!

P.S. in any case i changed my structure of the program, now it works, but in a not elegant way as it could be with abstract class :smiley:

Arduino uses standard C++ (i.e., the compiler is gcc), and just adds functions that make it easy to work with the particular hardware platform they've built around the atmega 328. For example, you can set and read digital pin status without knowing what a port register is.
Being standard C++, inheritance works like it does everywhere else.
The main difference with "normal", i.e. PC-style, C++ programming is the very low memory available on the atmega 328. I suspect the liberal use of "new" is making you run out of memory...
In other words, I don't think inheritance was the thing that made you program crash and restart.
Anyway, I'm glad you've finally made it work.

Ok...
quick try... Explain me this...
Why this example doesn't work

class A {
    public:
      virtual void f() { Serial.println("A"); }
};

class B : public A {
    protected:
     char *firstMember;
     int secondMember;
    public:
      virtual void f() { Serial.println("B"); }
};

class C : public A {
    protected:
     double firstMember;
     int secondMember;
    public:
      virtual void f() { Serial.println("C"); }
};
class D : public A {
    protected:
     double firstMember;
     int secondMember;
     int *thirdMember;
    public:
      virtual void f() { Serial.println("D"); }
};

void setup() {
    A* obj;    // base-class pointer
    A **obj2;
    Serial.begin(9600);
    Serial.println("Start");
    obj = new A();
    obj->f();         // base class version
    obj = new B();
    obj->f();        // child class version
    obj = new C();
    obj->f();        // child class version
    obj = new D();
    obj->f();        // child class version
    
     /*  Until here it works  */
    obj2[0] = new B();
    obj2[1] = new C();
    obj2[2] = new D();
    
    for (int i=0; i<3; i++)
      obj2[i]->f();
}

void loop() {
}

and the same code with different obj2 instantiation works:
A* obj2[3];

What's the point i'm missing?

This

A* obj2[3];

allocates an array of 3 pointers.

This

A** obj2;

Is just a pointer. Nothing is allocated. Therefore when you assign something to obj2[0] you're writing unallocated memory, i.e. corrupting it.