burrow-pi-img/deps/tools/configServer/src/main.cpp
Peter Johnson c85fd9f33c
Revamp image to build dependencies as part of stages (#83)
Fixes #17.

Stage 2 is fairly minimal, stage 3 builds/installs OpenCV and WPILib et al, and stage 4
builds/installs the FRCVision webdash and adds the vision examples.

Other changes:
- OpenCV compiled with ffmpeg, OpenBLAS, and libgtk (fixes #79, fixes #80)
- OpenBLAS added to image (fixes #65)
- C++ Makefile is more easily extensible (fixes #71)
- Sources for everything are bundled into image into /usr/src
- README updated (fixes #16)
- pkg-config files for wpilibc et al are now installed and C++ Makefile uses them (if compiled local to Pi)
- Both dynamic and static libs are included in image

The only downside of all these changes (particularly the ffmpeg, OpenBLAS, and libgtk inclusion)
is the image size is now over 3GB (800MB compressed). The previous image didn't quite fit on a
2GB card however.
2019-02-02 23:37:18 -08:00

140 lines
4.3 KiB
C++

/*----------------------------------------------------------------------------*/
/* Copyright (c) 2018 FIRST. 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 the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#include <chrono>
#include <thread>
#include <wpi/ArrayRef.h>
#include <wpi/StringRef.h>
#include <wpi/raw_ostream.h>
#include <wpi/raw_uv_ostream.h>
#include <wpi/timestamp.h>
#include <wpi/uv/Loop.h>
#include <wpi/uv/Process.h>
#include <wpi/uv/Tcp.h>
#include <wpi/uv/Timer.h>
#include <wpi/uv/Udp.h>
#include "MyHttpConnection.h"
#include "NetworkSettings.h"
#include "SystemStatus.h"
#include "VisionStatus.h"
namespace uv = wpi::uv;
static uint64_t startTime = wpi::Now();
int main(int argc, char* argv[]) {
int port = 80;
if (argc == 2) port = std::atoi(argv[1]);
uv::Process::DisableStdioInheritance();
SystemStatus::GetInstance();
auto loop = uv::Loop::Create();
NetworkSettings::GetInstance()->SetLoop(loop);
VisionStatus::GetInstance()->SetLoop(loop);
loop->error.connect(
[](uv::Error err) { wpi::errs() << "uv ERROR: " << err.str() << '\n'; });
auto tcp = uv::Tcp::Create(loop);
// bind to listen address and port
tcp->Bind("", port);
// when we get a connection, accept it and start reading
tcp->connection.connect([srv = tcp.get()] {
auto tcp = srv->Accept();
if (!tcp) return;
// wpi::errs() << "Got a connection\n";
// Close on error
tcp->error.connect([s = tcp.get()](wpi::uv::Error err) {
wpi::errs() << "stream error: " << err.str() << '\n';
s->Close();
});
auto conn = std::make_shared<MyHttpConnection>(tcp);
tcp->SetData(conn);
});
// start listening for incoming connections
tcp->Listen();
wpi::errs() << "Listening on port " << port << '\n';
// start timer to collect system and vision status
auto timer = uv::Timer::Create(loop);
timer->Start(std::chrono::seconds(1), std::chrono::seconds(1));
timer->timeout.connect([&loop] {
SystemStatus::GetInstance()->UpdateAll();
VisionStatus::GetInstance()->UpdateStatus();
});
// listen on port 6666 for console logging
auto udpCon = uv::Udp::Create(loop);
udpCon->Bind("127.0.0.1", 6666, UV_UDP_REUSEADDR);
udpCon->StartRecv();
udpCon->received.connect(
[](uv::Buffer& buf, size_t len, const sockaddr&, unsigned) {
VisionStatus::GetInstance()->ConsoleLog(buf, len);
});
// create riolog console port
auto tcpCon = uv::Tcp::Create(loop);
tcpCon->Bind("", 1740);
// when we get a connection, accept it
tcpCon->connection.connect([ srv = tcpCon.get(), udpCon ] {
auto tcp = srv->Accept();
if (!tcp) return;
// close on error
tcp->error.connect([s = tcp.get()](uv::Error err) { s->Close(); });
// copy console log to it with headers
udpCon->received.connect(
[ tcpSeq = std::make_shared<uint16_t>(), tcpPtr = tcp.get() ](
uv::Buffer & buf, size_t len, const sockaddr&, unsigned) {
// build buffers
wpi::SmallVector<uv::Buffer, 4> bufs;
wpi::raw_uv_ostream out(bufs, 4096);
// Header is 2 byte len, 1 byte type, 4 byte timestamp, 2 byte
// sequence num
uint32_t ts = wpi::FloatToBits((wpi::Now() - startTime) * 1.0e-6);
uint16_t pktlen = len + 1 + 4 + 2;
out << wpi::ArrayRef<uint8_t>(
{static_cast<uint8_t>((pktlen >> 8) & 0xff),
static_cast<uint8_t>(pktlen & 0xff), 12,
static_cast<uint8_t>((ts >> 24) & 0xff),
static_cast<uint8_t>((ts >> 16) & 0xff),
static_cast<uint8_t>((ts >> 8) & 0xff),
static_cast<uint8_t>(ts & 0xff),
static_cast<uint8_t>((*tcpSeq >> 8) & 0xff),
static_cast<uint8_t>(*tcpSeq & 0xff)});
out << wpi::StringRef(buf.base, len);
(*tcpSeq)++;
// send output
tcpPtr->Write(bufs, [](auto bufs2, uv::Error) {
for (auto buf : bufs2) buf.Deallocate();
});
},
tcp);
});
// start listening for incoming connections
tcpCon->Listen();
// run loop
loop->Run();
}