To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.robotics.rcx.legosOpen lugnet.robotics.rcx.legos in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 Robotics / RCX / legOS / 2614
2613  |  2615
Subject: 
Thread class
Newsgroups: 
lugnet.robotics.rcx.legos
Date: 
Wed, 5 Jun 2002 14:04:26 GMT
Viewed: 
2403 times
  
// Thread Class for Legos
// By Pongsak Suvanpong
// psksvp@ccs.neu.edu
// use it anyway you'd like as long as this comment is here

#ifndef __THREAD_CLASS___
#define __THREAD_CLASS___

#include <unistd.h>
#include <sys/dsensor.h>
#include <sys/battery.h>
#include <dmotor.h>
#include <dsound.h>
#include <dbutton.h>
#include <c++/Sound.H>
#include <c++/TouchSensor.H>
#include <c++/LightSensor.H>
#include <c++/RotationSensor.H>

class Thread;
class Runable
{
  friend Thread;
  bool m_bIsRunning;
public:
  Runable(void)
  {
    m_bIsRunning = false;
  }

  virtual ~Runable(void)
  {
  }

  bool IsRunning(void)
  {
    return m_bIsRunning;
  }

  virtual int Run(void)=0;

private:
  int CallBack(void)
  {
    m_bIsRunning = true;
    Run();
    m_bIsRunning = false;
  }
};

class Thread
{
protected:
  pid_t m_id;
  Runable *m_pHandler;
  bool m_bCreated;

public:
  Thread(void)
  {
    m_pHandler = (Runable *)NULL;
    m_id = 0;
    m_bCreated = false;
  }
  Thread(Runable *pHandler)
  {
    m_pHandler = pHandler;
    m_id = 0;
    m_bCreated = false;
  }

  ~Thread(void)
  {
    Stop();
  }

  pid_t Id(void)
  {
    return m_id;
  }

  void SetRunable(Runable *pHandler)
  {
    m_pHandler = pHandler;
  }

  bool Start(priority_t priority = PRIO_NORMAL, size_t stackSize =
DEFAULT_STACK_SIZE)
  {
    if(NULL != m_pHandler)
    {
      char *argv[2];
      argv[0] = (char *)m_pHandler;
      argv[1] = (char *)NULL;
      m_id = ::execi(Proc, 2, argv, priority, stackSize);
      m_bCreated = ( m_id == -1 ? false : true);
      return m_bCreated;
    }
    else
    {
      return false;
    }
  }

  void Stop(void)
  {
    if(true == m_bCreated)
    {
      ::kill(m_id);
      m_bCreated = false;
    }
  }

  bool IsRunning(void)
  {
    return m_pHandler->IsRunning();
  }

private:
  static int Proc(int argc, char **argv)
  {
    Runable *pcHandler = reinterpret_cast<Runable*>(argv[0]);
    return pcHandler->CallBack();
  }
};


class SensorMonitor :public Runable
{
protected:
  unsigned char m_iFreq; //millisec
  Thread m_myThread;
public:
  SensorMonitor(void) :Runable()
  {
    m_myThread.SetRunable(this);
  }

  ~SensorMonitor(void)
  {
    StopMonitor();
  }

  virtual bool StartMonitor(unsigned char iFreq=100)
  {
    m_iFreq = iFreq;
    return m_myThread.Start();
  }

  virtual void StopMonitor(void)
  {
    m_myThread.Stop();
  }

  int Run(void)
  {
    while(true)
    {
      if(false == Monitor())
        return 1;
      else
        ::msleep(m_iFreq);
    }
  }

protected:
  virtual bool Monitor(void) = 0;
};

class BatteryMonitor :public SensorMonitor
{
  int m_iLow;
public:
  BatteryMonitor(const int iLowThreadhold=300) :SensorMonitor()
  {
    m_iLow = iLowThreadhold;
  }

  int CurrentValue(void)
  {
    ::battery_refresh();
    return ::get_battery_mv();
  }

  virtual bool OnLow(void)
  {
    return true;
  }

protected:
  bool Monitor(void)
  {
    if(m_iLow >= CurrentValue())
      return OnLow();
    else
      return true;
  }
};

class TouchSensorMonitor :public SensorMonitor
{
  TouchSensor *m_pTheSensor;
public:
  TouchSensorMonitor(const Sensor::Port port):SensorMonitor()
  {
    m_pTheSensor = new TouchSensor(port);
  }

  ~TouchSensorMonitor(void)
  {
    delete m_pTheSensor;
  }

  virtual bool OnPressed(void)
  {
    return true;
  }

protected:
  bool Monitor(void)
  {
    if(true == m_pTheSensor->pressed())
      return OnPressed();
    else
      return true;
  }

};

class LightSensorMonitor :public SensorMonitor
{
  LightSensor *m_pTheSensor;
  unsigned int m_iCurValue;
public:
  LightSensorMonitor(const Sensor::Port port) :SensorMonitor()
  {
    m_iCurValue = 0;
    m_pTheSensor = new LightSensor(port);
  }

  ~LightSensorMonitor(void)
  {
    delete m_pTheSensor;
  }

  unsigned int CurrentValue(void)
  {
    return m_pTheSensor->get();
  }

  virtual bool OnChange(const unsigned int iNewValue)
  {
    return true;
  }

protected:
  bool Monitor(void)
  {
    unsigned int iNewValue = m_pTheSensor->get();
    if(m_iCurValue != iNewValue)
    {
      m_iCurValue = iNewValue;
      return OnChange(m_iCurValue);
    }
    else
      return true;
  }

};

class RotationSensorMonitor :public SensorMonitor
{
  RotationSensor *m_pTheSensor;
  int m_iCurValue;
protected:
  RotationSensorMonitor(const Sensor::Port port, const int pos=0)
:SensorMonitor()
  {
    m_iCurValue = 0;
    m_pTheSensor = new RotationSensor(port, pos);
  }

  ~RotationSensorMonitor(void)
  {
    delete m_pTheSensor;
  }

  int CurrentValue(void)
  {
    return m_pTheSensor->pos() % 16;
  }

  virtual bool OnRotate(const int iNewValue)
  {
    return true;
  }

  bool Monitor(void)
  {
    int iNewValue = CurrentValue();
    if(m_iCurValue != iNewValue)
    {
      m_iCurValue = iNewValue;
      return OnRotate(m_iCurValue);
    }
    else
      return true;
  }
};

#endif


///////////////////////////////////////////////
//// example
//////////////////////////////////////////////
#include <c++/Thread.H>

/////////////////////////////////////////////////
class MyTouchMonitor :public TouchSensorMonitor
{
public:
  MyTouchMonitor(const Sensor::Port port)
    :TouchSensorMonitor(port)
  {
  }

  bool OnPressed(void)
  {
    Sound::beep();
    return true;
  }
};

/////////////////////////////////////////////////
class MyLightMonitor :public LightSensorMonitor
{
public:
  MyLightMonitor(const Sensor::Port port)
    :LightSensorMonitor(port)
  {
  }

  bool OnChange(const unsigned int iNewValue)
  {
    ::cputw(iNewValue);
    return true;
  }
};

/////////////////////////////////////////////////
class MyRotMonitor :public RotationSensorMonitor
{
public:
  MyRotMonitor(const Sensor::Port port, const int pos=0)
    :RotationSensorMonitor(port, pos)
  {
  }

  virtual bool OnRotate(const int iNewValue)
  {
    ::cputw(iNewValue);
    return true;
  }
};



int main(int argc, char *argv[])
{
  //MyLightMonitor mon1(TouchSensor::S3);
  //mon1.StartMonitor();
  MyRotMonitor mon1(Sensor::S3);
  mon1.StartMonitor();
  MyTouchMonitor mon(Sensor::S1);
  mon.StartMonitor();
  ::getchar();

  return 0;
}



1 Message in This Thread:

Entire Thread on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact
    

Custom Search

©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR