Skip to content
This repository was archived by the owner on May 22, 2021. It is now read-only.

Commit 8f1baf3

Browse files
committed
Merge pull request DIT112-V20#57 from DIT112-V20/lasers
Backend drivers for various smartcar_lib sensors, servo and the VL53L0X
2 parents b567a1b + f888e74 commit 8f1baf3

32 files changed

+883
-27
lines changed

CMake/Modules/Patcher.cmake

+8-1
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,11 @@ function (hard_patch FILE FIND REPLACE)
2020
string (REPLACE "${FIND}" "${REPLACE}"
2121
PATCH_OUT "${PATCH_IN}")
2222
file (WRITE "${FILE}" "${PATCH_OUT}")
23-
endfunction()
23+
endfunction()
24+
25+
function (hard_patch_regexp FILE FIND REPLACE)
26+
file (READ "${FILE}" PATCH_IN)
27+
string (REGEX REPLACE "${FIND}" "${REPLACE}"
28+
PATCH_OUT "${PATCH_IN}")
29+
file (WRITE "${FILE}" "${PATCH_OUT}")
30+
endfunction()

CMake/Modules/SmartcarLib.cmake

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
include (Patcher)
2+
3+
# Custom GY50 impl
4+
SET(GY50 ${CMAKE_SOURCE_DIR}/thirdparty/smartcar_shield/src/sensors/heading/gyroscope/GY50.cpp)
5+
hard_patch_regexp(${GY50} "void GY50::update\(\).*currentTime;\n}" "void GY50::update() { mAngularDisplacement = getAngularVelocity(); }")
6+
hard_patch_regexp(${GY50} "int GY50::getHeading\(\).*normalizedReading;\n}" "int GY50::getHeading() { return mAngularDisplacement; }")
7+
hard_patch_regexp(${GY50} "int GY50::getOffset.*measurements\n};" "int GY50::getOffset(int measurements) { return 0; }")

CMakeLists.txt

+16-3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ add_custom_target (TestTag)
5454
include (CTest)
5555
include (Catch)
5656
include (SetupUrho3D)
57+
include (SmartcarLib)
5758
include (StdPolyfills)
5859
include (BoostDLL)
5960

@@ -89,11 +90,11 @@ target_link_libraries (smartcar_emul_deps INTERFACE
8990
stdpolyfills::stdpolyfills
9091
TryCompile
9192
ConfigLoader
92-
)
93+
RegMoniker)
9394

9495
add_executable (smartcar_emul src/main.cxx)
9596
target_include_directories (smartcar_emul PRIVATE include thirdparty/inih)
96-
target_link_libraries (smartcar_emul PRIVATE smartcar_emul_deps)
97+
target_link_libraries (smartcar_emul PRIVATE smartcar_emul_deps Urho3D-rapidjson)
9798
target_compile_options (smartcar_emul PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/permissive->)
9899
add_dependencies (smartcar_emul ArduinoRuntime)
99100

@@ -110,7 +111,19 @@ target_sources (smartcar_emul PRIVATE
110111
include/components/EmulGlue.hxx
111112
include/gui/TorchEvents.hxx
112113
include/components/SimpleVehicle.hxx
113-
src/components/SimpleVehicle.cxx)
114+
src/components/SimpleVehicle.cxx
115+
src/components/Servo.cxx
116+
include/components/Servo.hxx
117+
src/components/WheelServo.cxx
118+
include/components/WheelServo.hxx
119+
src/components/PerfectGyroscopeI2CSensor.cxx
120+
include/components/PerfectGyroscopeI2CSensor.hxx
121+
src/components/LaserCaster.cxx
122+
include/components/LaserCaster.hxx
123+
src/components/PerfectDistanceI2CSensor.cxx
124+
include/components/PerfectDistanceI2CSensor.hxx
125+
src/components/PerfectDistanceAnalogSensor.cxx
126+
include/components/PerfectDistanceAnalogSensor.hxx)
114127

115128
file (COPY ${CMAKE_SOURCE_DIR}/share DESTINATION ${CMAKE_BINARY_DIR})
116129

include/BoardData.hxx

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ struct SpiBus {
7676
struct BoardData {
7777
std::vector<std::atomic_bool> digital_pin_values;
7878
std::vector<std::atomic_uint16_t> analog_pin_values;
79-
std::vector<std::atomic_uint8_t> servo_value;
79+
std::vector<std::atomic_uint8_t> pwm_values;
8080
std::vector<std::atomic_uint8_t> pin_frequency;
8181
std::vector<UartBus> uart_buses;
8282
std::vector<I2cBus> i2c_buses;

include/ardpolyfills/Wire.h

-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ class SMCE__DLL_RT_API TwoWire : public Stream {
3030
void begin(int sda, int scl, std::uint8_t with_address);
3131
std::size_t requestFrom(std::uint8_t slave_address, std::size_t quantity, bool stop = true);
3232
std::uint8_t requestFrom(std::uint8_t slave_address, std::uint8_t quantity, std::uint8_t = 1);
33-
std::uint8_t requestFrom(int slave_address, int quantity, int stop = 1);
3433
void beginTransmission(std::uint8_t slave_address);
3534
inline void beginTransmission(int slave_address) { beginTransmission(static_cast<std::uint8_t>(slave_address)); }
3635
std::uint8_t endTransmission(std::uint8_t = 0);

include/components/LaserCaster.hxx

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* LaserCaster.hxx
3+
* Copyright 2020 ItJustWorksTM
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#ifndef SMARTCAR_EMUL_LASERCASTER_HXX
19+
#define SMARTCAR_EMUL_LASERCASTER_HXX
20+
21+
#include <cstdint>
22+
#include <Urho3D/Scene/LogicComponent.h>
23+
24+
class LaserCaster : public Urho3D::LogicComponent {
25+
URHO3D_OBJECT(LaserCaster, Urho3D::LogicComponent);
26+
Urho3D::Node* node;
27+
28+
public:
29+
explicit LaserCaster(Urho3D::Node* node);
30+
[[nodiscard]] std::uint32_t measure(float max_dist = 1000) const noexcept;
31+
};
32+
33+
#endif // SMARTCAR_EMUL_LASERCASTER_HXX

include/components/MovableCamera.hxx

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <Urho3D/Core/Context.h>
2424
#include <Urho3D/Graphics/Camera.h>
2525
#include <Urho3D/Graphics/Viewport.h>
26+
#include <Urho3D/Input/Input.h>
2627
#include <Urho3D/Scene/Component.h>
2728
#include <Urho3D/Scene/Scene.h>
2829

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* PerfectDistanceAnalogSensor.hxx
3+
* Copyright 2020 ItJustWorksTM
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#ifndef SMARTCAR_EMUL_PERFECTDISTANCEANALOGSENSOR_HXX
19+
#define SMARTCAR_EMUL_PERFECTDISTANCEANALOGSENSOR_HXX
20+
21+
#include <atomic>
22+
#include <rapidjson/document.h>
23+
#include "BoardData.hxx"
24+
#include "LaserCaster.hxx"
25+
26+
class PerfectDistanceAnalogSensor : public LaserCaster {
27+
std::atomic_uint16_t* m_pin_ptr;
28+
std::uint8_t m_type;
29+
30+
public:
31+
PerfectDistanceAnalogSensor(BoardData& bd, Urho3D::Node* node, const rapidjson::Value& conf);
32+
void Update(float timeStep) override;
33+
};
34+
35+
#endif // SMARTCAR_EMUL_PERFECTDISTANCEANALOGSENSOR_HXX
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* PerfectDistanceI2CSensor.hxx
3+
* Copyright 2020 ItJustWorksTM
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#ifndef SMARTCAR_EMUL_PERFECTDISTANCEI2CSENSOR_HXX
19+
#define SMARTCAR_EMUL_PERFECTDISTANCEI2CSENSOR_HXX
20+
21+
#include <cstdint>
22+
#include <rapidjson/include/rapidjson/document.h>
23+
#include "BoardData.hxx"
24+
#include "DeviceMap.hxx"
25+
#include "LaserCaster.hxx"
26+
27+
class PerfectDistanceI2CSensor : public LaserCaster {
28+
URHO3D_OBJECT(PerfectDistanceI2CSensor, LaserCaster);
29+
30+
std::function<void()> ticker;
31+
std::uint8_t bus_id{};
32+
I2cBus* bus;
33+
34+
enum ReadRegs { INTERRUPT_RESULT = 0x13, MEASUREMENT_RESULT = 0x14, SYSRANGE_START = 0x00 };
35+
36+
enum WriteRegs { SPAD_INFO = 0x83, DEVICE_ID = 0xC0, CHANGE_ADDRESS = 0x8A };
37+
38+
using RDev = regmon::Device<PerfectDistanceI2CSensor>;
39+
const RDev::DeviceMap vlx = RDev::make_device(
40+
RDev::DefaultsTo<DEVICE_ID>{0xEE}, RDev::DefaultsTo<SPAD_INFO>{0x01}, RDev::DefaultsTo<INTERRUPT_RESULT>{0x07},
41+
RDev::InvokesFunction<SYSRANGE_START>{+[](PerfectDistanceI2CSensor&, RDev::DeviceStorage&, gsl::span<const std::byte>) {}},
42+
RDev::InvokesFunction<CHANGE_ADDRESS>{+[](PerfectDistanceI2CSensor& drv, RDev::DeviceStorage& store, gsl::span<const std::byte> incoming) {
43+
auto ex = drv.bus->slaves.extract(store.address);
44+
store.data[CHANGE_ADDRESS] = store.address = ex.key() = static_cast<uint8_t>(incoming.front());
45+
drv.bus->slaves.insert(std::move(ex));
46+
}});
47+
RDev::DeviceStorage store{};
48+
49+
public:
50+
PerfectDistanceI2CSensor(BoardData& bd, Urho3D::Node* node, const rapidjson::Value& pin);
51+
52+
void Update(float timeStep) override;
53+
};
54+
55+
#endif // SMARTCAR_EMUL_PERFECTDISTANCEI2CSENSOR_HXX
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* PerfectGyroscopeI2CSensor.hxx
3+
* Copyright 2020 ItJustWorksTM
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#ifndef SMARTCAR_EMUL_PERFECTGYROSCOPEI2CSENSOR_HXX
19+
#define SMARTCAR_EMUL_PERFECTGYROSCOPEI2CSENSOR_HXX
20+
21+
#include <array>
22+
#include <bit>
23+
#include <rapidjson/include/rapidjson/document.h>
24+
#include <Urho3D/Scene/LogicComponent.h>
25+
#include <Urho3D/Core/Context.h>
26+
#include "BoardData.hxx"
27+
#include "DeviceMap.hxx"
28+
29+
30+
class PerfectGyroscopeI2CSensor : public Urho3D::LogicComponent {
31+
URHO3D_OBJECT(PerfectGyroscopeI2CSensor, Urho3D::LogicComponent);
32+
33+
std::function<void()> ticker;
34+
35+
enum Registers {
36+
WHO_AM_I = 0xF0,
37+
CTRL_REG1 [[maybe_unused]] = 0x20,
38+
CTRL_REG2 [[maybe_unused]] = 0x21,
39+
CTRL_REG3 [[maybe_unused]] = 0x22,
40+
CTRL_REG4 [[maybe_unused]] = 0x23,
41+
CTRL_REG5 [[maybe_unused]] = 0x24,
42+
REFERENCE [[maybe_unused]] = 0x25,
43+
OUT_TEMP = 0x26,
44+
STATUS_REG [[maybe_unused]] = 0x27,
45+
OUT_X_L = 0x28,
46+
OUT_X_H = 0x29,
47+
OUT_Y_L = 0x2A,
48+
OUT_Y_H = 0x2B,
49+
OUT_Z_L = 0x2C,
50+
OUT_Z_H = 0x2D,
51+
};
52+
53+
enum class PowerMode {
54+
powered_down,
55+
sleeping,
56+
normal,
57+
};
58+
enum class DataRate {
59+
hz100 [[maybe_unused]],
60+
hz200 [[maybe_unused]],
61+
hz400 [[maybe_unused]],
62+
hz800 [[maybe_unused]],
63+
};
64+
enum class FullScale {
65+
dps250,
66+
dps500,
67+
dps2000,
68+
};
69+
enum Enabled {
70+
x = 1,
71+
y = 2,
72+
z = 4,
73+
};
74+
75+
// Full scale to sensitivity
76+
constexpr static std::array fs2sens{0.00875f, 0.0175f, 0.07f};
77+
78+
using RDev = regmon::Device<PerfectGyroscopeI2CSensor>;
79+
const RDev::DeviceMap gy = RDev::make_device(
80+
RDev::DefaultsTo<WHO_AM_I>{0b11010011},
81+
RDev::DefaultsTo<OUT_TEMP>{20} // °C
82+
);
83+
84+
RDev::DeviceStorage store{};
85+
I2cBus* bus;
86+
87+
[[maybe_unused]] [[nodiscard]] bool is_powered_up() const noexcept;
88+
[[nodiscard]] PowerMode get_power_mode() const noexcept;
89+
[[maybe_unused]] [[nodiscard]] DataRate get_data_rate() const noexcept;
90+
[[nodiscard]] FullScale get_full_scale() const noexcept;
91+
[[nodiscard]] std::endian get_data_endianness() const noexcept;
92+
public:
93+
PerfectGyroscopeI2CSensor(BoardData& bd, Urho3D::Node* node, const rapidjson::Value& pin);
94+
void UpdatePy(Urho3D::StringHash, Urho3D::VariantMap& event_data);
95+
96+
};
97+
98+
#endif // SMARTCAR_EMUL_PERFECTGYROSCOPEI2CSENSOR_HXX

include/components/Registry.hxx

+20-1
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,28 @@
2323
#include <utility>
2424
#include <Urho3D/Scene/LogicComponent.h>
2525
#include <Urho3D/Scene/Node.h>
26+
#include <gsl/gsl>
27+
#include <nameof.hpp>
2628
#include <rapidjson/document.h>
29+
#include "components/PerfectDistanceAnalogSensor.hxx"
30+
#include "components/PerfectDistanceI2CSensor.hxx"
31+
#include "components/PerfectGyroscopeI2CSensor.hxx"
32+
#include "components/WheelServo.hxx"
2733
#include "BoardData.hxx"
34+
#include "utility.hxx"
2835

29-
constexpr std::array<std::pair<std::string_view, Urho3D::LogicComponent*(*)(BoardData&, Urho3D::Node*, const rapidjson::Value&)>, 0> attachments_registry{};
36+
using namespace std::literals;
37+
38+
template <class T> constexpr auto attachment_entry() {
39+
return std::pair{nameof::nameof_type<T>(),
40+
+[](BoardData& bd, Urho3D::Node* node, const rapidjson::Value& conf) -> gsl::owner<Urho3D::LogicComponent*> {
41+
return new T{bd, node, conf};
42+
}};
43+
}
44+
45+
template <class... Attachments> constexpr auto compile_registry() { return make_array(attachment_entry<Attachments>()...); }
46+
47+
constexpr std::array attachments_registry =
48+
compile_registry<ServoMotor, SteeringServo, ServoMotor, PerfectDistanceI2CSensor, PerfectGyroscopeI2CSensor, PerfectDistanceAnalogSensor>();
3049

3150
#endif // SMARTCAR_EMUL_REGISTRY_HXX

include/components/Servo.hxx

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Servo.hxx
3+
* Copyright 2020 ItJustWorksTM
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#ifndef SMARTCAR_EMUL_SERVO_HXX
19+
#define SMARTCAR_EMUL_SERVO_HXX
20+
21+
#include <optional>
22+
#include <BoardData.hxx>
23+
#include <Urho3D/Scene/LogicComponent.h>
24+
#include <Urho3D/Scene/Node.h>
25+
#include <rapidjson/include/rapidjson/document.h>
26+
#include "utility.hxx"
27+
28+
class Servo : public Urho3D::LogicComponent {
29+
URHO3D_OBJECT(Servo, Urho3D::LogicComponent);
30+
31+
struct Bounds {
32+
// Degrees
33+
float angle_min;
34+
float angle_max;
35+
};
36+
37+
std::atomic_uint8_t* pwm_pin;
38+
Urho3D::Node* node;
39+
40+
std::optional<Bounds> movement_mode{};
41+
42+
public:
43+
explicit Servo(BoardData& bd, Urho3D::Node* node, const rapidjson::Value& pin);
44+
virtual void Update(float timeStep) override;
45+
};
46+
47+
#endif // SMARTCAR_EMUL_SERVO_HXX

0 commit comments

Comments
 (0)