Apollo 11.0
自动驾驶开放平台
camera_component.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18#ifdef __aarch64__
19#include <cuda_runtime.h>
20#endif
21
22namespace apollo {
23namespace drivers {
24namespace camera {
25
33
35 // hook: Apollo License Verification: v_apollo_park
36 camera_config_ = std::make_shared<Config>();
38 return false;
39 }
40 AINFO << "UsbCam config: " << camera_config_->DebugString();
41
42 camera_device_.reset(new UsbCam());
43 camera_device_->init(camera_config_);
44 raw_image_.reset(new CameraImage);
45 raw_image_for_compress_.reset(new CameraImage);
46
47 raw_image_->width = camera_config_->width();
48 raw_image_->height = camera_config_->height();
49 raw_image_->bytes_per_pixel = camera_config_->bytes_per_pixel();
50
51 raw_image_for_compress_->width = camera_config_->width();
52 raw_image_for_compress_->height = camera_config_->height();
53 raw_image_for_compress_->bytes_per_pixel = camera_config_->bytes_per_pixel();
54
55 if (camera_config_->pixel_format() == "yuyv" || camera_config_->pixel_format() == "uyvy"
56 || camera_config_->pixel_format() == "yuvmono10") {
57 raw_image_for_compress_->image_size = raw_image_for_compress_->width * raw_image_for_compress_->height * 2;
58 } else if (camera_config_->pixel_format() == "mjpeg") {
59 AINFO << "Disable sensor raw camera output with format mjpeg";
60 raw_image_for_compress_->image_size = 0;
61 } else if (camera_config_->pixel_format() == "rgb24") {
62 raw_image_for_compress_->image_size = raw_image_for_compress_->width * raw_image_for_compress_->height * 3;
63 } else {
64 AERROR << "Wrong pixel fromat:" << camera_config_->pixel_format()
65 << ",must be yuyv | uyvy | mjpeg | yuvmono10 | rgb24";
66 return false;
67 }
68
69 if (raw_image_for_compress_->image_size == 0) {
70 raw_image_for_compress_->image = nullptr;
71 } else {
72 raw_image_for_compress_->image
73 = reinterpret_cast<char*>(calloc(raw_image_for_compress_->image_size, sizeof(char)));
74 }
75
76 device_wait_ = camera_config_->device_wait_ms();
77 spin_rate_ = static_cast<uint32_t>((1.0 / camera_config_->spin_rate()) * 1e6);
78
79 if (camera_config_->output_type() == YUYV) {
80 raw_image_->image_size = raw_image_->width * raw_image_->height * 2;
81 } else if (camera_config_->output_type() == RGB) {
82 raw_image_->image_size = raw_image_->width * raw_image_->height * 3;
83 }
84 if (raw_image_->image_size > MAX_IMAGE_SIZE) {
85 AERROR << "image size is too big ,must less than " << MAX_IMAGE_SIZE << " bytes.";
86 return false;
87 }
88 raw_image_->is_new = 0;
89 // free memory in this struct desturctor
90#ifndef __aarch64__
91 raw_image_->image = reinterpret_cast<char*>(calloc(raw_image_->image_size, sizeof(char)));
92 if (raw_image_->image == nullptr) {
93 AERROR << "system calloc memory error, size:" << raw_image_->image_size;
94 return false;
95 }
96#else
97 if (camera_config_->arm_gpu_acceleration()) {
98 if (cudaMallocHost(&raw_image_->image, raw_image_->image_size * sizeof(char), cudaHostAllocMapped)
99 != cudaSuccess) {
100 AERROR << "cuda malloc memory error, size:" << raw_image_->image_size;
101 return false;
102 }
103 } else {
104 raw_image_->image = reinterpret_cast<char*>(calloc(raw_image_->image_size, sizeof(char)));
105 if (raw_image_->image == nullptr) {
106 AERROR << "system calloc memory error, size:" << raw_image_->image_size;
107 return false;
108 }
109 }
110#endif
111
112 writer_ = node_->CreateWriter<Image>(camera_config_->channel_name());
113 raw_writer_ = node_->CreateWriter<Image>(camera_config_->raw_channel_name());
114
115 async_result_ = cyber::Async(&CameraComponent::run, this);
116 return true;
117}
118
119void CameraComponent::run() {
120 running_.exchange(true);
121 while (!cyber::IsShutdown()) {
122 if (!camera_device_->wait_for_device()) {
123 // sleep for next check
124 cyber::SleepFor(std::chrono::milliseconds(device_wait_));
125 continue;
126 }
127
128 auto s = camera_device_->poll(raw_image_, raw_image_for_compress_);
131 continue;
132 } else {
133 AERROR << "camera device poll failed";
134 continue;
135 }
136 }
137
138 cyber::Time image_time(raw_image_->tv_sec, 1000 * raw_image_->tv_usec);
139 if (index_ >= buffer_size_) {
140 index_ = 0;
141 }
142 auto pb_image = writer_->AcquireMessage();
143 pb_image->mutable_header()->set_frame_id(camera_config_->frame_id());
144 pb_image->set_width(raw_image_->width);
145 pb_image->set_height(raw_image_->height);
146 pb_image->mutable_data()->reserve(raw_image_->image_size);
147
148 if cyber_likely(camera_config_->output_type() == YUYV) {
149 pb_image->set_encoding("yuyv");
150 pb_image->set_step(2 * raw_image_->width);
151 } else if (camera_config_->output_type() == RGB) {
152 pb_image->set_encoding("rgb8");
153 pb_image->set_step(3 * raw_image_->width);
154 }
155 auto header_time = cyber::Time::Now().ToSecond();
156 auto measurement_time = image_time.ToSecond();
157 if (measurement_time > header_time) {
158 // measurement_time should never greater than header_time
159 // invalid v4l2 buffer time, use header_time instead
160 measurement_time = header_time;
161 }
162 pb_image->mutable_header()->set_timestamp_sec(header_time);
163 pb_image->set_measurement_time(measurement_time);
164 pb_image->set_data(raw_image_->image, raw_image_->image_size);
165 writer_->Write(pb_image);
166
167 auto raw_image_for_compress = raw_writer_->AcquireMessage();
168 raw_image_for_compress->mutable_header()->set_frame_id(camera_config_->frame_id());
169 raw_image_for_compress->set_width(raw_image_for_compress_->width);
170 raw_image_for_compress->set_height(raw_image_for_compress_->height);
171 raw_image_for_compress->mutable_data()->reserve(raw_image_for_compress_->image_size);
172 raw_image_for_compress->set_encoding(camera_config_->pixel_format());
173 raw_image_for_compress->mutable_header()->set_timestamp_sec(header_time);
174 raw_image_for_compress->set_measurement_time(measurement_time);
175 raw_image_for_compress->set_data(raw_image_for_compress_->image, raw_image_for_compress_->image_size);
176 raw_writer_->Write(raw_image_for_compress);
177
178#ifndef __aarch64__
179 // the frame rate become unstable if yielding cpu in aarch64
180 // thus only yielding cpu in x86_64
181 cyber::SleepFor(std::chrono::microseconds(spin_rate_));
182#endif
183 }
184}
185
187 if (running_.load()) {
188 running_.exchange(false);
189#ifndef __aarch64__
190 free(raw_image_->image);
191#else
192 cudaFreeHost(raw_image_->image);
193#endif
194 async_result_.wait();
195 }
196}
197
198} // namespace camera
199} // namespace drivers
200} // namespace apollo
std::shared_ptr< Node > node_
Reader subscribes a channel, it has two main functions:
Definition reader.h:69
static Time Now()
get the current time.
Definition time.cc:57
double ToSecond() const
convert time to second.
Definition time.cc:77
#define cyber_likely(x)
Definition macros.h:27
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
Definition file.cc:132
bool IsShutdown()
Definition state.h:46
class register implement
Definition arena_queue.h:37