Skip to content

Commit

Permalink
Feat: Add PyCramKnowRobPrinter for Planning
Browse files Browse the repository at this point in the history
  • Loading branch information
McModknower committed Jun 14, 2024
1 parent 601242a commit 1268aad
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 6 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ dependencies {
testAnnotationProcessor "org.projectlombok:lombok:${versions.lombok}"

testImplementation "org.junit.jupiter:junit-jupiter-api:${versions.junit}"
testImplementation "org.junit.jupiter:junit-jupiter-params:${versions.junit}"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${versions.junit}"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@
import com.malte3d.suturo.knowledge.owl2anything.converter.OwlConverter;
import com.malte3d.suturo.knowledge.owl2anything.converter.OwlRecord;
import com.malte3d.suturo.knowledge.owl2anything.input.StarterArgs;
import com.malte3d.suturo.knowledge.owl2anything.output.CramKnowRobPrinter;
import com.malte3d.suturo.knowledge.owl2anything.output.CramRoboKudoPrinter;
import com.malte3d.suturo.knowledge.owl2anything.output.Id2NameJsonPrinter;
import com.malte3d.suturo.knowledge.owl2anything.output.SuturoObjectsCsvPrinter;
import com.malte3d.suturo.knowledge.owl2anything.output.SuturoObjectsDefaultSizeCsvPrinter;
import com.malte3d.suturo.knowledge.owl2anything.output.YoloObjNamesPrinter;
import com.malte3d.suturo.knowledge.owl2anything.output.*;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

Expand Down Expand Up @@ -49,5 +44,6 @@ public static void main(String[] args) {
YoloObjNamesPrinter.print(owlRecords, new File(outputDir, "obj.names"));
CramRoboKudoPrinter.print(owlRecords, new File(outputDir, "cram_robokudo.txt"));
CramKnowRobPrinter.print(owlRecords, new File(outputDir, "cram_knowrob.txt"));
PyCramKnowRobPrinter.print(owlRecords, new File(outputDir, "pycram_knowrob.py"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import com.malte3d.suturo.knowledge.owl2anything.converter.OwlRecord;
import lombok.experimental.UtilityClass;

import java.util.Locale;
import java.util.regex.Pattern;

/**
* Converts an {@link OwlRecord} to the formats needed for the different interfaces
*/
Expand All @@ -25,6 +28,31 @@ public static String toCramFormat(OwlRecord owlRecord) {
return owlRecord.getIriName().toLowerCase();
}

private static final Pattern CAPITAL_LETTER = Pattern.compile("([A-Z])");
private static final Pattern CAPITAL_LETTER_GROUP = Pattern.compile("([A-Z])_([A-Z])");

/**
* @param owlRecord the record to convert
* @return the record in the format needed for the PyCRAM variable names
*/
public static String toPycramFormat(OwlRecord owlRecord) {
String name = owlRecord.getIriName();
// First convert "CerealBox" and "ToyotaHSR" to "_Cereal_Box" and "_Toyota_H_S_R"
// aka prefix all capital letters with an _
name = CAPITAL_LETTER.matcher(name).replaceAll("_$1");
// Then convert "_Cereal_Box" and "_Toyota_H_S_R" to "_Cereal_Box" and "_Toyota_HS_R"
// aka remove underscores between capital letters
name = CAPITAL_LETTER_GROUP.matcher(name).replaceAll("$1$2");
// Then convert "_Cereal_Box" and "_Toyota_HS_R" to "_Cereal_Box" and "_Toyota_HSR"
// aka remove the underscores not removed in the step before,
// since the left capital letter was already part of a replacement in that step
name = CAPITAL_LETTER_GROUP.matcher(name).replaceAll("$1$2");
// Lastly convert "_Cereal_Box" and "_Toyota_HSR" to "cereal_box" and "toyota_hsr"
// aka remove the underscore at the beginning (since all names start with a capital letter)
// and convert it to lower case
return name.substring(1).toLowerCase();
}

/**
* @param owlRecord the record to convert
* @return the record in the format needed for the CRAM - RoboKudo interface in Perception
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.malte3d.suturo.knowledge.owl2anything.output;

import com.malte3d.suturo.knowledge.owl2anything.converter.OwlRecord;
import lombok.NonNull;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;

/**
* Utility class to create a .py file for the PyCRAM - KnowRob interface
*/
@Slf4j
@UtilityClass
public class PyCramKnowRobPrinter {

private static final Pattern SINGLE_QUOTE = Pattern.compile("'");

public static void print(@NonNull List<OwlRecord> classes, @NonNull File outputFile) {

List<OwlRecord> output = PerceptionClassesFilter.filter(classes);

try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(outputFile), StandardCharsets.UTF_8)) {

writer.append(generateCramObjectListString(output));

log.info("Successfully created {}", outputFile.getName());

} catch (IOException e) {
log.error("Error while writing the Cram Object Names file", e);
}
}

public static String generateCramObjectListString(@NonNull List<OwlRecord> classes) {


List<OwlRecord> perceptionClasses = classes.stream()
.filter(csvRecord -> csvRecord.getPerceptionId() != null)
.sorted(Comparator.comparing(OwlRecord::getPerceptionId))
.toList();

StringBuilder sb = new StringBuilder();

for (OwlRecord owlRecord : perceptionClasses) {

sb.append(OwlRecordConverter.toPycramFormat(owlRecord))
.append(" = '").append(OwlRecordConverter.toKnowRobFormat(owlRecord)).append("'").append("\n");
}

return sb.toString();
}

private static String escapeSingleQuotes(String literal) {
return SINGLE_QUOTE.matcher(literal).replaceAll("\\\\'");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.malte3d.suturo.knowledge.owl2anything.output;

import com.malte3d.suturo.knowledge.owl2anything.converter.OwlRecord;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

import static org.junit.jupiter.api.Assertions.*;

class OwlRecordConverterTest {

@ParameterizedTest
@CsvSource({
"CerealBox, cereal_box",
"ToyotaHSR, toyota_hsr",
"JellOChocolatePuddingBox, jell_ochocolate_pudding_box",
"Drawer, drawer"
})
void toPycramFormat(String iriName, String pycramName) {
OwlRecord record = OwlRecord.builder()
// The actual test data
.iriName(iriName)
// and the other values with empty strings since lombok does not allow them to be null
.iriNamespace("")
.iriNamespaceShort("")
.naturalName("")
.description("")
.build();
assertEquals(pycramName, OwlRecordConverter.toPycramFormat(record));
}
}

0 comments on commit 1268aad

Please sign in to comment.