/// @file motion_behaviors.cc #include "behavior/motion_behaviors.hh" #include "mind/mind.hh" #include "eyebot_behavior_types.h" #include "eyebot_behavior_sem.h" namespace EyeMind { /** * VWMove */ VWMove::VWMove() : Behavior() { memset(&speed, 0, sizeof(SpeedType)); Mind::Register(*this); } void VWMove::Feed(SignalLink& l) { if ( !l.Generic() ) reinterpret_cast(l).Speed(speed); Behavior::Feed(l); } int VWMove::Execute() { unsigned s=0; unsigned total_signal = 0; // reset the output speed memset(&speed, 0, sizeof(SpeedType)); // Find the maximum input signal SpeedLink* sl = reinterpret_cast(FindMaxNonGenericInputSignal()); if (sl==NULL) return EXCITE_IDLE; // calculate weighted average of incoming signals SignalLink* i = inlinks.Begin(); while (i!=NULL) { if(!i->Generic()) { sl = reinterpret_cast(i); s = sl->Signal(); speed.v += (sl->Speed().v)*s; speed.w += (sl->Speed().w)*s; total_signal+=s; } i = ++inlinks; } if(total_signal) { speed.v/=total_signal; speed.w/=total_signal; } return EXCITE_IDLE; }; VWMove& operator>>(SpeedLink& l, VWMove& o) { SignalLinkOutputToBehavior(l,o); return o; } VWMove& operator<<(SpeedLink& l, VWMove& i) { SignalLinkInputToBehavior(l,i); return i; } SpeedLink& operator>>(VWMove& n, SpeedLink& o) { BehaviorOutputToSignalLink(n,o); return o; } SpeedLink& operator<<(VWMove& n, SpeedLink& i) { BehaviorInputToSignalLink(n,i); return i; } VWDrive::VWDrive() : Behavior() { speed = NULL; Mind::Register(*this); } VWDrive& operator>>(SpeedLink& l, VWDrive& o) { SignalLinkOutputToBehavior(l,o); o.speed = &l; return o; } SpeedLink& operator<<(VWDrive& n, SpeedLink& i) { BehaviorInputToSignalLink(n,i); n.speed = &i; return i; } VWDriveTwoWheeled::VWDriveTwoWheeled() : VWDrive(), left_controller(MotorControlLeft::I()), right_controller(MotorControlRight::I()) { w_l = 0; w_r = 0; // Attach output FloatLinks BehaviorOutputToSignalLink(*this, left); BehaviorOutputToSignalLink(*this, right); // Attach controllers to FloatLinks left_controller << left; right_controller << right; // pre-feed the FloatLinks left.Float(0); right.Float(0); //get data from hdt twowheeldrive_bt *tw = (twowheeldrive_bt*) HDTFindEntry(B_TWOWHEELDRIVE,0); if(tw==NULL) OSPanic("Cannot find\n drive data\n"); radius = tw->radius; width = tw->width; vwdrive_bt *vw = (vwdrive_bt*) HDTFindEntry(B_VWDRIVE,0); if(vw==NULL) OSPanic("Cannot find\n vwdrive data\n"); left_controller.Params(vw->Kp, vw->reset_time, vw->rate_time); right_controller.Params(vw->Kp, vw->reset_time, vw->rate_time); left_controller.Limits(vw->limit_lo, vw->limit_hi); right_controller.Limits(vw->limit_lo, vw->limit_hi); // Attach the controllers to the active Id Id& id = *Mind::ActiveId(); id >> left_controller; id >> right_controller; } int VWDriveTwoWheeled::Execute() { SpeedType s = {0.0,0.0}; //convert v, w speeds to rad/s for two wheels if(speed==NULL) return EXCITE_NONE; s = speed->Speed(); float w_straight = s.v / radius; w_l = w_straight - s.w / radius * (width / 2.0); w_r = w_straight + s.w / radius * (width / 2.0); // pre-feed the FloatLinks left.Float(w_l); right.Float(w_r); return 1; } Wander::Wander() { memset(&speed,0,sizeof(SpeedType)); wander_bt *wr = (wander_bt*) HDTFindEntry(B_WANDER,0); if(wr==NULL) OSPanic("Cannot find\n wander data\n"); v = wr->v; w = wr->w; period = (unsigned) wr->period; count = 0; sign = 1; } int Wander::Execute() { if (++count % period == 0) { if(speed.v > 0) { speed.v = 0; speed.w = sign * w; sign *= -1; } else { speed.v = v; speed.w = 0.0; } count=0; } return EXCITE_IDLE; } void Wander::Feed(SignalLink &l) { if (!l.Generic()) { reinterpret_cast(l).Speed(speed); } Behavior::Feed(l); } SpeedLink& operator>>(Wander& n, SpeedLink& o) { BehaviorOutputToSignalLink(n,o); return o; } Wander& operator<<(SpeedLink& l, Wander& i) { SignalLinkInputToBehavior(l,i); return i; } VWMotion::VWMotion() : Behavior() { speed.v = 0; speed.w = 0; } VWMotion::VWMotion(int device) : Behavior() { motion_bt* mt = (motion_bt*)HDTFindEntry(B_MOTION, (DeviceSemantics) device); OSPanicIf(mt==NULL,"Cannot find motion data\n"); speed.v = mt->v; speed.w = mt->w; } int VWMotion::Execute() { return EXCITE_IDLE; } void VWMotion::Feed(SignalLink &l) { if (!l.Generic()) { reinterpret_cast(l).Speed(speed); } Behavior::Feed(l); } SpeedLink& operator>>(VWMotion& n, SpeedLink& o) { BehaviorOutputToSignalLink(n,o); return o; } }; // namespace EyeMind