<commit_before>/*
 * File:   XMLDocument.cpp
 * Author: tjoppen
 *
 * Created on February 15, 2010, 1:22 PM
 */

#include <xercesc/dom/DOMImplementationRegistry.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/dom/DOMImplementationLS.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/dom/DOMWriter.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/util/BinInputStream.hpp>
#include <xercesc/sax/InputSource.hpp>
#include <stdexcept>
#include <istream>
#include <ostream>
#include "XMLDocument.h"
#include "XMLObject.h"
#include "XercesString.h"

using namespace xercesc;
using namespace james;
using namespace std;

/**
 * Minimal utility class for parsing directly from an std::istream.
 */
class IStreamInputSource : public InputSource {
    istream &is;

    class IStreamBinInputStream : public BinInputStream {
        istream &is;
    public:
        IStreamBinInputStream(istream &is) : BinInputStream(), is(is) {
        }

        unsigned int curPos(void) const {
            return is.tellg();
        }

        unsigned int readBytes(XMLByte* const buf, const unsigned int max) {
            is.read((char*)buf, max);

            return is.gcount();
        }
    };
public:
    IStreamInputSource(istream &is) : InputSource(), is(is) {
    }

    BinInputStream* makeStream() const {
        return new IStreamBinInputStream(is);
    }
};

ostream& operator<< (ostream& os, const XMLDocument& doc) {
    //TODO: make exception safe
    const XMLObject         *object = dynamic_cast<const XMLObject*>(&doc);
    DOMImplementation       *implementation = DOMImplementationRegistry::getDOMImplementation(X("LS"));
    DOMImplementationLS     *lsImplementation = dynamic_cast<DOMImplementationLS*>(implementation);

    if(!object)             throw runtime_error(doc.getName() + " is not a sibling class of XMLObject");
    if(!implementation)     throw runtime_error("Failed to find a DOM implementation");
    if(!lsImplementation)   throw runtime_error("Failed to find a DOM LS implementation");

    DOMWriter *writer = lsImplementation->createDOMWriter();

    if(!writer)             throw runtime_error("Failed to create DOM writer");

    //get name of root element and create new DOM dodument
    DOMDocument *document = implementation->createDocument(0, X(doc.getName()), 0);

    if(!document)           throw runtime_error("Failed to create DOM document");

    DOMElement *root = document->getDocumentElement();

    if(!root)               throw runtime_error("Failed failed to get DOM document element");

    //append the nodes of each member variable to the root element in a recursive fashion
    object->appendChildren(root);

    //serialize
    XMLCh *str = writer->writeToString(*root);

    //convert XMLCh* string to std::string
    os << X(str);

    writer->release();
    document->release();

    //HACKHACK: if we don't do this valgrind complains
    //FIXME: we should call XMLString::release(), but that causes a mismatched delete[] - new thing
    delete str;

    return os;
}

istream& operator>> (istream& is, const XMLDocument& doc) {
    //parse XML, then parse objects from the resulting DOM tree
    XercesDOMParser parser;

    parser.setDoNamespaces(true);
    parser.parse(IStreamInputSource(is));

    const XMLObject *object = dynamic_cast<const XMLObject*>(&doc);
    DOMDocument     *document = parser.getDocument();
    DOMElement      *root = document->getDocumentElement();

    return is;
}
<commit_msg>More work in the parsing<commit_after>/*
 * File:   XMLDocument.cpp
 * Author: tjoppen
 *
 * Created on February 15, 2010, 1:22 PM
 */

#include <xercesc/dom/DOMImplementationRegistry.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/dom/DOMImplementationLS.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/dom/DOMWriter.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/util/BinInputStream.hpp>
#include <xercesc/sax/InputSource.hpp>
#include <stdexcept>
#include <istream>
#include <ostream>
#include "XMLDocument.h"
#include "XMLObject.h"
#include "XercesString.h"

using namespace xercesc;
using namespace james;
using namespace std;

/**
 * Minimal utility class for parsing directly from an std::istream.
 */
class IStreamInputSource : public InputSource {
    istream &is;

    class IStreamBinInputStream : public BinInputStream {
        istream &is;
    public:
        IStreamBinInputStream(istream &is) : BinInputStream(), is(is) {
        }

        unsigned int curPos(void) const {
            return is.tellg();
        }

        unsigned int readBytes(XMLByte* const buf, const unsigned int max) {
            is.read((char*)buf, max);

            return is.gcount();
        }
    };
public:
    IStreamInputSource(istream &is) : InputSource(), is(is) {
    }

    BinInputStream* makeStream() const {
        return new IStreamBinInputStream(is);
    }
};

ostream& operator<< (ostream& os, const XMLDocument& doc) {
    //TODO: make exception safe
    const XMLObject         *object = dynamic_cast<const XMLObject*>(&doc);
    DOMImplementation       *implementation = DOMImplementationRegistry::getDOMImplementation(X("LS"));
    DOMImplementationLS     *lsImplementation = dynamic_cast<DOMImplementationLS*>(implementation);

    if(!object)             throw runtime_error(doc.getName() + " is not a sibling class of XMLObject");
    if(!implementation)     throw runtime_error("Failed to find a DOM implementation");
    if(!lsImplementation)   throw runtime_error("Failed to find a DOM LS implementation");

    DOMWriter *writer = lsImplementation->createDOMWriter();

    if(!writer)             throw runtime_error("Failed to create DOM writer");

    //get name of root element and create new DOM dodument
    DOMDocument *document = implementation->createDocument(0, X(doc.getName()), 0);

    if(!document)           throw runtime_error("Failed to create DOM document");

    DOMElement *root = document->getDocumentElement();

    if(!root)               throw runtime_error("Failed failed to get DOM document element");

    //append the nodes of each member variable to the root element in a recursive fashion
    object->appendChildren(root);

    //serialize
    XMLCh *str = writer->writeToString(*root);

    //convert XMLCh* string to std::string
    os << X(str);

    writer->release();
    document->release();

    //HACKHACK: if we don't do this valgrind complains
    //FIXME: we should call XMLString::release(), but that causes a mismatched delete[] - new thing
    delete str;

    return os;
}

istream& operator>> (istream& is, const XMLDocument& doc) {
    //parse XML, then parse objects from the resulting DOM tree
    XercesDOMParser parser;

    parser.setDoNamespaces(true);
    parser.parse(IStreamInputSource(is));

    const XMLObject *object = dynamic_cast<const XMLObject*>(&doc);
    DOMDocument     *document = parser.getDocument();

    if(!object)     throw runtime_error(doc.getName() + " is not a sibling class of XMLObject");
    if(!document)   throw runtime_error("Failed to parse document");

    DOMElement      *root = document->getDocumentElement();

    if(!root)       throw runtime_error("Failed to get document root");

    //check that the name of the root node matches the name of the XMLDocument
    if(!root->getLocalName() || X(root->getLocalName()) != doc.getName())
        throw runtime_error("No local name for DOM document or supplied XML is not a " + doc.getName());

    return is;
}
<|endoftext|>


<commit_before>#include "SymbolicRangeAnalysis.h"

#define DEBUG_TYPE "sra-gen-test"

#include "llvm/Pass.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"

using namespace llvm;

class SymbolicRangeAnalysisGenTest : public ModulePass {
public:
  static char ID;
  SymbolicRangeAnalysisGenTest() : ModulePass(ID) { }

  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
  virtual bool runOnModule(Module&);
};

static RegisterPass<SymbolicRangeAnalysisGenTest>
  X("sra-gen-test", "Symbolic range analysis range generation test");
char SymbolicRangeAnalysisGenTest::ID = 0;

void SymbolicRangeAnalysisGenTest::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.addRequired<SymbolicRangeAnalysis>();
  AU.setPreservesAll();
}

bool SymbolicRangeAnalysisGenTest::runOnModule(Module& M) {
  for (auto &F : M) {
    if (F.isIntrinsic() || F.isDeclaration())
      continue;

    auto &SRA = getAnalysis<SymbolicRangeAnalysis>(F);

    for (auto &BB : F) {
      IRBuilder<> IRB(BB.getTerminator());
      std::vector<Instruction*> Ins;
      for (auto &I : BB)
        if (I.getType()->isIntegerTy()) {
          Ins.push_back(&I);
        }

      for (auto I : Ins) {
        DEBUG(dbgs() << "Generating ranges: " << SRA.getStateOrInf(I)
                     << " for instruction " << *I << "\n");
        SRA.getRangeValuesFor(I, IRB);
      }
    }
  }

  return false;
}

<commit_msg>Making the generation test a function pass<commit_after>#include "SymbolicRangeAnalysis.h"

#define DEBUG_TYPE "sra-gen-test"

#include "llvm/Pass.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"

using namespace llvm;

class SymbolicRangeAnalysisGenTest : public FunctionPass {
public:
  static char ID;
  SymbolicRangeAnalysisGenTest() : FunctionPass(ID) { }

  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
  virtual bool runOnFunction(Function&);
};

static RegisterPass<SymbolicRangeAnalysisGenTest>
  X("sra-gen-test", "Symbolic range analysis range generation test");
char SymbolicRangeAnalysisGenTest::ID = 0;

void SymbolicRangeAnalysisGenTest::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.addRequired<SymbolicRangeAnalysis>();
  AU.setPreservesAll();
}

bool SymbolicRangeAnalysisGenTest::runOnFunction(Function& F) {
  auto &SRA = getAnalysis<SymbolicRangeAnalysis>();

  dbgs() << "SRA-GEN: runOnFunction: " << F.getName() << "\n";

  for (auto &BB : F) {
    IRBuilder<> IRB(BB.getTerminator());
    std::vector<Instruction*> Ins;
    for (auto &I : BB)
      if (I.getType()->isIntegerTy()) {
        Ins.push_back(&I);
      }

    for (auto I : Ins) {
      DEBUG(dbgs() << "Generating ranges: " << SRA.getStateOrInf(I)
                   << " for instruction " << *I << "\n");
      SRA.getRangeValuesFor(I, IRB);
    }
  }

  return false;
}

<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2014-2019 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <modules/basecl/processors/entryexitpointsclprocessor.h>
#include <inviwo/core/datastructures/geometry/mesh.h>
#include <modules/opencl/image/imagecl.h>
#include <modules/opencl/image/imageclgl.h>
#include <modules/opencl/settings/openclsettings.h>
#include <modules/opencl/syncclgl.h>
#include <inviwo/core/algorithm/boundingbox.h>

namespace inviwo {

const ProcessorInfo EntryExitPointsCLProcessor::processorInfo_{
    "org.inviwo.EntryExitPointsCL",  // Class identifier
    "Entry Exit Points",             // Display name
    "Mesh Rendering",                // Category
    CodeState::Stable,               // Code state
    Tags::CL,                        // Tags
};
const ProcessorInfo EntryExitPointsCLProcessor::getProcessorInfo() const { return processorInfo_; }

EntryExitPointsCLProcessor::EntryExitPointsCLProcessor()
    : Processor()
    , KernelObserver()
    , geometryPort_("geometry")
    , entryPort_(
          "entry-points",
          DataVec4Float32::get())  // Using 8-bits will create artifacts when entering the volume
    , exitPort_("exit-points", DataVec4Float32::get())
    , camera_("camera", "Camera", util::boundingBox(geometryPort_))
    , workGroupSize_("wgsize", "Work group size", ivec2(8, 8), ivec2(0), ivec2(256))
    , useGLSharing_("glsharing", "Use OpenGL sharing", true)
    , trackball_(&camera_)
    , entryExitPoints_(workGroupSize_.get()) {
    addPort(geometryPort_);
    addPort(entryPort_, "ImagePortGroup1");
    addPort(exitPort_, "ImagePortGroup1");
    addProperty(camera_);
    addProperty(workGroupSize_);
    addProperty(useGLSharing_);
    addProperty(trackball_);

    workGroupSize_.onChange([this]() {
        entryExitPoints_.setWorkGroupSize(workGroupSize_.get());
    });

    // Will enable the processor to invalidate when the kernel has recompiled
    entryExitPoints_.addObserver(this);

    if (!InviwoApplication::getPtr()->getSettingsByType<OpenCLSettings>()->isSharingEnabled()) {
        useGLSharing_.setReadOnly(true);
        useGLSharing_.set(false);
    }
    LogWarn(
        "This processor does not compute depth values. It act as an example on how to use OpenCL. "
        "Use OpenGL based Entry Exit Points processor, in module BaseGL, instead.");
}

void EntryExitPointsCLProcessor::process() {
    auto mesh = geometryPort_.getData();
    if (!mesh) return;

    if (mesh->getNumberOfIndicies() == 0) {
        LogInfo("Unable to compute entry exit points for a mesh without indices");
        return;
    }
    // Computes entry exit points in texture coordinates
    entryExitPoints_.computeEntryExitPoints(
        mesh.get(), camera_.viewMatrix(), camera_.projectionMatrix(),
        entryPort_.getEditableData()->getColorLayer(), exitPort_.getEditableData()->getColorLayer(),
        useGLSharing_.get());
}

void EntryExitPointsCLProcessor::onKernelCompiled(const cl::Kernel*) {
    invalidate(InvalidationLevel::InvalidResources);
}

}  // namespace inviwo
<commit_msg>Jenkins: Format fixes<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2014-2019 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <modules/basecl/processors/entryexitpointsclprocessor.h>
#include <inviwo/core/datastructures/geometry/mesh.h>
#include <modules/opencl/image/imagecl.h>
#include <modules/opencl/image/imageclgl.h>
#include <modules/opencl/settings/openclsettings.h>
#include <modules/opencl/syncclgl.h>
#include <inviwo/core/algorithm/boundingbox.h>

namespace inviwo {

const ProcessorInfo EntryExitPointsCLProcessor::processorInfo_{
    "org.inviwo.EntryExitPointsCL",  // Class identifier
    "Entry Exit Points",             // Display name
    "Mesh Rendering",                // Category
    CodeState::Stable,               // Code state
    Tags::CL,                        // Tags
};
const ProcessorInfo EntryExitPointsCLProcessor::getProcessorInfo() const { return processorInfo_; }

EntryExitPointsCLProcessor::EntryExitPointsCLProcessor()
    : Processor()
    , KernelObserver()
    , geometryPort_("geometry")
    , entryPort_(
          "entry-points",
          DataVec4Float32::get())  // Using 8-bits will create artifacts when entering the volume
    , exitPort_("exit-points", DataVec4Float32::get())
    , camera_("camera", "Camera", util::boundingBox(geometryPort_))
    , workGroupSize_("wgsize", "Work group size", ivec2(8, 8), ivec2(0), ivec2(256))
    , useGLSharing_("glsharing", "Use OpenGL sharing", true)
    , trackball_(&camera_)
    , entryExitPoints_(workGroupSize_.get()) {
    addPort(geometryPort_);
    addPort(entryPort_, "ImagePortGroup1");
    addPort(exitPort_, "ImagePortGroup1");
    addProperty(camera_);
    addProperty(workGroupSize_);
    addProperty(useGLSharing_);
    addProperty(trackball_);

    workGroupSize_.onChange([this]() { entryExitPoints_.setWorkGroupSize(workGroupSize_.get()); });

    // Will enable the processor to invalidate when the kernel has recompiled
    entryExitPoints_.addObserver(this);

    if (!InviwoApplication::getPtr()->getSettingsByType<OpenCLSettings>()->isSharingEnabled()) {
        useGLSharing_.setReadOnly(true);
        useGLSharing_.set(false);
    }
    LogWarn(
        "This processor does not compute depth values. It act as an example on how to use OpenCL. "
        "Use OpenGL based Entry Exit Points processor, in module BaseGL, instead.");
}

void EntryExitPointsCLProcessor::process() {
    auto mesh = geometryPort_.getData();
    if (!mesh) return;

    if (mesh->getNumberOfIndicies() == 0) {
        LogInfo("Unable to compute entry exit points for a mesh without indices");
        return;
    }
    // Computes entry exit points in texture coordinates
    entryExitPoints_.computeEntryExitPoints(
        mesh.get(), camera_.viewMatrix(), camera_.projectionMatrix(),
        entryPort_.getEditableData()->getColorLayer(), exitPort_.getEditableData()->getColorLayer(),
        useGLSharing_.get());
}

void EntryExitPointsCLProcessor::onKernelCompiled(const cl::Kernel*) {
    invalidate(InvalidationLevel::InvalidResources);
}

}  // namespace inviwo
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/canbus/vehicle/lincoln/protocol/brakeinfo_74.h"

#include "gtest/gtest.h"

namespace apollo {
namespace canbus {
namespace lincoln {

class Brakeinfo74Test : public ::testing::Test {
 public:
  virtual void SetUp() {}
};

TEST_F(Brakeinfo74Test, simple) {
  Brakeinfo74 brakeinfo;
  uint8_t data = 0x64U;
  int32_t length = 8;
  ChassisDetail cd;
  brakeinfo.Parse(&data, length, &cd);

  EXPECT_FALSE(cd.esp().is_abs_active());
  EXPECT_FALSE(cd.esp().is_abs_enabled());
  EXPECT_FALSE(cd.esp().is_stab_active());
  EXPECT_FALSE(cd.esp().is_stab_enabled());
  EXPECT_FALSE(cd.esp().is_trac_active());
  EXPECT_FALSE(cd.esp().is_trac_enabled());

  EXPECT_EQ(cd.epb().parking_brake_status(), Epb::PBRAKE_OFF);
  EXPECT_DOUBLE_EQ(cd.brake().brake_torque_req(), 8592.0);
  EXPECT_EQ(cd.brake().hsa_status(), Brake::HSA_INACTIVE);
  EXPECT_DOUBLE_EQ(cd.brake().brake_torque_act(), 0.0);
  EXPECT_EQ(cd.brake().hsa_status(), Brake::HSA_OFF);
  EXPECT_DOUBLE_EQ(cd.brake().wheel_torque_act(), 8192.0);
  EXPECT_FALSE(cd.vehicle_spd().is_vehicle_standstill());
  EXPECT_DOUBLE_EQ(cd.vehicle_spd().acc_est(), 0.0);
}

}  // namespace lincoln
}  // namespace apollo
}  // namespace canbus
<commit_msg>temporarily fixed brakeinfo74_test. TODO: extract chassis_detail data from rosbag and use them for test.<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/canbus/vehicle/lincoln/protocol/brakeinfo_74.h"

#include "gtest/gtest.h"

namespace apollo {
namespace canbus {
namespace lincoln {

class Brakeinfo74Test : public ::testing::Test {
 public:
  virtual void SetUp() {}
};

TEST_F(Brakeinfo74Test, simple) {
  Brakeinfo74 brakeinfo;
  uint8_t data[8] = {0x64U};
  int32_t length = 8;
  ChassisDetail cd;
  brakeinfo.Parse(data, length, &cd);

  EXPECT_FALSE(cd.esp().is_abs_active());
  EXPECT_FALSE(cd.esp().is_abs_enabled());
  EXPECT_FALSE(cd.esp().is_stab_active());
  EXPECT_FALSE(cd.esp().is_stab_enabled());
  EXPECT_FALSE(cd.esp().is_trac_active());
  EXPECT_FALSE(cd.esp().is_trac_enabled());

  EXPECT_EQ(cd.epb().parking_brake_status(), Epb::PBRAKE_OFF);
  EXPECT_DOUBLE_EQ(cd.brake().brake_torque_req(), 400.0);
  EXPECT_EQ(cd.brake().hsa_status(), Brake::HSA_INACTIVE);
  EXPECT_DOUBLE_EQ(cd.brake().brake_torque_act(), 0.0);
  EXPECT_EQ(cd.brake().hsa_status(), Brake::HSA_OFF);
  EXPECT_DOUBLE_EQ(cd.brake().wheel_torque_act(), 0.0);
  EXPECT_FALSE(cd.vehicle_spd().is_vehicle_standstill());
  EXPECT_DOUBLE_EQ(cd.vehicle_spd().acc_est(), 0.0);
}

}  // namespace lincoln
}  // namespace apollo
}  // namespace canbus
<|endoftext|>


<commit_before><commit_msg>Planning: add third order derivate into objective function<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2013 Plenluno All rights reserved.

#include <libnode/http.h>
#include <libnode/node.h>
#include <libnode/trace.h>

#include <libj/console.h>

#include <google/gflags.h>

DEFINE_int32(repeat, 1, "the number of repetitions");

namespace libj {
namespace node {
namespace example {

void printRequest(Int id, String::CPtr method, String::CPtr url) {
    console::printf(console::LEVEL_NORMAL, "[%d] ", id);
    console::printv(console::LEVEL_NORMAL, "%v %v\n", method, url);
}

class OnData : LIBJ_JS_FUNCTION(OnData)
 public:
    OnData(
        Int id,
        String::CPtr method,
        String::CPtr url)
        : id_(id)
        , method_(method)
        , url_(url) {}

    virtual Value operator()(JsArray::Ptr args) {
        printRequest(id_, method_, url_);
        console::printv(console::LEVEL_NORMAL, "%v\n\n", args->get(0));
        return UNDEFINED;
    }

 private:
    Int id_;
    String::CPtr method_;
    String::CPtr url_;
};

class OnResponse : LIBJ_JS_FUNCTION(OnResponse)
 public:
    OnResponse(
        Int id,
        String::CPtr method,
        String::CPtr url)
        : id_(id)
        , method_(method)
        , url_(url) {}

    virtual Value operator()(JsArray::Ptr args) {
        http::ClientResponse::Ptr res = args->getPtr<http::ClientResponse>(0);
        res->on(
            http::ClientResponse::EVENT_DATA,
            JsFunction::Ptr(new OnData(id_, method_, url_)));
        return UNDEFINED;
    }

 private:
    Int id_;
    String::CPtr method_;
    String::CPtr url_;
};

class OnError : LIBJ_JS_FUNCTION(OnError)
 public:
    OnError(
        Int id_,
        String::CPtr method,
        String::CPtr url)
        : method_(method)
        , url_(url) {}

    virtual Value operator()(JsArray::Ptr args) {
        printRequest(id_, method_, url_);
        console::printv(console::LEVEL_NORMAL, "%v\n\n", args->get(0));
        return UNDEFINED;
    }

 private:
    Int id_;
    String::CPtr method_;
    String::CPtr url_;
};

void httpClient(String::CPtr url) {
    LIBJ_STATIC_SYMBOL_DEF(symGet, "GET");

    http::ClientRequest::Ptr req;
    for (Int i = 0; i < FLAGS_repeat; i++) {
        req = http::request(
            url,
            JsFunction::Ptr(new OnResponse(i, symGet, url)));
        req->on(
            http::ClientRequest::EVENT_ERROR,
            JsFunction::Ptr(new OnError(i, symGet, url)));
        req->end();
    }
    node::run();
}

}  // namespace exampel
}  // namespace node
}  // namespace libj

int main(int argc, char** argv) {
    std::string usage = "usage: http-client url";
    google::SetUsageMessage("\n\n" + usage);
    google::ParseCommandLineFlags(&argc, &argv, true);
    if (argc < 2) {
        libj::console::log(usage.data());
        return 0;
    }

    LIBNODE_DEBUG_TRACE_ON;
    namespace node = libj::node;
    node::example::httpClient(libj::String::create(argv[1]));
    LIBNODE_DEBUG_TRACE_OFF;
    return 0;
}
<commit_msg>fix wrong request IDs<commit_after>// Copyright (c) 2013 Plenluno All rights reserved.

#include <libnode/http.h>
#include <libnode/node.h>
#include <libnode/trace.h>

#include <libj/console.h>

#include <google/gflags.h>

DEFINE_int32(repeat, 1, "the number of repetitions");

namespace libj {
namespace node {
namespace example {

void printRequest(Int id, String::CPtr method, String::CPtr url) {
    console::printf(console::LEVEL_NORMAL, "[%d] ", id);
    console::printv(console::LEVEL_NORMAL, "%v %v\n", method, url);
}

class OnData : LIBJ_JS_FUNCTION(OnData)
 public:
    OnData(
        Int id,
        String::CPtr method,
        String::CPtr url)
        : id_(id)
        , method_(method)
        , url_(url) {}

    virtual Value operator()(JsArray::Ptr args) {
        printRequest(id_, method_, url_);
        console::printv(console::LEVEL_NORMAL, "%v\n\n", args->get(0));
        return UNDEFINED;
    }

 private:
    Int id_;
    String::CPtr method_;
    String::CPtr url_;
};

class OnResponse : LIBJ_JS_FUNCTION(OnResponse)
 public:
    OnResponse(
        Int id,
        String::CPtr method,
        String::CPtr url)
        : id_(id)
        , method_(method)
        , url_(url) {}

    virtual Value operator()(JsArray::Ptr args) {
        http::ClientResponse::Ptr res = args->getPtr<http::ClientResponse>(0);
        res->on(
            http::ClientResponse::EVENT_DATA,
            JsFunction::Ptr(new OnData(id_, method_, url_)));
        return UNDEFINED;
    }

 private:
    Int id_;
    String::CPtr method_;
    String::CPtr url_;
};

class OnError : LIBJ_JS_FUNCTION(OnError)
 public:
    OnError(
        Int id,
        String::CPtr method,
        String::CPtr url)
        : id_(id)
        , method_(method)
        , url_(url) {}

    virtual Value operator()(JsArray::Ptr args) {
        printRequest(id_, method_, url_);
        console::printv(console::LEVEL_NORMAL, "%v\n\n", args->get(0));
        return UNDEFINED;
    }

 private:
    Int id_;
    String::CPtr method_;
    String::CPtr url_;
};

void httpClient(String::CPtr url) {
    LIBJ_STATIC_SYMBOL_DEF(symGet, "GET");

    http::ClientRequest::Ptr req;
    for (Int i = 0; i < FLAGS_repeat; i++) {
        req = http::request(
            url,
            JsFunction::Ptr(new OnResponse(i, symGet, url)));
        req->on(
            http::ClientRequest::EVENT_ERROR,
            JsFunction::Ptr(new OnError(i, symGet, url)));
        req->end();
    }
    node::run();
}

}  // namespace exampel
}  // namespace node
}  // namespace libj

int main(int argc, char** argv) {
    std::string usage = "usage: http-client url";
    google::SetUsageMessage("\n\n" + usage);
    google::ParseCommandLineFlags(&argc, &argv, true);
    if (argc < 2) {
        libj::console::log(usage.data());
        return 0;
    }

    LIBNODE_DEBUG_TRACE_ON;
    namespace node = libj::node;
    node::example::httpClient(libj::String::create(argv[1]));
    LIBNODE_DEBUG_TRACE_OFF;
    return 0;
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/toolkits/deciders/side_pass_path_decider.h"

#include <algorithm>
#include <string>
#include <utility>

#include "modules/common/proto/pnc_point.pb.h"

#include "modules/common/configs/vehicle_config_helper.h"
#include "modules/map/hdmap/hdmap_util.h"
#include "modules/planning/common/frame.h"
#include "modules/planning/common/planning_gflags.h"

namespace apollo {
namespace planning {

using apollo::common::ErrorCode;
using apollo::common::Status;
using apollo::common::TrajectoryPoint;
using apollo::common::VehicleConfigHelper;
using apollo::hdmap::PathOverlap;
using apollo::common::util::MakePointENU;
using apollo::hdmap::HDMapUtil;

constexpr double kRoadBuffer = 0.2;
constexpr double kObstacleBuffer = 0.1;
constexpr double kPlanDistAfterObs = 5.0;
constexpr double kSidePassPathLength = 50.0;

SidePassPathDecider::SidePassPathDecider(const TaskConfig &config)
    : Decider(config) {
  fem_qp_.reset(new Fem1dExpandedJerkQpProblem());
  delta_s_ = config.side_pass_path_decider_config().path_resolution();
  const int n = static_cast<int>(
      config.side_pass_path_decider_config().total_path_length() / delta_s_);
  std::array<double, 3> l_init = {0.0, 0.0, 0.0};
  std::array<double, 5> w = {
      config.side_pass_path_decider_config().l_weight(),
      config.side_pass_path_decider_config().dl_weight(),
      config.side_pass_path_decider_config().ddl_weight(),
      config.side_pass_path_decider_config().dddl_weight(),
      config.side_pass_path_decider_config().guiding_line_weight(),
  };
  CHECK(fem_qp_->Init(n, l_init, delta_s_, w,
                      config.side_pass_path_decider_config().max_dddl()));
}

Status SidePassPathDecider::Process(Frame *frame,
                                    ReferenceLineInfo *reference_line_info) {
  adc_planning_start_point_ = frame->PlanningStartPoint();
  adc_frenet_frame_point_ =
      reference_line_info->reference_line().GetFrenetPoint(
          frame->PlanningStartPoint());
  if (!GeneratePath(frame, reference_line_info)) {
    const std::string msg = "Fail to generate path.";
    AERROR << msg;
    return Status(ErrorCode::PLANNING_ERROR, msg);
  }
  return Status::OK();
}

bool SidePassPathDecider::BuildSidePathDecision(
    Frame *frame, ReferenceLineInfo *const reference_line_info) {
  hdmap::LaneInfoConstPtr lane;
  double s = 0.0;
  double l = 0.0;
  if (HDMapUtil::BaseMapPtr()->GetNearestLaneWithHeading(
          common::util::MakePointENU(
              adc_planning_start_point_.path_point().x(),
              adc_planning_start_point_.path_point().y(),
              adc_planning_start_point_.path_point().z()),
          1.0, adc_planning_start_point_.path_point().theta(), M_PI / 3.0,
          &lane, &s, &l) != 0) {
    AERROR << "Failed to find nearest lane from map at position: "
           << adc_planning_start_point_.DebugString()
           << ", heading:" << adc_planning_start_point_.path_point().theta();
    return false;
  }

  const auto &lane_pb = lane->lane();
  ADEBUG << lane_pb.ShortDebugString();
  if (lane_pb.left_neighbor_forward_lane_id_size() > 0) {
    decided_direction_ = SidePassDirection::LEFT;
  } else if (lane_pb.right_neighbor_forward_lane_id_size() > 0) {
    decided_direction_ = SidePassDirection::RIGHT;
  } else if (lane_pb.left_neighbor_reverse_lane_id_size() > 0) {
    decided_direction_ = SidePassDirection::LEFT;
  } else if (lane_pb.right_neighbor_reverse_lane_id_size() > 0) {
    decided_direction_ = SidePassDirection::RIGHT;
  } else {
    AERROR << "Fail to find side pass direction.";
    return false;
  }
  return true;
}

// TODO(All): currently it's the 1st version, and only consider one
// vehicular obstacle ahead. It side-passes that obstacle and move
// back to original reference_line immediately. (without considering
// subsequent obstacles)
bool SidePassPathDecider::GeneratePath(Frame *frame,
                                       ReferenceLineInfo *reference_line_info) {
  // Sanity checks.
  CHECK_NOTNULL(frame);
  CHECK_NOTNULL(reference_line_info);

  // TODO(All): Check if ADC has fully stopped.

  // Decide whether to side-pass from left or right.
  if (!BuildSidePathDecision(frame, reference_line_info)) {
    AERROR << "Failed to decide on a side-pass direction.";
    return false;
  }

  auto lateral_bounds = GetPathBoundaries(
      frame->PlanningStartPoint(), reference_line_info->AdcSlBoundary(),
      reference_line_info->reference_line(),
      reference_line_info->path_decision()->obstacles());

  for (const auto &bd : lateral_bounds) {
    ADEBUG << std::get<0>(bd) << ": " << std::get<1>(bd) << ", "
           << std::get<2>(bd);
  }

  // Call optimizer to generate smooth path.
  fem_qp_->SetVariableBounds(lateral_bounds);
  if (!fem_qp_->Optimize()) {
    AERROR << "Fail to optimize in SidePassPathDecider.";
    return false;
  }

  // TODO(All): put optimized results into ReferenceLineInfo.
  // Update Reference_Line_Info with this newly generated path.
  std::vector<common::FrenetFramePoint> frenet_frame_path;
  double accumulated_s = adc_frenet_frame_point_.s();
  for (size_t i = 0; i < fem_qp_->x().size(); ++i) {
    common::FrenetFramePoint frenet_frame_point;
    ADEBUG << "FrenetFramePath: s = " << accumulated_s
           << ", l = " << fem_qp_->x()[i];
    if (accumulated_s >= reference_line_info->reference_line().Length()) {
      break;
    }
    frenet_frame_point.set_s(accumulated_s);
    frenet_frame_point.set_l(fem_qp_->x()[i]);
    frenet_frame_point.set_dl(fem_qp_->x_derivative()[i]);
    frenet_frame_point.set_ddl(fem_qp_->x_second_order_derivative()[i]);
    frenet_frame_path.push_back(std::move(frenet_frame_point));
    accumulated_s += delta_s_;
  }

  auto path_data = reference_line_info->mutable_path_data();
  if (path_data == nullptr) {
    return false;
  }
  path_data->SetReferenceLine(&reference_line_info->reference_line());
  path_data->SetFrenetPath(FrenetFramePath(frenet_frame_path));

  RecordDebugInfo(reference_line_info);
  return true;
}

std::vector<std::tuple<double, double, double>>
SidePassPathDecider::GetPathBoundaries(
    const TrajectoryPoint &planning_start_point,
    const SLBoundary &adc_sl_boundary, const ReferenceLine &reference_line,
    const IndexedList<std::string, Obstacle> &indexed_obstacles) {
  std::vector<std::tuple<double, double, double>> lateral_bounds;

  const auto nearest_obstacle = GetNearestObstacle(
      adc_sl_boundary, reference_line, indexed_obstacles);
  if (nearest_obstacle == nullptr) {
    AERROR << "Can't find nearest obstacle.";
    return lateral_bounds;
  }

  const auto nearest_obs_sl_boundary = nearest_obstacle->PerceptionSLBoundary();

  // Get road info at every point and fill in the boundary condition vector.
  const double s_increment = 1.0;
  bool is_blocked_by_obs = false;

  // Currently, it only considers one obstacle.
  // For future scaling so that multiple obstacles can be considered,
  // a sweep-line method can be used. The code here leaves some room
  // for the sweep-line method.
  for (double curr_s = adc_frenet_frame_point_.s();
       curr_s < std::min(kSidePassPathLength, reference_line.Length());
       curr_s += s_increment) {
    std::tuple<double, double, double> lateral_bound{
        curr_s - adc_frenet_frame_point_.s(), 0.0, 0.0};

    // Check if boundary should be dictated by obstacle or road
    if (curr_s >= nearest_obs_sl_boundary.start_s() - kPlanDistAfterObs &&
        curr_s <= nearest_obs_sl_boundary.end_s() + kPlanDistAfterObs) {
      is_blocked_by_obs = true;
    } else {
      is_blocked_by_obs = false;
    }
    // Get the road info at the current s.
    double lane_left_width_at_curr_s = 0.0;
    double lane_right_width_at_curr_s = 0.0;
    if (!reference_line.GetLaneWidth(curr_s, &lane_left_width_at_curr_s,
                                     &lane_right_width_at_curr_s)) {
      AERROR << "Fail to get lane width at s = " << curr_s;
      continue;
    }
    const double adc_half_width =
        VehicleConfigHelper::GetConfig().vehicle_param().width() / 2.0;

    // TODO(All): calculate drivable areas
    // lower bound
    std::get<1>(lateral_bound) =
        -(lane_right_width_at_curr_s - adc_half_width - kRoadBuffer);
    // upper bound
    std::get<2>(lateral_bound) =
        lane_left_width_at_curr_s - adc_half_width - kRoadBuffer;

    ADEBUG << "default bound: " << std::get<1>(lateral_bound) << ", "
           << std::get<2>(lateral_bound);

    if (is_blocked_by_obs) {
      if (decided_direction_ == SidePassDirection::LEFT) {
        std::get<1>(lateral_bound) = nearest_obs_sl_boundary.end_l() +
                                     FLAGS_static_decision_nudge_l_buffer +
                                     kObstacleBuffer + adc_half_width;
        std::get<2>(lateral_bound) += lane_left_width_at_curr_s;
      } else if (decided_direction_ == SidePassDirection::RIGHT) {
        std::get<1>(lateral_bound) -= lane_right_width_at_curr_s;
        std::get<2>(lateral_bound) = nearest_obs_sl_boundary.start_l() -
                                     FLAGS_static_decision_nudge_l_buffer -
                                     kObstacleBuffer - adc_half_width;
      } else {
        AERROR << "Side-pass direction undefined.";
        return lateral_bounds;
      }
    }
    ADEBUG << "obstacle bound: " << std::get<0>(lateral_bound) << ", "
           << std::get<1>(lateral_bound) << ", " << std::get<2>(lateral_bound);

    lateral_bounds.push_back(lateral_bound);
  }

  return lateral_bounds;
}

const Obstacle *SidePassPathDecider::GetNearestObstacle(
    const SLBoundary &adc_sl_boundary, const ReferenceLine &reference_line,
    const IndexedList<std::string, Obstacle> &indexed_obstacles) {
  const Obstacle *nearest_obstacle = nullptr;

  // Generate the boundary conditions for the selected direction
  // based on the obstacle ahead and road conditions.
  double adc_end_s = adc_sl_boundary.end_s();

  // Get obstacle info.
  bool no_obs_selected = true;
  double nearest_obs_start_s = 0.0;
  for (const auto *obstacle : indexed_obstacles.Items()) {
    // Filter out obstacles that are behind ADC.
    double obs_start_s = obstacle->PerceptionSLBoundary().start_s();
    double obs_end_s = obstacle->PerceptionSLBoundary().end_s();
    if (obs_end_s < adc_end_s) {
      continue;
    }
    // TODO(All): ignores obstacles that are partially ahead of ADC
    if (obs_start_s < adc_end_s) {
      continue;
    }
    // Filter out those out-of-lane obstacles.
    double lane_left_width_at_start_s = 0.0;
    double lane_left_width_at_end_s = 0.0;
    double lane_right_width_at_start_s = 0.0;
    double lane_right_width_at_end_s = 0.0;
    reference_line.GetLaneWidth(obs_start_s, &lane_left_width_at_start_s,
                                &lane_right_width_at_start_s);
    reference_line.GetLaneWidth(obs_end_s, &lane_left_width_at_end_s,
                                &lane_right_width_at_end_s);
    double lane_left_width = std::min(std::abs(lane_left_width_at_start_s),
                                      std::abs(lane_left_width_at_end_s));
    double lane_right_width = std::min(std::abs(lane_right_width_at_start_s),
                                       std::abs(lane_right_width_at_end_s));
    double obs_start_l = obstacle->PerceptionSLBoundary().start_l();
    double obs_end_l = obstacle->PerceptionSLBoundary().end_l();

    // filter out-of-lane obstacles
    if (obs_start_l > lane_left_width || obs_end_l < -lane_right_width) {
      continue;
    }
    // do NOT sidepass non-vehicle obstacles.
    if (obstacle->Perception().type() !=
        perception::PerceptionObstacle::VEHICLE) {
      continue;
    }
    // For obstacles of interests, select the nearest one.
    // TODO(All): currently, regardless of the orientation
    // of the obstacle, it treats the obstacle as a rectangle
    // with two edges parallel to the reference line and the
    // other two perpendicular to that.
    if (no_obs_selected) {
      nearest_obs_start_s = obs_start_s;
      nearest_obstacle = obstacle;
      no_obs_selected = false;
    }
    if (nearest_obs_start_s > obs_start_s) {
      nearest_obs_start_s = obs_start_s;
    }
  }
  return nearest_obstacle;
}

void SidePassPathDecider::RecordDebugInfo(
    ReferenceLineInfo *reference_line_info) {
  const auto &path_points =
      reference_line_info->path_data().discretized_path().path_points();
  auto *ptr_optimized_path =
      reference_line_info->mutable_debug()->mutable_planning_data()->add_path();
  ptr_optimized_path->set_name(Name());
  ptr_optimized_path->mutable_path_point()->CopyFrom(
      {path_points.begin(), path_points.end()});
}

}  // namespace planning
}  // namespace apollo
<commit_msg>Planning: fixed worldsim 7.<commit_after>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/toolkits/deciders/side_pass_path_decider.h"

#include <algorithm>
#include <string>
#include <utility>

#include "modules/common/proto/pnc_point.pb.h"

#include "modules/common/configs/vehicle_config_helper.h"
#include "modules/map/hdmap/hdmap_util.h"
#include "modules/planning/common/frame.h"
#include "modules/planning/common/planning_gflags.h"

namespace apollo {
namespace planning {

using apollo::common::ErrorCode;
using apollo::common::Status;
using apollo::common::TrajectoryPoint;
using apollo::common::VehicleConfigHelper;
using apollo::hdmap::PathOverlap;
using apollo::common::util::MakePointENU;
using apollo::hdmap::HDMapUtil;

constexpr double kRoadBuffer = 0.2;
constexpr double kObstacleBuffer = 0.1;
constexpr double kPlanDistAfterObs = 5.0;
constexpr double kSidePassPathLength = 50.0;

SidePassPathDecider::SidePassPathDecider(const TaskConfig &config)
    : Decider(config) {
  fem_qp_.reset(new Fem1dExpandedJerkQpProblem());
  delta_s_ = config.side_pass_path_decider_config().path_resolution();
  const int n = static_cast<int>(
      config.side_pass_path_decider_config().total_path_length() / delta_s_);
  std::array<double, 3> l_init = {0.0, 0.0, 0.0};
  std::array<double, 5> w = {
      config.side_pass_path_decider_config().l_weight(),
      config.side_pass_path_decider_config().dl_weight(),
      config.side_pass_path_decider_config().ddl_weight(),
      config.side_pass_path_decider_config().dddl_weight(),
      config.side_pass_path_decider_config().guiding_line_weight(),
  };
  CHECK(fem_qp_->Init(n, l_init, delta_s_, w,
                      config.side_pass_path_decider_config().max_dddl()));
}

Status SidePassPathDecider::Process(Frame *frame,
                                    ReferenceLineInfo *reference_line_info) {
  adc_planning_start_point_ = frame->PlanningStartPoint();
  adc_frenet_frame_point_ =
      reference_line_info->reference_line().GetFrenetPoint(
          frame->PlanningStartPoint());
  if (!GeneratePath(frame, reference_line_info)) {
    const std::string msg = "Fail to generate path.";
    AERROR << msg;
    return Status(ErrorCode::PLANNING_ERROR, msg);
  }
  return Status::OK();
}

bool SidePassPathDecider::BuildSidePathDecision(
    Frame *frame, ReferenceLineInfo *const reference_line_info) {
  hdmap::LaneInfoConstPtr lane;
  double s = 0.0;
  double l = 0.0;
  if (HDMapUtil::BaseMapPtr()->GetNearestLaneWithHeading(
          common::util::MakePointENU(
              adc_planning_start_point_.path_point().x(),
              adc_planning_start_point_.path_point().y(),
              adc_planning_start_point_.path_point().z()),
          1.0, adc_planning_start_point_.path_point().theta(), M_PI / 3.0,
          &lane, &s, &l) != 0) {
    AERROR << "Failed to find nearest lane from map at position: "
           << adc_planning_start_point_.DebugString()
           << ", heading:" << adc_planning_start_point_.path_point().theta();
    return false;
  }

  const auto &lane_pb = lane->lane();
  ADEBUG << lane_pb.ShortDebugString();
  if (lane_pb.left_neighbor_forward_lane_id_size() > 0) {
    decided_direction_ = SidePassDirection::LEFT;
  } else if (lane_pb.right_neighbor_forward_lane_id_size() > 0) {
    decided_direction_ = SidePassDirection::RIGHT;
  } else if (lane_pb.left_neighbor_reverse_lane_id_size() > 0) {
    decided_direction_ = SidePassDirection::LEFT;
  } else if (lane_pb.right_neighbor_reverse_lane_id_size() > 0) {
    decided_direction_ = SidePassDirection::RIGHT;
  } else {
    AERROR << "Fail to find side pass direction.";
    return false;
  }
  return true;
}

// TODO(All): currently it's the 1st version, and only consider one
// vehicular obstacle ahead. It side-passes that obstacle and move
// back to original reference_line immediately. (without considering
// subsequent obstacles)
bool SidePassPathDecider::GeneratePath(Frame *frame,
                                       ReferenceLineInfo *reference_line_info) {
  // Sanity checks.
  CHECK_NOTNULL(frame);
  CHECK_NOTNULL(reference_line_info);

  // TODO(All): Check if ADC has fully stopped.

  // Decide whether to side-pass from left or right.
  if (!BuildSidePathDecision(frame, reference_line_info)) {
    AERROR << "Failed to decide on a side-pass direction.";
    return false;
  }

  auto lateral_bounds = GetPathBoundaries(
      frame->PlanningStartPoint(), reference_line_info->AdcSlBoundary(),
      reference_line_info->reference_line(),
      reference_line_info->path_decision()->obstacles());

  for (const auto &bd : lateral_bounds) {
    ADEBUG << std::get<0>(bd) << ": " << std::get<1>(bd) << ", "
           << std::get<2>(bd);
  }

  // Call optimizer to generate smooth path.
  fem_qp_->SetVariableBounds(lateral_bounds);
  if (!fem_qp_->Optimize()) {
    AERROR << "Fail to optimize in SidePassPathDecider.";
    return false;
  }

  // TODO(All): put optimized results into ReferenceLineInfo.
  // Update Reference_Line_Info with this newly generated path.
  std::vector<common::FrenetFramePoint> frenet_frame_path;
  double accumulated_s = adc_frenet_frame_point_.s();
  for (size_t i = 0; i < fem_qp_->x().size(); ++i) {
    common::FrenetFramePoint frenet_frame_point;
    ADEBUG << "FrenetFramePath: s = " << accumulated_s
           << ", l = " << fem_qp_->x()[i];
    if (accumulated_s >= reference_line_info->reference_line().Length()) {
      break;
    }
    frenet_frame_point.set_s(accumulated_s);
    frenet_frame_point.set_l(fem_qp_->x()[i]);
    frenet_frame_point.set_dl(fem_qp_->x_derivative()[i]);
    frenet_frame_point.set_ddl(fem_qp_->x_second_order_derivative()[i]);
    frenet_frame_path.push_back(std::move(frenet_frame_point));
    accumulated_s += delta_s_;
  }

  auto path_data = reference_line_info->mutable_path_data();
  if (path_data == nullptr) {
    return false;
  }
  path_data->SetReferenceLine(&reference_line_info->reference_line());
  path_data->SetFrenetPath(FrenetFramePath(frenet_frame_path));

  RecordDebugInfo(reference_line_info);
  return true;
}

std::vector<std::tuple<double, double, double>>
SidePassPathDecider::GetPathBoundaries(
    const TrajectoryPoint &planning_start_point,
    const SLBoundary &adc_sl_boundary, const ReferenceLine &reference_line,
    const IndexedList<std::string, Obstacle> &indexed_obstacles) {
  std::vector<std::tuple<double, double, double>> lateral_bounds;

  const auto nearest_obstacle =
      GetNearestObstacle(adc_sl_boundary, reference_line, indexed_obstacles);
  if (nearest_obstacle == nullptr) {
    AERROR << "Can't find nearest obstacle.";
    return lateral_bounds;
  }

  const auto nearest_obs_sl_boundary = nearest_obstacle->PerceptionSLBoundary();

  // Get road info at every point and fill in the boundary condition vector.
  const double s_increment = 1.0;
  bool is_blocked_by_obs = false;

  // Currently, it only considers one obstacle.
  // For future scaling so that multiple obstacles can be considered,
  // a sweep-line method can be used. The code here leaves some room
  // for the sweep-line method.
  for (double curr_s = adc_frenet_frame_point_.s();
       curr_s < std::min(kSidePassPathLength, reference_line.Length());
       curr_s += s_increment) {
    std::tuple<double, double, double> lateral_bound{
        curr_s - adc_frenet_frame_point_.s(), 0.0, 0.0};

    // Check if boundary should be dictated by obstacle or road
    if (curr_s >= nearest_obs_sl_boundary.start_s() - kPlanDistAfterObs &&
        curr_s <= nearest_obs_sl_boundary.end_s() + kPlanDistAfterObs) {
      is_blocked_by_obs = true;
    } else {
      is_blocked_by_obs = false;
    }
    // Get the road info at the current s.
    double lane_left_width_at_curr_s = 0.0;
    double lane_right_width_at_curr_s = 0.0;
    if (!reference_line.GetLaneWidth(curr_s, &lane_left_width_at_curr_s,
                                     &lane_right_width_at_curr_s)) {
      AERROR << "Fail to get lane width at s = " << curr_s;
      continue;
    }
    const double adc_half_width =
        VehicleConfigHelper::GetConfig().vehicle_param().width() / 2.0;

    // TODO(All): calculate drivable areas
    // lower bound
    std::get<1>(lateral_bound) =
        -(lane_right_width_at_curr_s - adc_half_width - kRoadBuffer);
    // upper bound
    std::get<2>(lateral_bound) =
        lane_left_width_at_curr_s - adc_half_width - kRoadBuffer;

    ADEBUG << "default bound: " << std::get<1>(lateral_bound) << ", "
           << std::get<2>(lateral_bound);

    if (is_blocked_by_obs) {
      if (decided_direction_ == SidePassDirection::LEFT) {
        std::get<1>(lateral_bound) = nearest_obs_sl_boundary.end_l() +
                                     FLAGS_static_decision_nudge_l_buffer +
                                     kObstacleBuffer + adc_half_width;
        std::get<2>(lateral_bound) += lane_left_width_at_curr_s;
      } else if (decided_direction_ == SidePassDirection::RIGHT) {
        std::get<1>(lateral_bound) -= lane_right_width_at_curr_s;
        std::get<2>(lateral_bound) = nearest_obs_sl_boundary.start_l() -
                                     FLAGS_static_decision_nudge_l_buffer -
                                     kObstacleBuffer - adc_half_width;
      } else {
        AERROR << "Side-pass direction undefined.";
        return lateral_bounds;
      }
    }
    ADEBUG << "obstacle bound: " << std::get<0>(lateral_bound) << ", "
           << std::get<1>(lateral_bound) << ", " << std::get<2>(lateral_bound);

    lateral_bounds.push_back(lateral_bound);
  }

  return lateral_bounds;
}

const Obstacle *SidePassPathDecider::GetNearestObstacle(
    const SLBoundary &adc_sl_boundary, const ReferenceLine &reference_line,
    const IndexedList<std::string, Obstacle> &indexed_obstacles) {
  const Obstacle *nearest_obstacle = nullptr;

  // Generate the boundary conditions for the selected direction
  // based on the obstacle ahead and road conditions.
  double adc_end_s = adc_sl_boundary.end_s();

  // Get obstacle info.
  bool no_obs_selected = true;
  double nearest_obs_start_s = 0.0;
  for (const auto *obstacle : indexed_obstacles.Items()) {
    // Filter out obstacles that are behind ADC.
    double obs_start_s = obstacle->PerceptionSLBoundary().start_s();
    double obs_end_s = obstacle->PerceptionSLBoundary().end_s();
    if (obs_end_s < adc_end_s) {
      continue;
    }
    // TODO(All): ignores obstacles that are partially ahead of ADC
    if (obs_start_s < adc_end_s) {
      continue;
    }
    // Filter out those out-of-lane obstacles.
    double lane_left_width_at_start_s = 0.0;
    double lane_left_width_at_end_s = 0.0;
    double lane_right_width_at_start_s = 0.0;
    double lane_right_width_at_end_s = 0.0;
    reference_line.GetLaneWidth(obs_start_s, &lane_left_width_at_start_s,
                                &lane_right_width_at_start_s);
    reference_line.GetLaneWidth(obs_end_s, &lane_left_width_at_end_s,
                                &lane_right_width_at_end_s);
    double lane_left_width = std::min(std::abs(lane_left_width_at_start_s),
                                      std::abs(lane_left_width_at_end_s));
    double lane_right_width = std::min(std::abs(lane_right_width_at_start_s),
                                       std::abs(lane_right_width_at_end_s));
    double obs_start_l = obstacle->PerceptionSLBoundary().start_l();
    double obs_end_l = obstacle->PerceptionSLBoundary().end_l();

    // filter out-of-lane obstacles
    if (obs_start_l > lane_left_width || obs_end_l < -lane_right_width) {
      continue;
    }
    // For obstacles of interests, select the nearest one.
    // TODO(All): currently, regardless of the orientation
    // of the obstacle, it treats the obstacle as a rectangle
    // with two edges parallel to the reference line and the
    // other two perpendicular to that.
    if (no_obs_selected) {
      nearest_obs_start_s = obs_start_s;
      nearest_obstacle = obstacle;
      no_obs_selected = false;
    }
    if (nearest_obs_start_s > obs_start_s) {
      nearest_obs_start_s = obs_start_s;
    }
  }
  return nearest_obstacle;
}

void SidePassPathDecider::RecordDebugInfo(
    ReferenceLineInfo *reference_line_info) {
  const auto &path_points =
      reference_line_info->path_data().discretized_path().path_points();
  auto *ptr_optimized_path =
      reference_line_info->mutable_debug()->mutable_planning_data()->add_path();
  ptr_optimized_path->set_name(Name());
  ptr_optimized_path->mutable_path_point()->CopyFrom(
      {path_points.begin(), path_points.end()});
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/toolkits/deciders/side_pass_path_decider.h"

#include <algorithm>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "modules/common/proto/pnc_point.pb.h"
#include "modules/planning/common/frame.h"

namespace apollo {
namespace planning {

using ::apollo::common::ErrorCode;
using ::apollo::common::Status;
using ::apollo::hdmap::PathOverlap;

double ROAD_BUFFER = 0.2;
double OBSTACLE_BUFFER = 0.2;
double PLANNING_DIST_AFTER_OBSTACLE = 3.0;

SidePassPathDecider::SidePassPathDecider(const TaskConfig &config)
    : Decider(config) {
  SetName("SidePassPathDecider");
  fem_qp_.reset(new Fem1dExpandedJerkQpProblem());
  // TODO(lianglia-apollo):
  // Put numbers into config when refactor is finished.
  const int n = 400;
  std::array<double, 3> l_init = {0.0, 0.0, 0.0};
  const double delta_s = 0.5;
  std::array<double, 5> w = {1.0, 2.0, 3.0, 4.0, 5.0};
  constexpr double kMaxLThirdOrderDerivative = 10.0;
  CHECK(fem_qp_->Init(n, l_init, delta_s, w, kMaxLThirdOrderDerivative));
}

Status SidePassPathDecider::Process(Frame *frame,
                                    ReferenceLineInfo *reference_line_info) {
  return Status::OK();
}

Status SidePassPathDecider::BuildSidePathDecision(
    Frame *frame, ReferenceLineInfo *const reference_line_info) {
  // TODO(All): decide side pass from left or right.
  // For now, just go left at all times.
  decided_direction_ = LEFT;
  return Status().OK();
}

// TODO(All): currently it's the 1st version, and only consider one
// vehicular obstacle ahead. It side-passes that obstacle and move
// back to original reference_line immediately. (without considering
// subsequent obstacles)
bool SidePassPathDecider::GeneratePath(Frame *frame,
                                       ReferenceLineInfo *reference_line_info) {
  // Sanity checks.
  CHECK_NOTNULL(frame);
  CHECK_NOTNULL(reference_line_info);

  // Check if ADC has fully stopped.
  // TODO(All)

  // Decide whether to side-pass from left or right.
  if (BuildSidePathDecision(frame, reference_line_info) != Status().OK()) {
    AERROR << "Failed to decide on a side-pass direction.";
    return false;
  }

  // Generate the boundary conditions for the selected direction
  // based on the obstacle ahead and road conditions.
  std::vector<std::pair<double, double>> bound_cond;
  const ReferenceLine& reference_line = reference_line_info->reference_line();
  double adc_end_s = reference_line_info->AdcSlBoundary().end_s();
  // Get obstacle info.
  bool no_obs_selected = true;
  double nearest_obs_start_s, nearest_obs_end_s,
         nearest_obs_start_l, nearest_obs_end_l;
  for (const auto* path_obstacle :
       reference_line_info->path_decision()->path_obstacles().Items()) {
    // Filter out obstacles that are behind ADC.
    double obs_start_s = path_obstacle->PerceptionSLBoundary().start_s();
    double obs_end_s = path_obstacle->PerceptionSLBoundary().end_s();
    if (obs_end_s < adc_end_s) {
      continue;
    }
    // TODO(All): currently, it also ignores obstacles that are
    // partially ahead of ADC, meaning (obs_end_s > adc_end_s) but
    // (obs_start_s < adc_end_s). It treats such obstacles as
    // those that have been considered already in the last cycle.
    if (obs_start_s < adc_end_s) {
      continue;
    }
    // Filter out those out-of-lane obstacles.
    double lane_left_width_at_start_s, lane_left_width_at_end_s,
           lane_right_width_at_start_s, lane_right_width_at_end_s;
    reference_line.GetLaneWidth(obs_start_s,
        &lane_left_width_at_start_s, &lane_right_width_at_start_s);
    reference_line.GetLaneWidth(obs_end_s,
        &lane_left_width_at_end_s, &lane_right_width_at_end_s);
    double lane_left_width = std::min(std::abs(lane_left_width_at_start_s),
                                      std::abs(lane_left_width_at_end_s));
    double lane_right_width = std::min(std::abs(lane_right_width_at_start_s),
                                      std::abs(lane_right_width_at_end_s));
    double obs_start_l = path_obstacle->PerceptionSLBoundary().start_l();
    double obs_end_l = path_obstacle->PerceptionSLBoundary().end_l();
    if (obs_start_l > lane_left_width || -obs_end_l > lane_right_width) {
      continue;
    }
    // Only select vehicle obstacles.
    if (path_obstacle->obstacle()->Perception().type() !=
        perception::PerceptionObstacle::VEHICLE) {
      continue;
    }
    // For obstacles of interests, select the nearest one.
    // TODO(All): currently, regardless of the orientation
    // of the obstacle, it treats the obstacle as a rectangle
    // with two edges parallel to the reference line and the
    // other two perpendicular to that.
    if (no_obs_selected) {
      nearest_obs_start_s = obs_start_s;
      nearest_obs_end_s = obs_end_s;
      nearest_obs_start_l = obs_start_l;
      nearest_obs_end_l = obs_end_l;
      no_obs_selected = false;
    }
    if (nearest_obs_start_s > obs_start_s) {
      nearest_obs_start_s = obs_start_s;
      nearest_obs_end_s = obs_end_s;
      nearest_obs_start_l = obs_start_l;
      nearest_obs_end_l = obs_end_l;
    }
  }
  // Get road info at every point and fill in the boundary condition vector.
  common::PathPoint start_path_point = frame->PlanningStartPoint().path_point();
  common::math::Vec2d start_path_point_vec2d(start_path_point.x(),
                                             start_path_point.y());
  common::SLPoint start_path_point_SL;
  if (!reference_line.XYToSL(start_path_point_vec2d, &start_path_point_SL)) {
    AERROR << "Failed to get the projection from TrajectoryPoint onto "
              "reference_line";
    return false;
  }
  double s_increment = 1.0;
  double curr_s = start_path_point_SL.s();
  bool bound_cond_gen_finished = false;
  bool is_blocked_by_obs = false;
  std::vector<std::tuple<double, double, double>> list_s_leftbound_rightbound;
  // Currently, it only considers one obstacle.
  // For future scaling so that multiple obstacles can be considered,
  // a sweep-line method can be used. The code here leaves some room
  // for the sweep-line method.
  while (!bound_cond_gen_finished) {
    std::tuple<double, double, double> s_leftbound_rightbound;
    std::get<0>(s_leftbound_rightbound) = curr_s;
    // Check if boundary should be dictated by obstacle or road
    if (curr_s >= nearest_obs_start_s && curr_s <= nearest_obs_end_s) {
      is_blocked_by_obs = true;
    } else {
      is_blocked_by_obs = false;
    }
    // Get the road info at the current s.
    double road_left_width_at_curr_s, road_right_width_at_curr_s;
    reference_line.GetRoadWidth(curr_s,
        &road_left_width_at_curr_s, &road_right_width_at_curr_s);
    if (!is_blocked_by_obs) {
      std::get<1>(s_leftbound_rightbound) =
          -std::abs(road_left_width_at_curr_s-ROAD_BUFFER);
      std::get<2>(s_leftbound_rightbound) =
          std::abs(road_right_width_at_curr_s-ROAD_BUFFER);
    } else {
      if (decided_direction_ == LEFT) {
        std::get<1>(s_leftbound_rightbound) =
            -std::abs(road_left_width_at_curr_s-ROAD_BUFFER);
        std::get<2>(s_leftbound_rightbound) =
            -nearest_obs_end_l;
      } else if (decided_direction_ == RIGHT) {
        std::get<1>(s_leftbound_rightbound) =
            -nearest_obs_start_l;
        std::get<2>(s_leftbound_rightbound) =
            std::abs(road_right_width_at_curr_s-ROAD_BUFFER);
      } else {
        AERROR << "Side-pass direction undefined.";
        return false;
      }
    }
    list_s_leftbound_rightbound.push_back(s_leftbound_rightbound);
    // Move to next s
    curr_s += s_increment;
    if (curr_s > PLANNING_DIST_AFTER_OBSTACLE + nearest_obs_end_s) {
      bound_cond_gen_finished = true;
    }
  }
  // Call optimizer to generate smooth path.
  fem_qp_->SetVariableBounds(list_s_leftbound_rightbound);
  fem_qp_->Optimize();

  // TODO(All): put optimized results into ReferenceLineInfo.
  // Update Reference_Line_Info with this newly generated path.

  return true;
}

}  // namespace planning
}  // namespace apollo
<commit_msg>Planning: coding style fixes.<commit_after>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/toolkits/deciders/side_pass_path_decider.h"

#include <algorithm>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "modules/common/proto/pnc_point.pb.h"
#include "modules/planning/common/frame.h"

namespace apollo {
namespace planning {

using ::apollo::common::ErrorCode;
using ::apollo::common::Status;
using ::apollo::hdmap::PathOverlap;

constexpr double kRoadBuffer = 0.2;
constexpr double kObstacleBuffer = 0.2;
constexpr double kPlanDistAfterObs = 3.0;

SidePassPathDecider::SidePassPathDecider(const TaskConfig &config)
    : Decider(config) {
  SetName("SidePassPathDecider");
  fem_qp_.reset(new Fem1dExpandedJerkQpProblem());
  // TODO(lianglia-apollo):
  // Put numbers into config when refactor is finished.
  const int n = 400;
  std::array<double, 3> l_init = {0.0, 0.0, 0.0};
  const double delta_s = 0.5;
  std::array<double, 5> w = {1.0, 2.0, 3.0, 4.0, 5.0};
  constexpr double kMaxLThirdOrderDerivative = 10.0;
  CHECK(fem_qp_->Init(n, l_init, delta_s, w, kMaxLThirdOrderDerivative));
}

Status SidePassPathDecider::Process(Frame *frame,
                                    ReferenceLineInfo *reference_line_info) {
  return Status::OK();
}

Status SidePassPathDecider::BuildSidePathDecision(
    Frame *frame, ReferenceLineInfo *const reference_line_info) {
  // TODO(All): decide side pass from left or right.
  // For now, just go left at all times.
  decided_direction_ = LEFT;
  return Status().OK();
}

// TODO(All): currently it's the 1st version, and only consider one
// vehicular obstacle ahead. It side-passes that obstacle and move
// back to original reference_line immediately. (without considering
// subsequent obstacles)
bool SidePassPathDecider::GeneratePath(Frame *frame,
                                       ReferenceLineInfo *reference_line_info) {
  // Sanity checks.
  CHECK_NOTNULL(frame);
  CHECK_NOTNULL(reference_line_info);

  // Check if ADC has fully stopped.
  // TODO(All)

  // Decide whether to side-pass from left or right.
  if (BuildSidePathDecision(frame, reference_line_info) != Status().OK()) {
    AERROR << "Failed to decide on a side-pass direction.";
    return false;
  }

  // Generate the boundary conditions for the selected direction
  // based on the obstacle ahead and road conditions.
  std::vector<std::pair<double, double>> bound_cond;
  const ReferenceLine& reference_line = reference_line_info->reference_line();
  double adc_end_s = reference_line_info->AdcSlBoundary().end_s();
  // Get obstacle info.
  bool no_obs_selected = true;
  double nearest_obs_start_s = 0.0;
  double nearest_obs_end_s = 0.0;
  double nearest_obs_start_l = 0.0;
  double nearest_obs_end_l = 0.0;
  for (const auto* path_obstacle :
       reference_line_info->path_decision()->path_obstacles().Items()) {
    // Filter out obstacles that are behind ADC.
    double obs_start_s = path_obstacle->PerceptionSLBoundary().start_s();
    double obs_end_s = path_obstacle->PerceptionSLBoundary().end_s();
    if (obs_end_s < adc_end_s) {
      continue;
    }
    // TODO(All): currently, it also ignores obstacles that are
    // partially ahead of ADC, meaning (obs_end_s > adc_end_s) but
    // (obs_start_s < adc_end_s). It treats such obstacles as
    // those that have been considered already in the last cycle.
    if (obs_start_s < adc_end_s) {
      continue;
    }
    // Filter out those out-of-lane obstacles.
    double lane_left_width_at_start_s = 0.0;
    double lane_left_width_at_end_s = 0.0;
    double lane_right_width_at_start_s = 0.0;
    double lane_right_width_at_end_s = 0.0;
    reference_line.GetLaneWidth(obs_start_s,
        &lane_left_width_at_start_s, &lane_right_width_at_start_s);
    reference_line.GetLaneWidth(obs_end_s,
        &lane_left_width_at_end_s, &lane_right_width_at_end_s);
    double lane_left_width = std::min(std::abs(lane_left_width_at_start_s),
                                      std::abs(lane_left_width_at_end_s));
    double lane_right_width = std::min(std::abs(lane_right_width_at_start_s),
                                      std::abs(lane_right_width_at_end_s));
    double obs_start_l = path_obstacle->PerceptionSLBoundary().start_l();
    double obs_end_l = path_obstacle->PerceptionSLBoundary().end_l();
    if (obs_start_l > lane_left_width || -obs_end_l > lane_right_width) {
      continue;
    }
    // Only select vehicle obstacles.
    if (path_obstacle->obstacle()->Perception().type() !=
        perception::PerceptionObstacle::VEHICLE) {
      continue;
    }
    // For obstacles of interests, select the nearest one.
    // TODO(All): currently, regardless of the orientation
    // of the obstacle, it treats the obstacle as a rectangle
    // with two edges parallel to the reference line and the
    // other two perpendicular to that.
    if (no_obs_selected) {
      nearest_obs_start_s = obs_start_s;
      nearest_obs_end_s = obs_end_s;
      nearest_obs_start_l = obs_start_l;
      nearest_obs_end_l = obs_end_l;
      no_obs_selected = false;
    }
    if (nearest_obs_start_s > obs_start_s) {
      nearest_obs_start_s = obs_start_s;
      nearest_obs_end_s = obs_end_s;
      nearest_obs_start_l = obs_start_l;
      nearest_obs_end_l = obs_end_l;
    }
  }
  // Get road info at every point and fill in the boundary condition vector.
  common::PathPoint start_path_point = frame->PlanningStartPoint().path_point();
  common::math::Vec2d start_path_point_vec2d(start_path_point.x(),
                                             start_path_point.y());
  common::SLPoint start_path_point_SL;
  if (!reference_line.XYToSL(start_path_point_vec2d, &start_path_point_SL)) {
    AERROR << "Failed to get the projection from TrajectoryPoint onto "
              "reference_line";
    return false;
  }
  double s_increment = 1.0;
  double curr_s = start_path_point_SL.s();
  bool bound_cond_gen_finished = false;
  bool is_blocked_by_obs = false;
  std::vector<std::tuple<double, double, double>> list_s_leftbound_rightbound;
  // Currently, it only considers one obstacle.
  // For future scaling so that multiple obstacles can be considered,
  // a sweep-line method can be used. The code here leaves some room
  // for the sweep-line method.
  while (!bound_cond_gen_finished) {
    std::tuple<double, double, double> s_leftbound_rightbound;
    std::get<0>(s_leftbound_rightbound) = curr_s;
    // Check if boundary should be dictated by obstacle or road
    if (curr_s >= nearest_obs_start_s - kObstacleBuffer
        && curr_s <= nearest_obs_end_s + kObstacleBuffer) {
      is_blocked_by_obs = true;
    } else {
      is_blocked_by_obs = false;
    }
    // Get the road info at the current s.
    double road_left_width_at_curr_s = 0.0;
    double road_right_width_at_curr_s = 0.0;
    reference_line.GetRoadWidth(curr_s,
        &road_left_width_at_curr_s, &road_right_width_at_curr_s);
    if (!is_blocked_by_obs) {
      std::get<1>(s_leftbound_rightbound) =
          -std::abs(road_left_width_at_curr_s - kRoadBuffer);
      std::get<2>(s_leftbound_rightbound) =
          std::abs(road_right_width_at_curr_s - kRoadBuffer);
    } else {
      if (decided_direction_ == LEFT) {
        std::get<1>(s_leftbound_rightbound) =
            -std::abs(road_left_width_at_curr_s - kRoadBuffer);
        std::get<2>(s_leftbound_rightbound) =
            -nearest_obs_end_l - kObstacleuffer;
      } else if (decided_direction_ == RIGHT) {
        std::get<1>(s_leftbound_rightbound) =
            -nearest_obs_start_l + kObstacleBuffer;
        std::get<2>(s_leftbound_rightbound) =
            std::abs(road_right_width_at_curr_s - kRoadBuffer);
      } else {
        AERROR << "Side-pass direction undefined.";
        return false;
      }
    }
    list_s_leftbound_rightbound.push_back(s_leftbound_rightbound);
    // Move to next s
    curr_s += s_increment;
    if (curr_s > kPlanDistAfterObs + nearest_obs_end_s) {
      bound_cond_gen_finished = true;
    }
  }
  // Call optimizer to generate smooth path.
  fem_qp_->SetVariableBounds(list_s_leftbound_rightbound);
  fem_qp_->Optimize();

  // TODO(All): put optimized results into ReferenceLineInfo.
  // Update Reference_Line_Info with this newly generated path.

  return true;
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before>
#include <platform/platform.h>
#include <platform/system.h>
#include <platform/dispatcher.h>
#include <gl/opengl.h>
#include <base/contract.h>

namespace
{

int safemain( int argc, char **argv )
{
	auto sys = platform::platform::common().create();

	auto win = sys->new_window();
	win->set_title( "Hello World" );
	win->exposed.callback( [&]( void )
	{
		win->acquire();
		glViewport( 0, 0, win->width(), win->height() );
		glClearColor( 0.0, 1.0, 0.0, 1.0 );
		glClear( GL_COLOR_BUFFER_BIT );
		win->release();
	} );

	win->show();

	auto dispatch = sys->get_dispatcher();
	return dispatch->execute();;
}

}

////////////////////////////////////////

int main( int argc, char *argv[] )
{
	int ret = -1;
	try
	{
		ret = safemain( argc, argv );
	}
	catch ( std::exception &e )
	{
		base::print_exception( std::cerr, e );
	}
	return ret;
}

////////////////////////////////////////

<commit_msg>Added a screen listing test.<commit_after>
#include <platform/platform.h>
#include <platform/system.h>
#include <platform/dispatcher.h>
#include <gl/opengl.h>
#include <base/contract.h>

namespace
{

int safemain( int argc, char **argv )
{
	auto sys = platform::platform::common().create();

	auto screens = sys->screens();

	for ( auto scr: screens )
		std::cout << "Screen " << scr->bounds() << ' ' << scr->dpi() << std::endl;

	auto win = sys->new_window();
	win->set_title( "Hello World" );
	win->exposed.callback( [&]( void )
	{
		win->acquire();
		glViewport( 0, 0, win->width(), win->height() );
		glClearColor( 0.0, 1.0, 0.0, 1.0 );
		glClear( GL_COLOR_BUFFER_BIT );
		win->release();
	} );
	win->resized.callback( [&]( double w, double h )
	{
		std::cout << "Resized to: " << w << 'x' << h << std::endl;
	} );

	win->show();

	auto dispatch = sys->get_dispatcher();
	return dispatch->execute();;
}

}

////////////////////////////////////////

int main( int argc, char *argv[] )
{
	int ret = -1;
	try
	{
		ret = safemain( argc, argv );
	}
	catch ( std::exception &e )
	{
		base::print_exception( std::cerr, e );
	}
	return ret;
}

////////////////////////////////////////

<|endoftext|>


<commit_before>#include "testApp.h"

testApp::~testApp() {
    for(int i = 0; i < bufferPlayers.size(); i++) {
        delete bufferPlayers[i];
    }
    bufferPlayers.clear();

    for(int i = 0; i < buffers.size(); i++) {
        delete buffers[i];
    }
    buffers.clear();
}

//--------------------------------------------------------------
void testApp::setup(){
	ofBackground(255,255,255);
    ofSetVerticalSync(true);
	ofSetFrameRate(60);

    // video setup
    camWidth 		= 320;	// try to grab at this size.
	camHeight 		= 240;

    // ready a grabbery source
	vidGrabber.initGrabber(camWidth,camHeight);

    numVideoSources = 3;

    // ready a ipcam source
    string uri = "http://148.61.142.228/axis-cgi/mjpg/video.cgi?resolution="+ ofToString(camWidth) + "x" + ofToString(camHeight);
    vidIpCam.setURI(uri);
    vidIpCam.connect();

    // ready a video source
	vidPlayer.loadMovie("fingers.mov");
	vidPlayer.play();

    currentBufferPlayer = 0;
    currentVideoSource  = 0;

    for(int i = 0; i < 4; i++) {
        ofxVideoBuffer* videoBuffer = new ofxVideoBuffer(100);
        buffers.push_back(videoBuffer);
        ofxVideoBufferPlayer* videoPlayer = new ofxVideoBufferPlayer();
        videoPlayer->loadBuffer(videoBuffer);
        bufferPlayers.push_back(videoPlayer);
    }

    isRecording = false;

}

//--------------------------------------------------------------
void testApp::update() {

    vidGrabber.update();
    vidIpCam.update();
    vidPlayer.update();

    for(int i = 0; i < bufferPlayers.size(); i++) {
        bufferPlayers[i]->update();;
    }

}

//--------------------------------------------------------------
void testApp::draw(){

    ofEnableAlphaBlending();

    ofBackground(0,0,0);

	ofSetColor(255,255,255,255);
    vidGrabber.draw(20,20,160,120);
    ofDrawBitmapString("LIVE GRABBER", 22,32);
    if(currentVideoSource == 0) {

        ofSetColor(isRecording ? 0 : 255,255,0);
        ofNoFill();
        ofRect(20,20,160,120);
    }

	ofSetColor(255,255,255,255);
    vidIpCam.draw(20,140,160,120);
    ofDrawBitmapString("LIVE WEB", 22,152);
    if(currentVideoSource == 1) {
        ofSetColor(isRecording ? 0 : 255,255,0);
        ofNoFill();
        ofRect(20,140,160,120);
    }

	ofSetColor(255,255,255,255);
    vidPlayer.draw(20,260,160,120);
    ofDrawBitmapString("VID", 22,272);
    if(currentVideoSource == 2) {
        ofSetColor(isRecording ? 0 : 255,255,0);
        ofNoFill();
        ofRect(20,260,160,120);
    }

    string keys = "";
    keys += "Keys:\n";
    keys += "Select the Source (ABOVE LEFT)\n";
    keys += "  [1] Next Video Source\n";
    keys += "  [s] Video Grabber Settings\n";
    keys += "\n";
    keys += "Select the Buffer Player (RIGHT)\n";
    keys += "  [`] Next Buffer Player\n";
    keys += "\n";
    keys += "All settings below apply to the\n";
    keys += "current player and buffer.\n";
    keys += "  [SPACE] Toggle Recording\n";
    keys += "  [x] Clear Buffer\n";
    keys += "  [?] Load Test Video Into Buffer\n";
    keys += "  [p] Next Buffer Mode\n";
    keys += "  [q] Next Loop Mode\n";
    keys += "\n";
    keys += "  [[] Loop Point (start) (DOWN)\n";
    keys += "  [{] Loop Point (end)   (DOWN)\n";
    keys += "  []] Loop Point (start) (UP)\n";
    keys += "  [}] Loop Point (end)    (UP)\n";
    keys += "  [c] Clear Loop Points\n";
    keys += "\n";
    keys += "  [-] Decrease Speed\n";
    keys += "  [=] Increase Speed\n";

    ofSetColor(255);
    ofDrawBitmapString(keys,20,400);

    if(isRecording) {
        if(currentVideoSource == 0 && vidGrabber.isFrameNew()) {
            bufferPlayers[currentBufferPlayer]->getVideoBuffer()->bufferFrame(vidGrabber.getPixelsRef());
        } else if(currentVideoSource == 1 ) {//&& vidIpCam.isFrameNew()) { // TODO
            bufferPlayers[currentBufferPlayer]->getVideoBuffer()->bufferFrame(vidIpCam.getPixelsRef());
        } else if(currentVideoSource == 2 && vidPlayer.isFrameNew() ) {
            bufferPlayers[currentBufferPlayer]->getVideoBuffer()->bufferFrame(vidPlayer.getPixelsRef());
        }
    }

    int x = 320;
    int y = 20;

    for(int i = 0; i < bufferPlayers.size(); i++) {

        ofSetColor(255);
        ofFill();
        bufferPlayers[i]->draw(x,y);

        if(currentBufferPlayer == i) {
            ofSetColor(255,255,0);
        } else {
            ofSetColor(255,127);
        }

        ofNoFill();
        ofRect(x,y,camWidth,camHeight);

        if(!bufferPlayers[i]->getVideoBuffer()->isLoadingMovie()) {
            float p = bufferPlayers[i]->getVideoBuffer()->getPercentFull();
            ofFill();
            ofSetColor(255,255,0,127);
            ofRect(x,y+camHeight-5,camWidth*p,5);
        }

        ofSetColor(255);
        // draw some stats
        string stats = bufferPlayers[i]->toString();
        ofDrawBitmapString(stats, x + 20, y + 20);

        x += (camWidth + 5);
        if((x + 320)> ofGetWidth()) {
            y+= camHeight + 5;
            x = 320;
        }
    }

    ofDisableAlphaBlending();

}

//--------------------------------------------------------------
void testApp::keyPressed  (int key){

    int l0 = bufferPlayers[currentBufferPlayer]->getLoopPointsStart();
    int l1 = bufferPlayers[currentBufferPlayer]->getLoopPointsEnd();
    ofLoopType lt = bufferPlayers[currentBufferPlayer]->getLoopType();
    ofVideoBufferType vbt = bufferPlayers[currentBufferPlayer]->getVideoBuffer()->getBufferType();

    float speed = bufferPlayers[currentBufferPlayer]->getSpeed();

    switch (key) {
        case '`':
            currentBufferPlayer = (currentBufferPlayer + 1) % bufferPlayers.size();
            break;
        case '1':
            currentVideoSource = (currentVideoSource + 1) % 3;
            break;
        case 's':
            vidGrabber.videoSettings();
            break;
        case 'p':
            if(vbt == OFX_VIDEO_BUFFER_NORMAL) vbt = OFX_VIDEO_BUFFER_CIRCULAR;
            else if(vbt == OFX_VIDEO_BUFFER_CIRCULAR) vbt = OFX_VIDEO_BUFFER_PASSTHROUGH;
            else if(vbt == OFX_VIDEO_BUFFER_PASSTHROUGH) vbt = OFX_VIDEO_BUFFER_NORMAL;
            bufferPlayers[currentBufferPlayer]->getVideoBuffer()->setBufferType(vbt);
            break;
        case 'q':
            // cycle through the loop mode
            if(lt == OF_LOOP_NONE) lt = OF_LOOP_NORMAL;
            else if(lt == OF_LOOP_NORMAL) lt = OF_LOOP_PALINDROME;
            else if(lt == OF_LOOP_PALINDROME) lt = OF_LOOP_NONE;
            bufferPlayers[currentBufferPlayer]->setLoopType(lt);
            break;
        case '[':
            bufferPlayers[currentBufferPlayer]->setLoopPointsStart(l0-1);
            break;
        case '{':
            bufferPlayers[currentBufferPlayer]->setLoopPointsEnd(l1-1);
            break;
        case ']':
            bufferPlayers[currentBufferPlayer]->setLoopPointsStart(l0+1);
            break;
        case '}':
            bufferPlayers[currentBufferPlayer]->setLoopPointsEnd(l1+1);
            break;
        case 'c':
            bufferPlayers[currentBufferPlayer]->clearLoopPoints();
            break;
        case ' ':
            isRecording = !isRecording;
            break;
        case 'x':
            bufferPlayers[currentBufferPlayer]->getVideoBuffer()->clear();
            break;
        case '0':
            bufferPlayers[currentBufferPlayer]->getVideoBuffer()->loadMovie("fingers.mov");
            break;
        case '-':
            speed -= .25;
            bufferPlayers[currentBufferPlayer]->setSpeed(speed);
            break;
        case '=':
            speed += .25;
            bufferPlayers[currentBufferPlayer]->setSpeed(speed);
            break;

        default:
            break;
    }

}

//--------------------------------------------------------------
void testApp::keyReleased(int key){
}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){
}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){
    float speed = ofMap(x, 0, ofGetWidth(), 0, 20);
    bufferPlayers[currentBufferPlayer]->setSpeed(speed);
}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){
}

//--------------------------------------------------------------
void testApp::resized(int w, int h){

}
<commit_msg>Fixed position setting.  Added a few more video buffers for testing.<commit_after>#include "testApp.h"

testApp::~testApp() {
    for(int i = 0; i < bufferPlayers.size(); i++) {
        delete bufferPlayers[i];
    }
    bufferPlayers.clear();

    for(int i = 0; i < buffers.size(); i++) {
        delete buffers[i];
    }
    buffers.clear();
}

//--------------------------------------------------------------
void testApp::setup(){
	ofBackground(255,255,255);
    ofSetVerticalSync(true);
	ofSetFrameRate(60);

    // video setup
    camWidth 		= 320;	// try to grab at this size.
	camHeight 		= 240;

    // ready a grabbery source
	vidGrabber.initGrabber(camWidth,camHeight);

    numVideoSources = 3;

    // ready a ipcam source
    string uri = "http://148.61.142.228/axis-cgi/mjpg/video.cgi?resolution="+ ofToString(camWidth) + "x" + ofToString(camHeight);
    vidIpCam.setURI(uri);
    vidIpCam.connect();

    // ready a video source
	vidPlayer.loadMovie("fingers.mov");
	vidPlayer.play();

    currentBufferPlayer = 0;
    currentVideoSource  = 0;

    for(int i = 0; i < 6; i++) {
        ofxVideoBuffer* videoBuffer = new ofxVideoBuffer(100);
        buffers.push_back(videoBuffer);
        ofxVideoBufferPlayer* videoPlayer = new ofxVideoBufferPlayer();
        videoPlayer->loadBuffer(videoBuffer);
        bufferPlayers.push_back(videoPlayer);
    }

    isRecording = false;

}

//--------------------------------------------------------------
void testApp::update() {

    vidGrabber.update();
    vidIpCam.update();
    vidPlayer.update();

    for(int i = 0; i < bufferPlayers.size(); i++) {
        bufferPlayers[i]->update();;
    }

}

//--------------------------------------------------------------
void testApp::draw(){

    ofEnableAlphaBlending();

    ofBackground(0,0,0);

	ofSetColor(255,255,255,255);
    vidGrabber.draw(20,20,160,120);
    ofDrawBitmapString("LIVE GRABBER", 22,32);
    if(currentVideoSource == 0) {

        ofSetColor(isRecording ? 0 : 255,255,0);
        ofNoFill();
        ofRect(20,20,160,120);
    }

	ofSetColor(255,255,255,255);
    vidIpCam.draw(20,140,160,120);
    ofDrawBitmapString("LIVE WEB", 22,152);
    if(currentVideoSource == 1) {
        ofSetColor(isRecording ? 0 : 255,255,0);
        ofNoFill();
        ofRect(20,140,160,120);
    }

	ofSetColor(255,255,255,255);
    vidPlayer.draw(20,260,160,120);
    ofDrawBitmapString("VID", 22,272);
    if(currentVideoSource == 2) {
        ofSetColor(isRecording ? 0 : 255,255,0);
        ofNoFill();
        ofRect(20,260,160,120);
    }

    string keys = "";
    keys += "Keys:\n";
    keys += "Select the Source (ABOVE LEFT)\n";
    keys += "  [1] Next Video Source\n";
    keys += "  [s] Video Grabber Settings\n";
    keys += "\n";
    keys += "Select the Buffer Player (RIGHT)\n";
    keys += "  [`] Next Buffer Player\n";
    keys += "\n";
    keys += "All settings below apply to the\n";
    keys += "current player and buffer.\n";
    keys += "  [SPACE] Toggle Recording\n";
    keys += "  [x] Clear Buffer\n";
    keys += "  [?] Load Test Video Into Buffer\n";
    keys += "  [p] Next Buffer Mode\n";
    keys += "  [q] Next Loop Mode\n";
    keys += "\n";
    keys += "  [[] Loop Point (start) (DOWN)\n";
    keys += "  [{] Loop Point (end)   (DOWN)\n";
    keys += "  []] Loop Point (start) (UP)\n";
    keys += "  [}] Loop Point (end)   (UP)\n";
    keys += "  [c] Clear Loop Points\n";
    keys += "\n";
    keys += "  [-] Decrease Speed\n";
    keys += "  [=] Increase Speed\n";
    keys += "\n";
    keys += "  [_] Decrease Position\n";
    keys += "  [+] Increase Position\n";

    ofSetColor(255);
    ofDrawBitmapString(keys,20,400);

    if(isRecording) {
        if(currentVideoSource == 0 && vidGrabber.isFrameNew()) {
            bufferPlayers[currentBufferPlayer]->getVideoBuffer()->bufferFrame(vidGrabber.getPixelsRef());
        } else if(currentVideoSource == 1 ) {//&& vidIpCam.isFrameNew()) { // TODO
            bufferPlayers[currentBufferPlayer]->getVideoBuffer()->bufferFrame(vidIpCam.getPixelsRef());
        } else if(currentVideoSource == 2 && vidPlayer.isFrameNew() ) {
            bufferPlayers[currentBufferPlayer]->getVideoBuffer()->bufferFrame(vidPlayer.getPixelsRef());
        }
    }

    int x = 320;
    int y = 20;

    for(int i = 0; i < bufferPlayers.size(); i++) {

        ofSetColor(255);
        ofFill();
        bufferPlayers[i]->draw(x,y);

        if(currentBufferPlayer == i) {
            ofSetColor(255,255,0);
        } else {
            ofSetColor(255,127);
        }

        ofNoFill();
        ofRect(x,y,camWidth,camHeight);

        if(!bufferPlayers[i]->getVideoBuffer()->isLoadingMovie()) {
            float p = bufferPlayers[i]->getVideoBuffer()->getPercentFull();
            ofFill();
            ofSetColor(255,255,0,127);
            ofRect(x,y+camHeight-5,camWidth*p,5);
        }

        ofSetColor(255);
        // draw some stats
        string stats = bufferPlayers[i]->toString();
        ofDrawBitmapString(stats, x + 20, y + 20);

        x += (camWidth + 0);
        if((x + 320)> ofGetWidth()) {
            y+= camHeight + 0;
            x = 320;
        }
    }

    ofDisableAlphaBlending();

}

//--------------------------------------------------------------
void testApp::keyPressed  (int key){

    int l0 = bufferPlayers[currentBufferPlayer]->getLoopPointsStart();
    int l1 = bufferPlayers[currentBufferPlayer]->getLoopPointsEnd();
    ofLoopType lt = bufferPlayers[currentBufferPlayer]->getLoopType();
    ofVideoBufferType vbt = bufferPlayers[currentBufferPlayer]->getVideoBuffer()->getBufferType();

    float speed = bufferPlayers[currentBufferPlayer]->getSpeed();

    int position = bufferPlayers[currentBufferPlayer]->getPosition();

    switch (key) {
        case '`':
            currentBufferPlayer = (currentBufferPlayer + 1) % bufferPlayers.size();
            break;
        case '1':
            currentVideoSource = (currentVideoSource + 1) % 3;
            break;
        case 's':
            vidGrabber.videoSettings();
            break;
        case 'p':
            if(vbt == OFX_VIDEO_BUFFER_NORMAL) vbt = OFX_VIDEO_BUFFER_CIRCULAR;
            else if(vbt == OFX_VIDEO_BUFFER_CIRCULAR) vbt = OFX_VIDEO_BUFFER_PASSTHROUGH;
            else if(vbt == OFX_VIDEO_BUFFER_PASSTHROUGH) vbt = OFX_VIDEO_BUFFER_NORMAL;
            bufferPlayers[currentBufferPlayer]->getVideoBuffer()->setBufferType(vbt);
            break;
        case 'q':
            // cycle through the loop mode
            if(lt == OF_LOOP_NONE) lt = OF_LOOP_NORMAL;
            else if(lt == OF_LOOP_NORMAL) lt = OF_LOOP_PALINDROME;
            else if(lt == OF_LOOP_PALINDROME) lt = OF_LOOP_NONE;
            bufferPlayers[currentBufferPlayer]->setLoopType(lt);
            break;
        case '[':
            bufferPlayers[currentBufferPlayer]->setLoopPointsStart(l0-1);
            break;
        case '{':
            bufferPlayers[currentBufferPlayer]->setLoopPointsEnd(l1-1);
            break;
        case ']':
            bufferPlayers[currentBufferPlayer]->setLoopPointsStart(l0+1);
            break;
        case '}':
            bufferPlayers[currentBufferPlayer]->setLoopPointsEnd(l1+1);
            break;
        case 'c':
            bufferPlayers[currentBufferPlayer]->clearLoopPoints();
            break;
        case ' ':
            isRecording = !isRecording;
            break;
        case 'x':
            bufferPlayers[currentBufferPlayer]->getVideoBuffer()->clear();
            break;
        case '0':
            bufferPlayers[currentBufferPlayer]->getVideoBuffer()->loadMovie("fingers.mov");
            break;
        case '-':
            speed -= .05;
            bufferPlayers[currentBufferPlayer]->setSpeed(speed);
            break;
        case '=':
            speed += .05;
            bufferPlayers[currentBufferPlayer]->setSpeed(speed);
            break;
        case '_':
            bufferPlayers[currentBufferPlayer]->setPosition(position - 1);
            break;
        case '+':
            bufferPlayers[currentBufferPlayer]->setPosition(position + 1);
            break;
        default:
            break;
    }

}

//--------------------------------------------------------------
void testApp::keyReleased(int key){
}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){
}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){
    float speed = ofMap(x, 0, ofGetWidth(), 0, 20);
    bufferPlayers[currentBufferPlayer]->setSpeed(speed);
}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){
}

//--------------------------------------------------------------
void testApp::resized(int w, int h){

}
<|endoftext|>