Skip to content

Commit ec1665f

Browse files
committed
Merge branch 'update-2023' into update-arm64
2 parents 4216407 + 06c9ae6 commit ec1665f

24 files changed

+424
-357
lines changed

deps/examples/cpp-multiCameraServer/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ ${EXE}: ${OBJS}
1919
${CXX} -pthread -g -o $@ $^ ${DEPS_LIBS} -Wl,--unresolved-symbols=ignore-in-shared-libs
2020

2121
.cpp.o:
22-
${CXX} -pthread -g -Og -c -o $@ -std=c++17 ${CXXFLAGS} ${DEPS_CFLAGS} $<
22+
${CXX} -pthread -g -Og -c -o $@ -std=c++20 ${CXXFLAGS} ${DEPS_CFLAGS} $<

deps/examples/cpp-multiCameraServer/main.cpp

+45-35
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include <wpi/StringExtras.h>
1616
#include <wpi/json.h>
1717
#include <wpi/raw_istream.h>
18-
#include <wpi/raw_ostream.h>
1918

2019
#include "cameraserver/CameraServer.h"
2120

@@ -85,8 +84,15 @@ std::vector<CameraConfig> cameraConfigs;
8584
std::vector<SwitchedCameraConfig> switchedCameraConfigs;
8685
std::vector<cs::VideoSource> cameras;
8786

88-
void ParseError(std::string_view msg) {
89-
fmt::print(stderr, "config error in '{}': {}\n", configFile, msg);
87+
void ParseErrorV(fmt::string_view format, fmt::format_args args) {
88+
fmt::print(stderr, "config error in '{}': ", configFile);
89+
fmt::vprint(stderr, format, args);
90+
fmt::print(stderr, "\n");
91+
}
92+
93+
template <typename... Args>
94+
void ParseError(fmt::string_view format, Args&&... args) {
95+
ParseErrorV(format, fmt::make_format_args(args...));
9096
}
9197

9298
bool ReadCameraConfig(const wpi::json& config) {
@@ -96,15 +102,15 @@ bool ReadCameraConfig(const wpi::json& config) {
96102
try {
97103
c.name = config.at("name").get<std::string>();
98104
} catch (const wpi::json::exception& e) {
99-
ParseError(fmt::format("could not read camera name: {}", e.what()));
105+
ParseError("could not read camera name: {}", e.what());
100106
return false;
101107
}
102108

103109
// path
104110
try {
105111
c.path = config.at("path").get<std::string>();
106112
} catch (const wpi::json::exception& e) {
107-
ParseError(fmt::format("camera '{}': could not read path: {}", c.name, e.what()));
113+
ParseError("camera '{}': could not read path: {}", c.name, e.what());
108114
return false;
109115
}
110116

@@ -124,17 +130,16 @@ bool ReadSwitchedCameraConfig(const wpi::json& config) {
124130
try {
125131
c.name = config.at("name").get<std::string>();
126132
} catch (const wpi::json::exception& e) {
127-
ParseError(fmt::format("could not read switched camera name: {}",
128-
e.what()));
133+
ParseError("could not read switched camera name: {}", e.what());
129134
return false;
130135
}
131136

132137
// key
133138
try {
134139
c.key = config.at("key").get<std::string>();
135140
} catch (const wpi::json::exception& e) {
136-
ParseError(fmt::format("switched camera '{}': could not read key: {}",
137-
c.name, e.what()));
141+
ParseError("switched camera '{}': could not read key: {}", c.name,
142+
e.what());
138143
return false;
139144
}
140145

@@ -147,8 +152,7 @@ bool ReadConfig() {
147152
std::error_code ec;
148153
wpi::raw_fd_istream is(configFile, ec);
149154
if (ec) {
150-
wpi::errs() << "could not open '" << configFile << "': " << ec.message()
151-
<< '\n';
155+
fmt::print(stderr, "could not open '{}': {}", configFile, ec.message());
152156
return false;
153157
}
154158

@@ -157,7 +161,7 @@ bool ReadConfig() {
157161
try {
158162
j = wpi::json::parse(is);
159163
} catch (const wpi::json::parse_error& e) {
160-
ParseError(fmt::format("byte {}: {}", e.byte, e.what()));
164+
ParseError("byte {}: {}", e.byte, e.what());
161165
return false;
162166
}
163167

@@ -171,7 +175,7 @@ bool ReadConfig() {
171175
try {
172176
team = j.at("team").get<unsigned int>();
173177
} catch (const wpi::json::exception& e) {
174-
ParseError(fmt::format("could not read team number: {}", e.what()));
178+
ParseError("could not read team number: {}", e.what());
175179
return false;
176180
}
177181

@@ -184,10 +188,10 @@ bool ReadConfig() {
184188
} else if (wpi::equals_lower(str, "server")) {
185189
server = true;
186190
} else {
187-
ParseError(fmt::format("could not understand ntmode value '{}'", str));
191+
ParseError("could not understand ntmode value '{}'", str);
188192
}
189193
} catch (const wpi::json::exception& e) {
190-
ParseError(fmt::format("could not read ntmode: {}", e.what()));
194+
ParseError("could not read ntmode: {}", e.what());
191195
}
192196
}
193197

@@ -197,7 +201,7 @@ bool ReadConfig() {
197201
if (!ReadCameraConfig(camera)) return false;
198202
}
199203
} catch (const wpi::json::exception& e) {
200-
ParseError(fmt::format("could not read cameras: {}", e.what()));
204+
ParseError("could not read cameras: {}", e.what());
201205
return false;
202206
}
203207

@@ -208,7 +212,7 @@ bool ReadConfig() {
208212
if (!ReadSwitchedCameraConfig(camera)) return false;
209213
}
210214
} catch (const wpi::json::exception& e) {
211-
ParseError(fmt::format("could not read switched cameras: {}", e.what()));
215+
ParseError("could not read switched cameras: {}", e.what());
212216
return false;
213217
}
214218
}
@@ -234,24 +238,29 @@ cs::MjpegServer StartSwitchedCamera(const SwitchedCameraConfig& config) {
234238
fmt::print("Starting switched camera '{}' on {}\n", config.name, config.key);
235239
auto server = frc::CameraServer::AddSwitchedCamera(config.name);
236240

237-
nt::NetworkTableInstance::GetDefault()
238-
.GetEntry(config.key)
239-
.AddListener(
240-
[server](const auto& event) mutable {
241-
if (event.value->IsDouble()) {
242-
int i = event.value->GetDouble();
243-
if (i >= 0 && i < cameras.size()) server.SetSource(cameras[i]);
244-
} else if (event.value->IsString()) {
245-
auto str = event.value->GetString();
246-
for (int i = 0; i < cameraConfigs.size(); ++i) {
247-
if (str == cameraConfigs[i].name) {
248-
server.SetSource(cameras[i]);
249-
break;
250-
}
251-
}
241+
auto inst = nt::NetworkTableInstance::GetDefault();
242+
inst.AddListener(
243+
inst.GetTopic(config.key),
244+
nt::EventFlags::kImmediate | nt::EventFlags::kValueAll,
245+
[server](const auto& event) mutable {
246+
if (auto data = event.GetValueEventData()) {
247+
if (data->value.IsInteger()) {
248+
int i = data->value.GetInteger();
249+
if (i >= 0 && i < cameras.size()) server.SetSource(cameras[i]);
250+
} else if (data->value.IsDouble()) {
251+
int i = data->value.GetDouble();
252+
if (i >= 0 && i < cameras.size()) server.SetSource(cameras[i]);
253+
} else if (data->value.IsString()) {
254+
auto str = data->value.GetString();
255+
for (int i = 0; i < cameraConfigs.size(); ++i) {
256+
if (str == cameraConfigs[i].name) {
257+
server.SetSource(cameras[i]);
258+
break;
252259
}
253-
},
254-
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
260+
}
261+
}
262+
}
263+
});
255264

256265
return server;
257266
}
@@ -280,7 +289,8 @@ int main(int argc, char* argv[]) {
280289
ntinst.StartServer();
281290
} else {
282291
fmt::print("Setting up NetworkTables client for team {}\n", team);
283-
ntinst.StartClientTeam(team);
292+
ntinst.StartClient4("multiCameraServer");
293+
ntinst.SetServerTeam(team);
284294
ntinst.StartDSClient();
285295
}
286296

deps/examples/java-multiCameraServer/src/main/java/Main.java

+28-18
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.nio.file.Files;
77
import java.nio.file.Paths;
88
import java.util.ArrayList;
9+
import java.util.EnumSet;
910
import java.util.List;
1011

1112
import com.google.gson.Gson;
@@ -19,7 +20,7 @@
1920
import edu.wpi.first.cscore.MjpegServer;
2021
import edu.wpi.first.cscore.UsbCamera;
2122
import edu.wpi.first.cscore.VideoSource;
22-
import edu.wpi.first.networktables.EntryListenerFlags;
23+
import edu.wpi.first.networktables.NetworkTableEvent;
2324
import edu.wpi.first.networktables.NetworkTableInstance;
2425
import edu.wpi.first.vision.VisionPipeline;
2526
import edu.wpi.first.vision.VisionThread;
@@ -253,25 +254,33 @@ public static MjpegServer startSwitchedCamera(SwitchedCameraConfig config) {
253254
System.out.println("Starting switched camera '" + config.name + "' on " + config.key);
254255
MjpegServer server = CameraServer.getInstance().addSwitchedCamera(config.name);
255256

256-
NetworkTableInstance.getDefault()
257-
.getEntry(config.key)
258-
.addListener(event -> {
259-
if (event.value.isDouble()) {
260-
int i = (int) event.value.getDouble();
261-
if (i >= 0 && i < cameras.size()) {
257+
NetworkTableInstance inst = NetworkTableInstance.getDefault();
258+
inst.addListener(
259+
inst.getTopic(config.key),
260+
EnumSet.of(NetworkTableEvent.Kind.kImmediate, NetworkTableEvent.Kind.kValueAll),
261+
event -> {
262+
if (event.valueData != null) {
263+
if (event.valueData.value.isInteger()) {
264+
int i = (int) event.valueData.value.getInteger();
265+
if (i >= 0 && i < cameras.size()) {
266+
server.setSource(cameras.get(i));
267+
}
268+
} else if (event.valueData.value.isDouble()) {
269+
int i = (int) event.valueData.value.getDouble();
270+
if (i >= 0 && i < cameras.size()) {
271+
server.setSource(cameras.get(i));
272+
}
273+
} else if (event.valueData.value.isString()) {
274+
String str = event.valueData.value.getString();
275+
for (int i = 0; i < cameraConfigs.size(); i++) {
276+
if (str.equals(cameraConfigs.get(i).name)) {
262277
server.setSource(cameras.get(i));
263-
}
264-
} else if (event.value.isString()) {
265-
String str = event.value.getString();
266-
for (int i = 0; i < cameraConfigs.size(); i++) {
267-
if (str.equals(cameraConfigs.get(i).name)) {
268-
server.setSource(cameras.get(i));
269-
break;
270-
}
278+
break;
271279
}
272280
}
273-
},
274-
EntryListenerFlags.kImmediate | EntryListenerFlags.kNew | EntryListenerFlags.kUpdate);
281+
}
282+
}
283+
});
275284

276285
return server;
277286
}
@@ -308,7 +317,8 @@ public static void main(String... args) {
308317
ntinst.startServer();
309318
} else {
310319
System.out.println("Setting up NetworkTables client for team " + team);
311-
ntinst.startClientTeam(team);
320+
ntinst.startClient4();
321+
ntinst.setServerTeam(team);
312322
ntinst.startDSClient();
313323
}
314324

deps/tools/configServer/Makefile

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
IMG_VERSION?=$(shell git describe)
2-
DEPS_CFLAGS?=$(shell pkg-config --cflags cscore wpiutil) -std=c++17
3-
DEPS_LIBS?=$(shell pkg-config --libs --static cscore wpiutil)
2+
3+
# For a desktop build with the allwpilib source tree:
4+
#ALLWPILIB=/home/peter/project/frc/allwpilib
5+
#DEPS_CFLAGS= \
6+
-I${ALLWPILIB}/wpiutil/src/main/native/include \
7+
-I${ALLWPILIB}/wpinet/src/main/native/include \
8+
-I${ALLWPILIB}/cscore/src/main/native/include \
9+
-I${ALLWPILIB}/wpiutil/src/main/native/thirdparty/llvm/include \
10+
-I${ALLWPILIB}/wpiutil/src/main/native/thirdparty/sigslot/include \
11+
-I${ALLWPILIB}/wpiutil/src/main/native/thirdparty/fmtlib/include \
12+
-I${ALLWPILIB}/wpiutil/src/main/native/thirdparty/json/include \
13+
-I${ALLWPILIB}/wpinet/src/main/native/thirdparty/libuv/include
14+
#DEPS_LIBS=-L${ALLWPILIB}/build-ninja/lib -lcscored -lwpinetd -lwpiutild
15+
16+
DEPS_CFLAGS?=$(shell pkg-config --cflags cscore wpinet wpiutil)
17+
DEPS_LIBS?=$(shell pkg-config --libs --static cscore wpinet wpiutil)
418
EXEC_HOME?=/home/pi
519
FRC_JSON?=/boot/frc.json
620
DHCPCD_CONF?=/boot/dhcpcd.conf
@@ -11,6 +25,7 @@ APP_UID?=1000
1125
APP_GID?=1000
1226
ROMI_JSON?=/boot/romi.json
1327
NODE_HOME?=/home/pi/.nvm/versions/node/v14.15.0/bin
28+
CXXFLAGS?=-std=c++20
1429

1530
.PHONY: all clean install
1631
.SUFFIXES:

deps/tools/configServer/src/Application.cpp

+14-21
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
#include <unistd.h>
1010

1111
#include <fmt/format.h>
12+
#include <wpi/SmallString.h>
1213
#include <wpi/StringExtras.h>
14+
#include <wpi/fmt/raw_ostream.h>
1315
#include <wpi/fs.h>
1416
#include <wpi/json.h>
1517
#include <wpi/raw_istream.h>
@@ -56,11 +58,7 @@ void Application::Set(std::string_view appType,
5658
} else if (appType == "custom") {
5759
return;
5860
} else {
59-
wpi::SmallString<64> msg;
60-
msg = "unrecognized application type '";
61-
msg += appType;
62-
msg += "'";
63-
onFail(msg);
61+
onFail(fmt::format("unrecognized application type '{}'", appType));
6462
return;
6563
}
6664

@@ -72,13 +70,13 @@ void Application::Set(std::string_view appType,
7270
onFail("could not write " EXEC_HOME "/runCamera");
7371
return;
7472
}
75-
os << "#!/bin/sh\n";
76-
os << TYPE_TAG << ' ' << appType << '\n';
77-
os << "echo \"Waiting 5 seconds...\"\n";
78-
os << "sleep 5\n";
79-
if (!appDir.empty()) os << "cd " << appDir << '\n';
80-
if (!appEnv.empty()) os << appEnv << '\n';
81-
os << "exec " << appCommand << '\n';
73+
fmt::print(os, "#!/bin/sh\n");
74+
fmt::print(os, "{} {}\n", TYPE_TAG, appType);
75+
fmt::print(os, "echo \"Waiting 5 seconds...\"\n");
76+
fmt::print(os, "sleep 5\n");
77+
if (!appDir.empty()) fmt::print(os, "cd {}\n", appDir);
78+
if (!appEnv.empty()) fmt::print(os, "{}\n", appEnv);
79+
fmt::print(os, "exec {}\n", appCommand);
8280
}
8381

8482
// terminate vision process so it reloads
@@ -97,18 +95,11 @@ void Application::FinishUpload(std::string_view appType, UploadHelper& helper,
9795
} else if (appType == "upload-python") {
9896
filename = "/uploaded.py";
9997
} else {
100-
wpi::SmallString<64> msg;
101-
msg = "cannot upload application type '";
102-
msg += appType;
103-
msg += "'";
104-
onFail(msg);
98+
onFail(fmt::format("cannot upload application type '{}'", appType));
10599
helper.Close();
106100
return;
107101
}
108102

109-
wpi::SmallString<64> pathname;
110-
pathname = EXEC_HOME;
111-
pathname += filename;
112103
int fd = helper.GetFD();
113104

114105
// change ownership
@@ -126,6 +117,8 @@ void Application::FinishUpload(std::string_view appType, UploadHelper& helper,
126117
// close temporary file
127118
helper.Close();
128119

120+
auto pathname = fmt::format("{}{}", EXEC_HOME, filename);
121+
129122
// remove old file (need to do this as we can't overwrite a running exe)
130123
if (unlink(pathname.c_str()) == -1) {
131124
fmt::print(stderr, "could not remove app executable: {}\n",
@@ -151,7 +144,7 @@ wpi::json Application::GetStatusJson() {
151144
std::error_code ec;
152145
wpi::raw_fd_istream is(EXEC_HOME "/runCamera", ec);
153146
if (ec) {
154-
fmt::print(stderr, "{}", "could not read " EXEC_HOME "/runCamera\n");
147+
fmt::print(stderr, "could not read {}/runCamera\n", EXEC_HOME);
155148
return j;
156149
}
157150

0 commit comments

Comments
 (0)