Exemplo n.º 1
0
void LandsharkPaintball::Initialize(const std::string& rIpAddress)
{
  if ( GetRunning() ) {
    std::cout << "Process is already initialized, will return." << std::endl;
    return;
  }

  m_SocketFileDescriptor = socket(AF_INET, SOCK_STREAM, DEFAULT_PROTOCOL);
  if (m_SocketFileDescriptor <  0) {
    std::stringstream ss;
    ss  << "Unable to create socket, error: " << strerror(errno);
    throw std::runtime_error(ss.str());
  }

  int result = setsockopt(m_SocketFileDescriptor, SOL_SOCKET, SO_REUSEADDR, &REUSEADDR_OPTVAL, sizeof(REUSEADDR_OPTVAL));
  if (result < 0) {
    std::stringstream ss;
    ss  << "Unable to set socket option SO_REUSEADDR, error: " << strerror(errno);
    throw std::runtime_error(ss.str());
  }

  struct sockaddr_in paintballServerAddress;
  bzero((char *) &paintballServerAddress, sizeof(paintballServerAddress));
  paintballServerAddress.sin_addr.s_addr = inet_addr(rIpAddress.c_str());
  paintballServerAddress.sin_family = AF_INET;
  paintballServerAddress.sin_port = htons( m_ControllerPort );

  result = connect(m_SocketFileDescriptor, (struct sockaddr *) &paintballServerAddress,sizeof(paintballServerAddress));
  if (result < 0) {
    std::stringstream ss;
    ss  << "Unable to connect to socket with address: " << rIpAddress << ", error: " << strerror(errno);
    throw std::runtime_error(ss.str());
  }

  char buffer[BUFFER_SIZE];
  bzero(buffer, BUFFER_SIZE);
  sprintf(buffer, "u;");

  result = write(m_SocketFileDescriptor, buffer, strlen(buffer));
  if (result < 0) {
    std::stringstream ss;
    ss << "Failed to write to socket, error: " << strerror(errno) << std::endl;
    throw std::runtime_error(ss.str());
  }

  bzero(buffer, BUFFER_SIZE);

  usleep(50000);

  result = read(m_SocketFileDescriptor, buffer, BUFFER_SIZE - 1);
  if (result < 0) {
    std::stringstream ss;
    ss << "Failed to read socket, error: " << strerror(errno) << std::endl;
    throw std::runtime_error(ss.str());
  }
  std::cout << "[paintball] Paintball id: " << buffer;

}
Exemplo n.º 2
0
void LandsharkPaintball::CommunicationProcess()
{
  std::cout << "[paintball] starting thread" << std::endl;
  unsigned int loopCount = 0;
  boost::posix_time::time_duration processPeriod;
  boost::posix_time::ptime startTime = boost::posix_time::microsec_clock::local_time();

  while ( GetRunning() )
  {
    processPeriod = boost::posix_time::microsec_clock::local_time() - startTime;

    long timeToSleep = m_DesiredProcessPeriod_us - processPeriod.total_microseconds();
    if (timeToSleep > 0)
    {
      boost::this_thread::sleep(boost::posix_time::microseconds(timeToSleep));
    }

    startTime = boost::posix_time::microsec_clock::local_time();

    //if (loopCount % m_ControllerUpdateRate)
    {
      boost::mutex::scoped_lock lock( m_ControlMutex );
      switch (m_ControlMode)
      {
        case SINGLE_SHOT:
            ShotControl('s');
            break;
        case TRIPLE_SHOT:
            ShotControl('t');
            break;
        case BURST:
            ShotControl('a');
            break;
        case IDLE:
            break;
        default:
            break;
      }
      m_ControlMode = IDLE;
    }

    ++loopCount;
  } // while
  std::cout << "[paintball] stopping thread" << std::endl;
}
Exemplo n.º 3
0
void InitAtmelControlProc()
{
	//bind to this process' message queue
	Bind(ATMELMQNUM);

	//wait for synchronization message from keyboardProc to begin
	char dummyBlock[1];
	int syncSrc = KBMQNUM;
	Recv(&syncSrc, ATMELMQNUM, dummyBlock, 1);

	//local variables for message passing
	int src = -1;
	char recvBuffer[RECV_BUFFER_SIZE];
	char sendHallSensorBuffer[SEND_HS_BUFFER_SIZE];

	//initialize cursor position for hall sensor display output
	//UpdateCursorPos(&(GetRunning()->cursorPosState), 23, 2);
	int currentCursorRow = HS_CURSOR_UPPER_LIMIT;
	UpdateCursorPos(&(GetRunning()->cursorPosState), currentCursorRow, 2);


	bool initialized = false; //set to true once track hardware has been initialized

	while(true) //the main loop of the Atmel Communication Process
	{
		src = -1; //-1 means "accept messages from any source"

		//clean the receive buffer
		int j;
		for(j = 0; j < 6; j++)
		{
			recvBuffer[j] = 0;
		}

		//blocking recieve waiting for messages
		Recv(&src, ATMELMQNUM, recvBuffer, -1);//because the src is unknown, size is determined by the sender

		switch(src) //two sources are supported: HS Process and Loco process.
		{
			case HSMQNUM:
			{
				switch(recvBuffer[0])
				{
					case 0:	//reset sensors and set switches
					{
						//init HS queues of atmel 1
						SendPacket *out_packet = InitHallSensorQueueInit();
						RecvPacket *in_packet = (RecvPacket*)Allocate(sizeof(RecvPacket));
						SendAndReceivePacket(out_packet, in_packet, 1);

						//init HS queues of atmel 3
						SendPacket *out_packet2 = InitHallSensorQueueInit();
						RecvPacket *in_packet2 = (RecvPacket*)Allocate(sizeof(RecvPacket));
						SendAndReceivePacket(out_packet2, in_packet2, 3);

						if(GetRecvSuccess(in_packet) && GetRecvSuccess(in_packet2))
						{
							//reset all HS (atmel 1 only)
							SendPacket *out_packet3 = InitHallSensorAllReset();
							RecvPacket *in_packet3 = (RecvPacket*)Allocate(sizeof(RecvPacket));

							SendAndReceivePacket(out_packet3, in_packet3, 1);

							Deallocate((uint32_t)out_packet);
							Deallocate((uint32_t)in_packet);
							Deallocate((uint32_t)out_packet2);
							Deallocate((uint32_t)in_packet2);
							Deallocate((uint32_t)out_packet3);
							Deallocate((uint32_t)in_packet3);

							initialized = true;

							//send back to HS to acknowledge that HS queues were initialized
							Send(ATMELMQNUM, HSMQNUM, recvBuffer, sizeof(char));
						}
						else
						{
							char *failure = "FATAL ERROR initalizing HS queues\n\r\0";
							WriteString(failure);
						}
						break;
					}
					default://1 or 3
					{
						if(initialized) //do not act on other messages if we haven't initialized the queues yet
						{
							//query which hall sensor was triggered
							SendPacket *out_packet = InitHallSensorInput();
							RecvPacket *in_packet = (RecvPacket*)Allocate(sizeof(RecvPacket));

							SendAndReceivePacket(out_packet, in_packet, (int)recvBuffer[0]);

							//examine the rx'd packet to determine the hall sensor number
							int sensorNum = -1;
							bool successfulSPI = GetHallSensorNum(in_packet, &sensorNum);

							Deallocate((uint32_t)out_packet);
							Deallocate((uint32_t)in_packet);

							//send which hall sensor triggered to LocoProc
							if(successfulSPI)
							{
								//output the HS number to the console
								char testHSNum[4];
								testHSNum[0] = sensorNum/10 + 0x30;
								testHSNum[1] = sensorNum%10 + 0x30;
								testHSNum[2] = ' ';
								testHSNum[3] = '\0';

								UpdateCursorPos(&(GetRunning()->cursorPosState), currentCursorRow, 2);
								OutputCursorPositionSequence(&(GetRunning()->cursorPosState));
								WriteStringChar('+');
								WriteString(testHSNum);

								//make sure the stream of hall sensor printouts stays on the screen.
								currentCursorRow = (currentCursorRow == HS_CURSOR_LOWER_LIMIT)? HS_CURSOR_UPPER_LIMIT: currentCursorRow +1;

								//send reset acknowledgement to Atmel 1 for hall sensor triggering
								SendPacket *out_packet2 = InitHallSensorSingleReset(sensorNum);
								RecvPacket *in_packet2 = (RecvPacket*)Allocate(sizeof(RecvPacket));

								SendAndReceivePacket(out_packet2, in_packet2, 1);

								if(GetRecvSuccess(in_packet2))
								{
									Deallocate((uint32_t)out_packet2);
									Deallocate((uint32_t)in_packet2);
								}
								else
								{
									char *failure = "FATAL ERROR when acknowledging Hall Sensor event\n\r\0";
									WriteString(failure);
								}

								if(lastSensorTriggered != sensorNum) //Some hall sensors will double-trigger intermittently as a train passes, so ignore successive duplicates
								{
									sendHallSensorBuffer[0] = (char)sensorNum;
									//tell the LocoProc which hall sensor was just hit
									Send(ATMELMQNUM, LOCOMQNUM, sendHallSensorBuffer, SEND_HS_BUFFER_SIZE);
								}

								lastSensorTriggered = sensorNum;
							}
							else
							{
								char *failure = "FATAL ERROR when getting hall sensor number\n\r\0";
								WriteString(failure);
							}
						}
						break;
					}
				}
				break;
			}
			case LOCOMQNUM:
			{
				switch(recvBuffer[0])
				{
					case SPI_SEGMENT_SPEED_DIR://set segment speed and dir
					{
						SendPacket *out_packet = InitDirAndMagFor1Section(recvBuffer[1], recvBuffer[2], recvBuffer[3]);
						RecvPacket *in_packet = (RecvPacket*)Allocate(sizeof(RecvPacket));
						SendAndReceivePacket(out_packet, in_packet, 1);

						if(GetRecvSuccess(in_packet))
						{
							Deallocate((uint32_t)out_packet);
							Deallocate((uint32_t)in_packet);
						}
						else
						{
							char *failure = "FATAL ERROR when setting single segment speed\n\r\0";
							WriteString(failure);
						}

						break;
					}
					case SPI_SWITCH://set switch as thrown or straight
					{
						SendPacket *out_packet = InitSwitchControl(recvBuffer[1], recvBuffer[2]);
						RecvPacket *in_packet = (RecvPacket*)Allocate(sizeof(RecvPacket));
						SendAndReceivePacket(out_packet, in_packet, 2);

						if(GetRecvSuccess(in_packet))
						{
							Deallocate((uint32_t)out_packet);
							Deallocate((uint32_t)in_packet);
						}
						else
						{
							char *failure = "FATAL ERROR when using switch command\n\r\0";
							WriteString(failure);
						}
						break;
					}
					case SPI_ALL_SEGMENTS_SPEED_DIR: //and init the switches
					{
						SendPacket *out_packet = InitDirAndMagForAllSections(0, 1);//1 means CCW
						RecvPacket *in_packet = (RecvPacket*)Allocate(sizeof(RecvPacket));
						SendAndReceivePacket(out_packet, in_packet, 1);

						if(GetRecvSuccess(in_packet))
						{
							//straighten all switches
							int i;
							SendPacket *out_packet2 = InitSwitchControl(-1, 1);//1 means straight
							RecvPacket *in_packet2 = (RecvPacket*)Allocate(sizeof(RecvPacket));

							for(i = 1; i <= 9; i++)
							{
								out_packet2->arg1 = i;
								SendAndReceivePacket(out_packet2, in_packet2, 2);
							}

							Deallocate((uint32_t)out_packet);
							Deallocate((uint32_t)in_packet);
							Deallocate((uint32_t)out_packet2);
							Deallocate((uint32_t)in_packet2);

							//acknowledge to loco proc that track is initialized
							Send(ATMELMQNUM, LOCOMQNUM, recvBuffer, sizeof(char));
						}
						else
						{
							char *failure = "FATAL ERROR when setting all segments speed\n\r\0";
							WriteString(failure);
						}
						break;
					}
				}
				break;
			}
		}
	}
}