Beispiel #1
0
 /// <summary>
 /// Return PulsationBehaviour with appropriate frequency.
 /// Frequency is defined by the position of the HaptiQ within this HapticLink
 /// </summary>
 /// <param name="haptiQ"></param>
 /// <returns></returns>
 protected override IBehaviour chooseBehaviour(HaptiQ haptiQ)
 {
     double highFrequency = _hasDirection ? 100 * (Helper.distanceBetweenTwoPoints(haptiQ.position, _pair.Item2) /
         Helper.distanceBetweenTwoPoints(_pair.Item2, _pair.Item1)) : DEFAULT_FREQUENCY;
     IBehaviour behaviour = new PulsationBehaviour(haptiQ, new Tuple<Point, Point>(_pair.Item1, _pair.Item2), highFrequency);
     return behaviour;
 }
Beispiel #2
0
 /// <summary>
 /// Constructor for edge-corner behaviour. 
 /// </summary>
 /// <param name="haptiQ"></param>
 /// <param name="lines">Geometric lines indicating the direction</param>
 public EdgeCornerBehaviour(HaptiQ haptiQ, List<Tuple<Point, Point>> lines)
     : base(haptiQ)
 {
     _lines = lines;
     TIME = 0;
     highPosition = HIGH_POSITION_PERCENTAGE;
     lowPosition = MIN_POSITION;
 }
Beispiel #3
0
 /// <summary>
 /// Constructor of the Linear behaviour.
 /// Height of the actuators is specified by the ratio value
 /// </summary>
 /// <param name="haptiQ"></param>
 /// <param name="segment"></param>
 /// <param name="ratio"></param>
 public LinearBehaviour(HaptiQ haptiQ, Tuple<Point, Point> segment, double ratio)
     : base(haptiQ)
 {
     _segment = segment;
     TIME = 0;
     highPosition = HIGH_POSITION_PERCENTAGE * ratio;
     lowPosition = 0;
 }
Beispiel #4
0
 /// <summary>
 /// Constructor of the pulsation behaviour.
 /// Make the specified actuators to pulse at a constant interval 
 /// </summary>
 /// <param name="haptiQ"></param>
 /// <param name="segment"></param>
 /// <param name="frequency"></param>
 public PulsationBehaviour(HaptiQ haptiQ, Tuple<Point, Point> segment, double frequency)
     : base(haptiQ)
 {
     _segment = segment;
     _frequency = frequency;
     TIME = 0;
     highPosition = HIGH_POSITION_PERCENTAGE;
     lowPosition = 0;
 }
Beispiel #5
0
        /// <summary>
        /// Behaviour constructor
        /// </summary>
        /// <param name="haptiQ"></param>
        public Behaviour(HaptiQ haptiQ)
        {
            this.actuators = haptiQ.getActuators();
            this.position = haptiQ.position;
            this.orientation = haptiQ.orientation;

            actuatorsDict = new Dictionary<int, Actuator>();
            foreach (Actuator actuator in actuators)
            {
                actuatorsDict[actuator.getId()] = actuator;
            }
        }
Beispiel #6
0
 /// <summary>
 /// Output information content via audio if input was received 
 /// for a device currently in this haptic rectangle
 /// </summary>
 /// <param name="haptiQ"></param>
 /// <param name="gestureType"></param>
 public override void handlePress(HaptiQ haptiQ, PRESSURE_GESTURE_TYPE gestureType)
 {
     Tuple<STATE, IBehaviour> HaptiQState = _HaptiQBehaviours.ContainsKey(haptiQ.getID()) ? _HaptiQBehaviours[haptiQ.getID()] : null;
     if (pointIsInside(haptiQ.position) && HaptiQState != null && HaptiQState.Item1 == STATE.down)
     {
         if (_action != null)
         {
             _action.run(haptiQ.getID(), gestureType, haptiQ.getCurrentPressureData());
         }
         else
         {
             SpeechOutput.Instance.speak(information);
         }
     }
 }
Beispiel #7
0
        /// <summary>
        /// Constructor for a NotificationBehaviour. 
        /// </summary>
        /// <param name="haptiQ"></param>
        /// <param name="frequency"></param>
        public NotificationBehaviour(HaptiQ haptiQ, double frequency)
            : base(haptiQ)
        {
            TIME = 0;
            _frequency = frequency;

            _positions = new double[actuators.Count(), 2];
            double position = 0.0;
            for (int i = 0; i < _positions.GetLength(0); i++)
            {
                position += 1.0 / (_positions.GetLength(0) - 1);
             
                _positions[i, 0] = position;
                _positions[i, 1] = 1;
            }
        }
Beispiel #8
0
        /// <summary>
        /// Constructor for a BasicBehaviour. 
        /// </summary>
        /// <param name="haptiQ"></param>
        /// <param name="type"></param>
        /// <param name="frequency"></param>
        public BasicBehaviour(HaptiQ haptiQ, TYPES type, double frequency)
            : base(haptiQ)
        {
            _type = type;
            TIME = 0;
            _frequency = frequency;
            highPosition = DEFAULT_POS;
            lowPosition = MIN_POSITION;

            if (type == TYPES.flat)
            {
                _actuatorsToActivate = 0;
            }
            else if (type == TYPES.max)
            {
                _actuatorsToActivate = (int) (Math.Pow(2, actuators.Count()) - 1);
            }
            else
            {
                 _actuatorsToActivate = 0;
                Helper.Logger("HaptiQ_API.BasicBehaviour.BasicBehaviour::type " + type + " undefined");
            }
        }
Beispiel #9
0
 /// <summary>
 /// Constructor for a BasicBehaviour.
 /// </summary>
 /// <param name="haptiQ"></param>
 /// <param name="type"></param>
 public BasicBehaviour(HaptiQ haptiQ, TYPES type)
     : this(haptiQ, type, DEFAULT_FREQUENCY) { }
Beispiel #10
0
 /// <summary>
 /// Return a notificationBehaviour with frequency dictated by the 
 /// position of the HaptiQ within this shape
 /// </summary>
 /// <param name="haptiQ"></param>
 /// <returns></returns>
 protected override IBehaviour chooseBehaviour(HaptiQ haptiQ)
 {
     return new NotificationBehaviour(haptiQ, getFrequency(haptiQ.position));
 }
Beispiel #11
0
 /// <summary>
 /// Return an Edge-Corner behaviour based on the position of the haptiQ
 /// on this polyline
 /// </summary>
 /// <param name="haptiQ"></param>
 /// <returns></returns>
 protected override IBehaviour chooseBehaviour(HaptiQ haptiQ)
 {
     return new EdgeCornerBehaviour(haptiQ, _lines);
 }
Beispiel #12
0
        /// <summary>
        /// Handle behaviours on input
        /// </summary>
        /// <param name="haptiQ"></param>
        /// <returns></returns>
        public Tuple<BEHAVIOUR_RULES, IBehaviour, IBehaviour> handleInput(HaptiQ haptiQ)
        {
            if (this.Parent != null)
            {
                Tuple<STATE, IBehaviour> HaptiQState = _HaptiQBehaviours.ContainsKey(haptiQ.getID()) ? _HaptiQBehaviours[haptiQ.getID()] : null;
                if (pointIsInside(haptiQ.position))
                {
                    IBehaviour prevBehaviour = HaptiQState != null ? HaptiQState.Item2 : null;
                    IBehaviour currentBehaviour = chooseBehaviour(haptiQ);
                    currentBehaviour.updateNext(prevBehaviour);

                    BEHAVIOUR_RULES rule = BEHAVIOUR_RULES.SUBS;
                    if (currentBehaviour.Equals(prevBehaviour))
                    {
                        rule = BEHAVIOUR_RULES.NOPE;
                    }
                    _HaptiQBehaviours[haptiQ.getID()] = new Tuple<STATE, IBehaviour>(STATE.down, currentBehaviour);
                    return new Tuple<BEHAVIOUR_RULES, IBehaviour, IBehaviour>(rule, currentBehaviour, prevBehaviour);
                }
                else if (HaptiQState != null && HaptiQState.Item1 == STATE.down)
                {
                    IBehaviour prevBehaviour = HaptiQState.Item2;
                    IBehaviour currentBehaviour = new BasicBehaviour(haptiQ, BasicBehaviour.TYPES.flat);
                    BEHAVIOUR_RULES rule = BEHAVIOUR_RULES.SUBS;
                    if (currentBehaviour.Equals(prevBehaviour))
                    {
                        rule = BEHAVIOUR_RULES.NOPE;
                    }
                    _HaptiQBehaviours[haptiQ.getID()] = new Tuple<STATE, IBehaviour>(STATE.up, currentBehaviour);
                    return new Tuple<BEHAVIOUR_RULES, IBehaviour, IBehaviour>(rule, currentBehaviour, prevBehaviour);
                }
            }

            Tuple<BEHAVIOUR_RULES, IBehaviour, IBehaviour> retval = 
                new Tuple<BEHAVIOUR_RULES, IBehaviour, IBehaviour>(BEHAVIOUR_RULES.REMOVE,
                    _HaptiQBehaviours.ContainsKey(haptiQ.getID()) ? _HaptiQBehaviours[haptiQ.getID()].Item2 : null, null);
            _HaptiQBehaviours[haptiQ.getID()] = new Tuple<STATE, IBehaviour>(STATE.up, null);
            return retval;
        }
Beispiel #13
0
        /// <summary>
        /// Return appropriate behaviour based on the position of the HaptiQ within 
        /// this HapticRectangle
        /// </summary>
        /// <param name="haptiQ"></param>
        /// <returns></returns>
        protected override IBehaviour chooseBehaviour(HaptiQ haptiQ)
        {
            IBehaviour behaviour = null;

            Point bottomLeft = new Point(x, y + height);
            Point bottomRight = new Point(x + width, y + height);
            Point topLeft = new Point(x, y);
            Point topRight = new Point(x + width, y);

            List<Tuple<Point, Point>> lines = new List<Tuple<Point, Point>>();
            if (pointIsCloseToSegment(haptiQ.position, bottomLeft, bottomRight, CORNER_NEARNESS_TOLLERANCE) &&
                pointIsCloseToSegment(haptiQ.position, bottomLeft, topLeft, CORNER_NEARNESS_TOLLERANCE)) // bottom-left corner
            {
                lines.Add(new Tuple<Point, Point>(bottomLeft, bottomRight));
                lines.Add(new Tuple<Point, Point>(bottomLeft, topLeft));
            }
            else if (pointIsCloseToSegment(haptiQ.position, topLeft, topRight, CORNER_NEARNESS_TOLLERANCE) &&
                    pointIsCloseToSegment(haptiQ.position, topLeft, bottomLeft, CORNER_NEARNESS_TOLLERANCE)) // top-left corner
            {
                lines.Add(new Tuple<Point, Point>(topLeft, topRight));
                lines.Add(new Tuple<Point, Point>(topLeft, bottomLeft));
            }
            else if (pointIsCloseToSegment(haptiQ.position, topRight, topLeft, CORNER_NEARNESS_TOLLERANCE) &&
                pointIsCloseToSegment(haptiQ.position, topRight, bottomRight, CORNER_NEARNESS_TOLLERANCE)) // top-right corner
            {
                lines.Add(new Tuple<Point, Point>(topRight, topLeft));
                lines.Add(new Tuple<Point, Point>(topRight, bottomRight));
            }
            else if (pointIsCloseToSegment(haptiQ.position, bottomRight, topRight, CORNER_NEARNESS_TOLLERANCE) &&
                pointIsCloseToSegment(haptiQ.position, bottomRight, bottomLeft, CORNER_NEARNESS_TOLLERANCE)) // bottom-right corner
            {
                lines.Add(new Tuple<Point, Point>(bottomRight, topRight));
                lines.Add(new Tuple<Point, Point>(bottomRight, bottomLeft));
            }
            else if (pointIsCloseToSegment(haptiQ.position, bottomLeft, bottomRight, NEARNESS_TOLLERANCE)) // horizontal
            {
                lines.Add(new Tuple<Point, Point>(bottomLeft, bottomRight));
            }
            else if (pointIsCloseToSegment(haptiQ.position, topLeft, topRight, NEARNESS_TOLLERANCE)) // horizontal
            {
                lines.Add(new Tuple<Point, Point>(topLeft, topRight));
            }
            else if (pointIsCloseToSegment(haptiQ.position, topLeft, bottomLeft, NEARNESS_TOLLERANCE)) // vertical
            {
                lines.Add(new Tuple<Point, Point>(topLeft, bottomLeft));
            }
            else if (pointIsCloseToSegment(haptiQ.position, topRight, bottomRight, NEARNESS_TOLLERANCE)) // vertical
            {
                lines.Add(new Tuple<Point, Point>(topRight, bottomRight));
            }
            else
            {
                behaviour = new BasicBehaviour(haptiQ, BasicBehaviour.TYPES.max);
            }
                   
            if (behaviour == null)
            {
                behaviour = new EdgeCornerBehaviour(haptiQ, lines);
            }
               
            return behaviour;
        }
Beispiel #14
0
 /// <summary>
 /// Return a behaviour for this haptic shape
 /// </summary>
 /// <param name="haptiQ"></param>
 /// <returns></returns>
 protected abstract IBehaviour chooseBehaviour(HaptiQ haptiQ);
Beispiel #15
0
        /// <summary>
        /// Registers an HaptiQ.
        /// Returns not updated id if HaptiQ could not be added.
        /// </summary>
        /// <param name="haptiQ"></param>
        /// <returns> unique id assigned to HaptiQ </returns>
        public UInt32 addHaptiQ(HaptiQ haptiQ)
        {
            if (haptiQ == null)
            {
                Helper.Logger("HaptiQ_API.HaptiQsManager.addHaptiQ:: HaptiQ is null");
                return _nextID;
            }
            else
            {
                haptiQ.PositionChanged += new PositionEventHandler(HaptiQ_PositionChanged);
                haptiQ.PressureInput += new PressureInputEventHandler(HaptiQ_PressureInput);
                haptiQ.ActuatorPositionChanged += new ActuatorPositionEventHandler(HaptiQ_ActuatorPositionChanged);
                haptiQ.PressureGesture += new PressureGestureEventHandler(pressureGestureHaptiQChanged);

                _HaptiQsDictionary.Add(_nextID, haptiQ);
                _inputIdentifiersToHaptiQs.Add(haptiQ.configuration.inputIdentifier, _nextID);
                return _nextID++;
            }
        }
Beispiel #16
0
 private void handleBehaviours(HaptiQ haptiQ, Point point, double orientation)
 {
     // Notify observers
     lock (_syncObj)
     {
         Parallel.ForEach(_hapticObjectObservers, observer =>
         {
             Tuple<BEHAVIOUR_RULES, IBehaviour, IBehaviour> behaviour = observer.handleInput(haptiQ);
             switch (behaviour.Item1)
             {
                 case BEHAVIOUR_RULES.ADD:
                     haptiQ.addBehaviour(behaviour.Item2);
                     break;
                 case BEHAVIOUR_RULES.REMOVE:
                     haptiQ.removeBehaviour(behaviour.Item2);
                     break;
                 case BEHAVIOUR_RULES.SUBS:
                     // Substitute behaviours
                     haptiQ.removeBehaviour(behaviour.Item3);
                     haptiQ.addBehaviour(behaviour.Item2);
                     break;
                 case BEHAVIOUR_RULES.NOPE:
                     // Do nothing
                     break;
                 default:
                     Helper.Logger("HaptiQ_API.HaptiQsManager.handleBehaviours:: observed returned unknown rule for behaviour");
                     break;
             }
         });
     }
 }
Beispiel #17
0
 private void createHaptiQs(List<Configuration> configurations)
 {
     if (configurations != null && configurations.Count > 0)
     {
         foreach (Configuration configuration in configurations)
         {
             HaptiQ haptiQ = new HaptiQ(_nextID, configuration);
             addHaptiQ(haptiQ); // Add this HaptiQ to HaptiQsManager appropriate data structure
         }
     }
 }
Beispiel #18
0
  /// <summary>
 /// Constructor for a NotificationBehaviour.
 /// </summary>
 /// <param name="haptiQ"></param>
 public NotificationBehaviour(HaptiQ haptiQ)
     : this(haptiQ, DEFAULT_FREQUENCY) { }
Beispiel #19
0
 /// <summary>
 /// Returns an edge-corner behaviour based on the position of the HaptiQ
 /// on the HapticLine
 /// </summary>
 /// <param name="haptiQ"></param>
 /// <returns></returns>
 protected override IBehaviour chooseBehaviour(HaptiQ haptiQ)
 {
     List<Tuple<Point, Point>> lines = new List<Tuple<Point, Point>>();
     lines.Add(_pair);
     return new EdgeCornerBehaviour(haptiQ, lines);
 }
Beispiel #20
0
 /// <summary>
 /// Handle an actuator press. 
 /// Note: Multiple presses are not supported, yet.
 /// </summary>
 /// <param name="haptiQ"></param>
 /// <param name="gestureType"></param>
 public virtual void handlePress(HaptiQ haptiQ, PRESSURE_GESTURE_TYPE gestureType)
 {
     Tuple<STATE, IBehaviour> HaptiQState = _HaptiQBehaviours.ContainsKey(haptiQ.getID()) ? _HaptiQBehaviours[haptiQ.getID()] : null;
     if (pointIsInside(haptiQ.position) && HaptiQState != null && HaptiQState.Item1 == STATE.down)
     {
         if (_action != null)
         {
             _action.run(haptiQ.getID(), gestureType, haptiQ.getCurrentPressureData());
         }
     }
 }