⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcvideoserver.cpp

📁 good luck to everyone!
💻 CPP
字号:
/********************************************************************************
*  Project   		: FIRST Motor Controller
*  File Name  		: PCVideoServer.cpp
*  Contributors   	: SVK, ELF
*  Creation Date 	: November 30, 2008
*  Revision History	: Source code & revision history maintained at sourceforge.WPI.edu
*  File Description	: C++ Axis camera control for the FIRST Vision API
*/
/*----------------------------------------------------------------------------*/
/*        Copyright (c) FIRST 2008.  All Rights Reserved.                     */
/*  Open Source Software - may be modified and shared by FRC teams. The code  */
/*  must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/

#include <vxWorks.h>

#include "sockLib.h"
#include "inetLib.h"
#include "hostLib.h"

#include "AxisCamera.h"
#include "BaeUtilities.h"
#include "FrcError.h"
#include "chipobject/NiRioStatus.h"
#include "Task.h"
#include "Timer.h"
#include "Utility.h"

#include "PCVideoServer.h"

bool g_stopImageToPCServer=false;

/**
@brief Implements an object that automatically does a close on a
camera socket on destruction.
*/
class ScopedSocket {
public:
    ScopedSocket(int camSock, const ErrorBase* errorBase) :
        m_camSock(camSock)
    {
        if (errorBase->StatusIsFatal()) {
            return;
        }
        if (m_camSock == ERROR) {
            wpi_setError(*errorBase, ERR_CAMERA_SOCKET_CREATE_FAILED);
            return;
        }
    }

    ~ScopedSocket() {
        if (m_camSock != ERROR) {
            close(m_camSock);
        }
    }
    //  Cast to int allows you to pass this to any function that
    //  takes the socket as an int.
    operator int() const {
        return m_camSock;
    }

private:
    int m_camSock;
};

//============================================================================
//  PCVideoServer
//============================================================================

/**
@brief Constructor.
*/
PCVideoServer::PCVideoServer(void)
	: m_task("PCVideo", (FUNCPTR)ImageToPCServer)
{
    try {
        // Start the image communication task.
        StartPcTask();
        if (StatusIsFatal()) {
            throw GetError().GetCode();
        }
    }
    catch(Error::Code error) {
        wpi_setError(*this, error);
        return;
    }
}
/**
@brief Destructor.
Stop serving images and destroy this class.
*/
PCVideoServer::~PCVideoServer() {
    //printf ("START PCVideoServer DESTRUCTOR **********************\n");
    //  Stop the images to PC server.
    Stop();
    //StopImageToPCServer();
    //  Clear the error so that you can use this object to make a connection to
    //  the VIDEO_TO_PC_PORT to stop the ImageToPCServer if it is waiting to
    //  accept connections from a PC.
    ClearError();
    //  Open a socket.
    ScopedSocket camSock(socket (AF_INET, SOCK_STREAM, 0), this);
    //  If successful
    if (!StatusIsFatal()) {
        //  Create a connection to the localhost.
        struct sockaddr_in selfAddr;
        int sockAddrSize = sizeof(selfAddr);
        bzero ((char *) &selfAddr, sockAddrSize);
        selfAddr.sin_family = AF_INET;
        selfAddr.sin_len = (u_char) sockAddrSize;
        selfAddr.sin_port = htons (VIDEO_TO_PC_PORT);

        if (( (int)(selfAddr.sin_addr.s_addr = inet_addr (const_cast<char*>("localhost")) ) != ERROR) ||
            ( (int)(selfAddr.sin_addr.s_addr = hostGetByName (const_cast<char*>("localhost")) ) != ERROR))
        {
            connect (camSock, (struct sockaddr *) &selfAddr, sockAddrSize);
        }
    }
}

/**
 * Start the task that is responsible for sending images to the PC.
 */
int PCVideoServer::StartPcTask() {
    if (StatusIsFatal()) {
        return -1;
    }
	int id = 0;
	g_stopImageToPCServer = false;
	// check for prior copy of running task
    // TODO: Report error. You are in a bad state.
    //char taskName[1024];
    //sprintf(taskName, "%s%X", taskName, reinterpret_cast<int>(this));
	int oldId = taskNameToId(m_task.GetName());
	if(oldId != ERROR) {
		taskDelete(oldId);
	}

	// spawn video server task
	// this is done to ensure that the task is spawned with the
	// floating point context save parameter.
	bool started = m_task.Start();

	id = m_task.GetID();

    if (!started) {
        wpi_setError(*this, ERR_CAMERA_TASK_SPAWN_FAILED);
        return id;
    }
	taskDelay(1);
	return id;
}
/**
@brief Start sending images to the PC.
*/
void PCVideoServer::Start() {
    StartPcTask();
}

/**
@brief Stop sending images to the PC.
*/
void PCVideoServer::Stop() {
    g_stopImageToPCServer = true;
}

//============================================================================
//  C Functions
//============================================================================

/**
@brief Stop sending images to the PC.
*/
void StopImageToPCServer() {
	g_stopImageToPCServer = true;
}

/**
@brief Check is server is shutting down.
@return bool true if time to stop
*/
bool ShouldStopImageToPCServer()  {
    //  Return the current state of g_stopImageToPCServer
    return g_stopImageToPCServer;
}

/**
@brief Initialize the socket and serve images to the PC.
*/
int ImageToPCServer() {
    /* Setup to PC sockets */
    struct sockaddr_in serverAddr;
    int sockAddrSize = sizeof(serverAddr);
    int pcSock = ERROR;
    bzero ((char *) &serverAddr, sockAddrSize);
    serverAddr.sin_len = (u_char) sockAddrSize;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons (VIDEO_TO_PC_PORT);
    serverAddr.sin_addr.s_addr = htonl (INADDR_ANY);

    int success;
    while (true) {
        double lastImageTimestamp = 0;

        taskSafe();
    	//  Create the socket.
        if ((pcSock = socket (AF_INET, SOCK_STREAM, 0)) == ERROR) {
            perror ("socket");
            continue;
        }
        //  Set the TCP socket so that it can be reused if it is in the wait state.
        int reuseAddr = 1;
        setsockopt(pcSock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&reuseAddr), sizeof(reuseAddr));
        //  Bind socket to local address.
        // printf ("Binding to socket\n");
        if (bind (pcSock, (struct sockaddr *) &serverAddr, sockAddrSize) == ERROR)
        {
            perror ("bind");
            close (pcSock);
            continue;
        }
        //  Create queue for client connection requests.
        //printf ("Listening on socket (port:%d)\n",VIDEO_TO_PC_PORT);
        if (listen (pcSock, 1) == ERROR)
        {
            perror ("listen");
            close (pcSock);
            continue;
        }
        //  Accept a new connect request
        struct sockaddr_in clientAddr;
        int clientAddrSize;
        int newPCSock = accept (pcSock, reinterpret_cast<sockaddr*>(&clientAddr), &clientAddrSize);
        if (newPCSock  == ERROR) {
            perror ("accept");
            close(pcSock);
            continue;
        }
        //  Got a connection.
        //TODO: check camera error
        //if (!StatusIsFatal()) {

        while(!ShouldStopImageToPCServer()) {

            double newTimestamp;
            int numBytes = 0;
            char* imageData = NULL;
            //printf ("Getting image from camera\n");
            success = GetImageDataBlocking(&imageData, &numBytes, &newTimestamp, lastImageTimestamp);
            if (!success) {
                //  If camera is not initialzed you will get failure and
                //  the timestamp is invalid. Reset this value and try again.
                lastImageTimestamp = 0;
                continue;
            }
            lastImageTimestamp = newTimestamp;

            //printf ("Writing image to PC\n");
            /* Write header to PC */
            static const char header[4]={1,0,0,0};
            int headerSend = write(newPCSock, const_cast<char*>(header), 4);

            /* Write image length to PC */
            int presend = write(newPCSock, reinterpret_cast<char*>(&numBytes), 4);

            /* Write image to PC */
            int sent = write (newPCSock, imageData, numBytes);

            //  Cleanup memory allocated for the image.
            delete imageData;
            imageData = NULL;
            numBytes = 0;

            //  The PC probably closed connection. Get out of here
            //  and try listening again.
            if (headerSend == ERROR || sent == ERROR || presend == ERROR) {
                break;
            }
            //no point in running too fast -
            //max camera frame rate is 30 fps
            Wait(0.01);
        }
        //  Clean up
        close (newPCSock);
        newPCSock = ERROR;
        close (pcSock);
        pcSock = ERROR;
        taskUnsafe();
        Wait(0.1);
    }
    return (OK);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -