Merge "shrink config for webproxy"
diff --git a/aos/network/web_proxy_main.cc b/aos/network/web_proxy_main.cc
index 479320a..0e49760 100644
--- a/aos/network/web_proxy_main.cc
+++ b/aos/network/web_proxy_main.cc
@@ -1,4 +1,5 @@
 #include "aos/events/shm_event_loop.h"
+#include "aos/flatbuffer_merge.h"
 #include "aos/init.h"
 #include "aos/network/web_proxy.h"
 #include "aos/seasocks/seasocks_logger.h"
@@ -15,17 +16,23 @@
     std::vector<std::unique_ptr<aos::web_proxy::Subscriber>> *subscribers,
     const aos::FlatbufferDetachedBuffer<aos::Configuration> &config) {
   aos::ShmEventLoop event_loop(&config.message());
-  const aos::Node *self = aos::configuration::GetMyNode(&config.message());
+  const bool is_multi_node =
+      aos::configuration::MultiNode(event_loop.configuration());
+  const aos::Node *self =
+      is_multi_node ? aos::configuration::GetMyNode(event_loop.configuration())
+                    : nullptr;
+
+  LOG(INFO) << "My node is " << aos::FlatbufferToJson(self);
 
   // TODO(alex): skip fetchers on the wrong node.
   for (uint i = 0; i < config.message().channels()->size(); ++i) {
     auto channel = config.message().channels()->Get(i);
-    if (!aos::configuration::ChannelIsReadableOnNode(channel, self)) {
-      subscribers->emplace_back(nullptr);
-    } else {
+    if (aos::configuration::ChannelIsReadableOnNode(channel, self)) {
       auto fetcher = event_loop.MakeRawFetcher(channel);
       subscribers->emplace_back(
           std::make_unique<aos::web_proxy::Subscriber>(std::move(fetcher), i));
+    } else {
+      subscribers->emplace_back(nullptr);
     }
   }
 
@@ -33,7 +40,9 @@
 
   auto timer = event_loop.AddTimer([&]() {
     for (auto &subscriber : *subscribers) {
-      subscriber->RunIteration();
+      if (subscriber != nullptr) {
+        subscriber->RunIteration();
+      }
     }
   });
 
@@ -54,6 +63,14 @@
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
       aos::configuration::ReadConfig(FLAGS_config);
 
+  for (size_t i = 0; i < config.message().channels()->size(); ++i) {
+    aos::Channel *channel =
+        config.mutable_message()->mutable_channels()->GetMutableObject(i);
+    channel->clear_schema();
+  }
+
+  config = aos::CopyFlatBuffer(&config.message());
+
   std::vector<std::unique_ptr<aos::web_proxy::Subscriber>> subscribers;
 
   std::thread data_thread{
diff --git a/aos/network/www/proxy.ts b/aos/network/www/proxy.ts
index 80c71b2..13f4636 100644
--- a/aos/network/www/proxy.ts
+++ b/aos/network/www/proxy.ts
@@ -1,5 +1,6 @@
 import {ConfigHandler} from './config_handler';
 import {Configuration} from 'aos/configuration_generated';
+import * as WebProxy from 'aos/network/web_proxy_generated';
 
 // There is one handler for each DataChannel, it maintains the state of
 // multi-part messages and delegates to a callback when the message is fully
@@ -73,7 +74,7 @@
     const fbBuffer = new flatbuffers.ByteBuffer(new Uint8Array(e.data));
     // TODO(alex): handle config updates if/when required
     if (!this.configHandler) {
-      const config = aos.Configuration.getRootAsConfiguration(fbBuffer);
+      const config = Configuration.getRootAsConfiguration(fbBuffer);
       this.config = config;
       this.configHandler = new ConfigHandler(config, this.dataChannel);
       this.configHandler.printConfig();
diff --git a/y2020/control_loops/superstructure/superstructure.cc b/y2020/control_loops/superstructure/superstructure.cc
index 39c913e..9a6c3cd 100644
--- a/y2020/control_loops/superstructure/superstructure.cc
+++ b/y2020/control_loops/superstructure/superstructure.cc
@@ -97,6 +97,12 @@
 
   if (output != nullptr) {
     if (unsafe_goal) {
+        output_struct.washing_machine_spinner_voltage = 6.0;
+      if (unsafe_goal->shooting()) {
+        output_struct.feeder_voltage = 6.0;
+      } else {
+        output_struct.feeder_voltage = 0.0;
+      }
       output_struct.intake_roller_voltage = unsafe_goal->roller_voltage();
     } else {
       output_struct.intake_roller_voltage = 0.0;
diff --git a/y2020/joystick_reader.cc b/y2020/joystick_reader.cc
index 7910859..89de4b9 100644
--- a/y2020/joystick_reader.cc
+++ b/y2020/joystick_reader.cc
@@ -40,6 +40,7 @@
 const ButtonLocation kTurret(3, 15);
 const ButtonLocation kHood(3, 3);
 const ButtonLocation kShootSlow(4, 2);
+const ButtonLocation kFeed(4, 1);
 const ButtonLocation kIntakeExtend(3, 9);
 const ButtonLocation kIntakeIn(4, 4);
 const ButtonLocation kSpit(4, 5);
@@ -84,8 +85,8 @@
     }
 
     if (data.IsPressed(kShootFast)) {
-      accelerator_speed = 600.0;
-      finisher_speed = 200.0;
+      accelerator_speed = 500.0;
+      finisher_speed = 500.0;
     } else if (data.IsPressed(kShootSlow)) {
       accelerator_speed = 30.0;
       finisher_speed = 30.0;
@@ -95,6 +96,9 @@
       intake_pos = 1.0;
     }
 
+    if (data.IsPressed(kFeed)) {
+    }
+
     if (data.IsPressed(kIntakeIn)) {
       roller_speed = 6.0f;
     } else if (data.IsPressed(kSpit)) {
@@ -132,6 +136,7 @@
       superstructure_goal_builder.add_turret(turret_offset);
       superstructure_goal_builder.add_roller_voltage(roller_speed);
       superstructure_goal_builder.add_shooter(shooter_offset);
+      superstructure_goal_builder.add_shooting(data.IsPressed(kFeed));
 
       if (!builder.Send(superstructure_goal_builder.Finish())) {
         AOS_LOG(ERROR, "Sending superstructure goal failed.\n");
diff --git a/y2020/www/image_handler.ts b/y2020/www/image_handler.ts
index 802e448..6ad83a3 100644
--- a/y2020/www/image_handler.ts
+++ b/y2020/www/image_handler.ts
@@ -1,10 +1,11 @@
 import {CameraImage} from 'y2020/vision/vision_generated';
+import {ImageMatchResult} from 'y2020/vision/sift/sift_generated'
 
 export class ImageHandler {
   private canvas = document.createElement('canvas');
   private imageBuffer: Uint8ClampedArray|null = null;
   private imageTimestamp: flatbuffers.Long|null = null;
-  private result: fr971.vision.ImageMatchResult|null = null;
+  private result: ImageMatchResult|null = null;
   private resultTimestamp: flatbuffers.Long|null = null;
 
   constructor() {
@@ -56,7 +57,7 @@
 
   handleImageMetadata(data: Uint8Array): void {
     const fbBuffer = new flatbuffers.ByteBuffer(data);
-    this.result = frc971.vision.ImageMatchResult.getRootAsImageMatchResult(fbBuffer);
+    this.result = ImageMatchResult.getRootAsImageMatchResult(fbBuffer);
     this.resultTimestamp = result.imageMonotonicTimestampNs();
     draw();
   }
@@ -92,6 +93,6 @@
   }
 
   getResultId(): string {
-    return frc971.vision.ImageMatchResult.getFullyQualifiedName();
+    return ImageMatchResult.getFullyQualifiedName();
   }
 }